import { createRequire } from "node:module";
import * as path$4 from "node:path";
import path, { dirname, join } from "node:path";
import * as fs$6 from "node:fs";
import fs, { appendFile, appendFileSync, copyFileSync, createReadStream, existsSync, mkdirSync, promises, readFileSync, readdirSync, renameSync, stat, statSync, unlinkSync, watch, watchFile, writeFileSync } from "node:fs";
import os, { tmpdir } from "node:os";
import fs$1, { existsSync as existsSync$1 } from "fs";
import { inspect, isDeepStrictEqual } from "node:util";
import fsPromise, { access, copyFile, mkdir, readFile, stat as stat$1, unlink, writeFile } from "node:fs/promises";
import path$1 from "path";
import { networkInterfaces } from "os";
import { deflateSync, gunzipSync, gzipSync, inflateSync, unzipSync } from "node:zlib";
import * as fileType from "file-type";
import { fileTypeFromBuffer } from "file-type";
import crypto$1, { createCipheriv, createDecipheriv, createECDH, createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
import { fileURLToPath, pathToFileURL } from "node:url";
import { decode, encode, getDuration, getWavFileInfo, isSilk, isWav } from "silk-wasm";
import { WebSocket as WebSocket$1, WebSocketServer } from "ws";
import http, { STATUS_CODES, createServer, request } from "node:http";
import { Http2ServerRequest, constants } from "node:http2";
import { Readable } from "node:stream";
import fsPromise$1, { stat as stat$2, unlink as unlink$1 } from "fs/promises";
import { constants as constants$1 } from "node:buffer";
import https from "node:https";
import net, { Socket } from "node:net";
import { versions } from "node:process";
import { lookup } from "node:dns/promises";
import { EventEmitter } from "node:events";
import { execSync } from "node:child_process";
//#region \0rolldown/runtime.js
var __create$1 = Object.create;
var __defProp$8 = Object.defineProperty;
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
var __getOwnPropNames$2 = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esmMin = (fn, res, err) => () => {
	if (err) throw err[0];
	try {
		return fn && (res = fn(fn = 0)), res;
	} catch (e) {
		throw err = [e], e;
	}
};
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __exportAll = (all, no_symbols) => {
	let target = {};
	for (var name in all) __defProp$8(target, name, {
		get: all[name],
		enumerable: true
	});
	if (!no_symbols) __defProp$8(target, Symbol.toStringTag, { value: "Module" });
	return target;
};
var __copyProps = (to, from, except, desc) => {
	if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames$2(from), i = 0, n = keys.length, key; i < n; i++) {
		key = keys[i];
		if (!__hasOwnProp.call(to, key) && key !== except) __defProp$8(to, key, {
			get: ((k) => from[k]).bind(null, key),
			enumerable: !(desc = __getOwnPropDesc$1(from, key)) || desc.enumerable
		});
	}
	return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create$1(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp$8(target, "default", {
	value: mod,
	enumerable: true
}) : target, mod));
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp$8({}, "__esModule", { value: true }), mod);
var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
//#endregion
//#region node_modules/cosmokit/lib/index.mjs
function noop() {}
function isNullable(value) {
	return value === null || value === void 0;
}
function isNonNullable(value) {
	return !isNullable(value);
}
function isPlainObject$1(data) {
	return data && typeof data === "object" && !Array.isArray(data);
}
function filterKeys(object, filter) {
	return Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));
}
function mapValues(object, transform) {
	return Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));
}
function pick$1(source, keys, forced) {
	if (!keys) return { ...source };
	const result = {};
	for (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];
	return result;
}
function omit$1(source, keys) {
	if (!keys) return { ...source };
	const result = { ...source };
	for (const key of keys) Reflect.deleteProperty(result, key);
	return result;
}
function defineProperty(object, key, value) {
	return Object.defineProperty(object, key, {
		writable: true,
		value,
		enumerable: false
	});
}
function difference(array1, array2) {
	return array1.filter((item) => !array2.includes(item));
}
function deduplicate(array) {
	return [...new Set(array)];
}
function remove(list, item) {
	const index = list?.indexOf(item);
	if (index >= 0) {
		list.splice(index, 1);
		return true;
	} else return false;
}
function makeArray(source) {
	return Array.isArray(source) ? source : isNullable(source) ? [] : [source];
}
function is(type, value) {
	if (arguments.length === 1) return (value2) => is(type, value2);
	return type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;
}
function isArrayBufferLike(value) {
	return is("ArrayBuffer", value) || is("SharedArrayBuffer", value);
}
function isArrayBufferSource(value) {
	return isArrayBufferLike(value) || ArrayBuffer.isView(value);
}
var Binary;
((Binary2) => {
	Binary2.is = isArrayBufferLike;
	Binary2.isSource = isArrayBufferSource;
	function fromSource(source) {
		if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
		else return source;
	}
	Binary2.fromSource = fromSource;
	function toBase64(source) {
		source = fromSource(source);
		if (typeof Buffer !== "undefined") return Buffer.from(source).toString("base64");
		let binary = "";
		const bytes = new Uint8Array(source);
		for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
		return btoa(binary);
	}
	Binary2.toBase64 = toBase64;
	function fromBase64(source) {
		if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "base64"));
		return Uint8Array.from(atob(source), (c) => c.charCodeAt(0));
	}
	Binary2.fromBase64 = fromBase64;
	function toHex(source) {
		source = fromSource(source);
		if (typeof Buffer !== "undefined") return Buffer.from(source).toString("hex");
		return Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, "0")).join("");
	}
	Binary2.toHex = toHex;
	function fromHex(source) {
		if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "hex"));
		const hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);
		const buffer = [];
		for (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));
		return Uint8Array.from(buffer).buffer;
	}
	Binary2.fromHex = fromHex;
})(Binary || (Binary = {}));
Binary.fromBase64;
Binary.toBase64;
Binary.fromHex;
Binary.toHex;
function clone$1(source, refs = /* @__PURE__ */ new Map()) {
	if (!source || typeof source !== "object") return source;
	if (is("Date", source)) return new Date(source.valueOf());
	if (is("RegExp", source)) return new RegExp(source.source, source.flags);
	if (isArrayBufferLike(source)) return source.slice(0);
	if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
	const cached = refs.get(source);
	if (cached) return cached;
	if (Array.isArray(source)) {
		const result2 = [];
		refs.set(source, result2);
		source.forEach((value, index) => {
			result2[index] = Reflect.apply(clone$1, null, [value, refs]);
		});
		return result2;
	}
	const result = Object.create(Object.getPrototypeOf(source));
	refs.set(source, result);
	for (const key of Reflect.ownKeys(source)) {
		const descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };
		if ("value" in descriptor) descriptor.value = Reflect.apply(clone$1, null, [descriptor.value, refs]);
		Reflect.defineProperty(result, key, descriptor);
	}
	return result;
}
function deepEqual(a, b, strict) {
	if (a === b) return true;
	if (!strict && isNullable(a) && isNullable(b)) return true;
	if (typeof a !== typeof b) return false;
	if (typeof a !== "object") return false;
	if (!a || !b) return false;
	function check(test, then) {
		return test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;
	}
	return check(Array.isArray, (a2, b2) => a2.length === b2.length && a2.every((item, index) => deepEqual(item, b2[index]))) ?? check(is("Date"), (a2, b2) => a2.valueOf() === b2.valueOf()) ?? check(is("RegExp"), (a2, b2) => a2.source === b2.source && a2.flags === b2.flags) ?? check(isArrayBufferLike, (a2, b2) => {
		if (a2.byteLength !== b2.byteLength) return false;
		const viewA = new Uint8Array(a2);
		const viewB = new Uint8Array(b2);
		for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
		return true;
	}) ?? Object.keys({
		...a,
		...b
	}).every((key) => deepEqual(a[key], b[key], strict));
}
function camelCase(source) {
	return source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase());
}
function tokenize(source, delimiters, delimiter) {
	const output = [];
	let state = 0;
	for (let i = 0; i < source.length; i++) {
		const code = source.charCodeAt(i);
		if (code >= 65 && code <= 90) {
			if (state === 1) {
				const next = source.charCodeAt(i + 1);
				if (next >= 97 && next <= 122) output.push(delimiter);
				output.push(code + 32);
			} else {
				if (state !== 0) output.push(delimiter);
				output.push(code + 32);
			}
			state = 1;
		} else if (code >= 97 && code <= 122) {
			output.push(code);
			state = 2;
		} else if (delimiters.includes(code)) {
			if (state !== 0) output.push(delimiter);
			state = 0;
		} else output.push(code);
	}
	return String.fromCharCode(...output);
}
function paramCase(source) {
	return tokenize(source, [45, 95], 45);
}
var camelize = camelCase;
var hyphenate = paramCase;
var Time;
((Time2) => {
	Time2.millisecond = 1;
	Time2.second = 1e3;
	Time2.minute = Time2.second * 60;
	Time2.hour = Time2.minute * 60;
	Time2.day = Time2.hour * 24;
	Time2.week = Time2.day * 7;
	let timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
	function setTimezoneOffset(offset) {
		timezoneOffset = offset;
	}
	Time2.setTimezoneOffset = setTimezoneOffset;
	function getTimezoneOffset() {
		return timezoneOffset;
	}
	Time2.getTimezoneOffset = getTimezoneOffset;
	function getDateNumber(date = /* @__PURE__ */ new Date(), offset) {
		if (typeof date === "number") date = new Date(date);
		if (offset === void 0) offset = timezoneOffset;
		return Math.floor((date.valueOf() / Time2.minute - offset) / 1440);
	}
	Time2.getDateNumber = getDateNumber;
	function fromDateNumber(value, offset) {
		const date = new Date(value * Time2.day);
		if (offset === void 0) offset = timezoneOffset;
		return new Date(+date + offset * Time2.minute);
	}
	Time2.fromDateNumber = fromDateNumber;
	const numeric = /\d+(?:\.\d+)?/.source;
	const timeRegExp = new RegExp(`^${[
		"w(?:eek(?:s)?)?",
		"d(?:ay(?:s)?)?",
		"h(?:our(?:s)?)?",
		"m(?:in(?:ute)?(?:s)?)?",
		"s(?:ec(?:ond)?(?:s)?)?"
	].map((unit) => `(${numeric}${unit})?`).join("")}$`);
	function parseTime(source) {
		const capture = timeRegExp.exec(source);
		if (!capture) return 0;
		return (parseFloat(capture[1]) * Time2.week || 0) + (parseFloat(capture[2]) * Time2.day || 0) + (parseFloat(capture[3]) * Time2.hour || 0) + (parseFloat(capture[4]) * Time2.minute || 0) + (parseFloat(capture[5]) * Time2.second || 0);
	}
	Time2.parseTime = parseTime;
	function parseDate(date) {
		const parsed = parseTime(date);
		if (parsed) date = Date.now() + parsed;
		else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;
		else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;
		return date ? new Date(date) : /* @__PURE__ */ new Date();
	}
	Time2.parseDate = parseDate;
	function format(ms) {
		const abs = Math.abs(ms);
		if (abs >= Time2.day - Time2.hour / 2) return Math.round(ms / Time2.day) + "d";
		else if (abs >= Time2.hour - Time2.minute / 2) return Math.round(ms / Time2.hour) + "h";
		else if (abs >= Time2.minute - Time2.second / 2) return Math.round(ms / Time2.minute) + "m";
		else if (abs >= Time2.second) return Math.round(ms / Time2.second) + "s";
		return ms + "ms";
	}
	Time2.format = format;
	function toDigits(source, length = 2) {
		return source.toString().padStart(length, "0");
	}
	Time2.toDigits = toDigits;
	function template(template2, time = /* @__PURE__ */ new Date()) {
		return template2.replace("yyyy", time.getFullYear().toString()).replace("yy", time.getFullYear().toString().slice(2)).replace("MM", toDigits(time.getMonth() + 1)).replace("dd", toDigits(time.getDate())).replace("hh", toDigits(time.getHours())).replace("mm", toDigits(time.getMinutes())).replace("ss", toDigits(time.getSeconds())).replace("SSS", toDigits(time.getMilliseconds(), 3));
	}
	Time2.template = template;
})(Time || (Time = {}));
//#endregion
//#region node_modules/cordis/lib/index.js
var __defProp$7 = Object.defineProperty;
var __name$7 = (target, value) => __defProp$7(target, "name", {
	value,
	configurable: true
});
var DisposableList = class {
	static {
		__name$7(this, "DisposableList");
	}
	sn = 0;
	map = /* @__PURE__ */ new Map();
	weak = /* @__PURE__ */ new WeakMap();
	get length() {
		return this.map.size;
	}
	push(value) {
		const sn = ++this.sn;
		this.map.set(sn, value);
		this.weak.set(value, sn);
		return () => this.map.delete(sn);
	}
	delete(value) {
		const sn = this.weak.get(value);
		if (!sn) return false;
		return this.map.delete(sn);
	}
	clear() {
		const values = [...this.map.values()];
		this.map.clear();
		return values.reverse();
	}
	[Symbol.iterator]() {
		return this.map.values();
	}
	[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
		return [...this];
	}
};
var symbols = {
	shadow: /* @__PURE__ */ Symbol.for("cordis.shadow"),
	receiver: /* @__PURE__ */ Symbol.for("cordis.receiver"),
	original: /* @__PURE__ */ Symbol.for("cordis.original"),
	metadata: /* @__PURE__ */ Symbol.for("cordis.metadata"),
	initHooks: /* @__PURE__ */ Symbol.for("cordis.initHooks"),
	checkProto: /* @__PURE__ */ Symbol.for("cordis.checkProto"),
	effect: /* @__PURE__ */ Symbol.for("cordis.effect"),
	filter: /* @__PURE__ */ Symbol.for("cordis.filter"),
	isolate: /* @__PURE__ */ Symbol.for("cordis.isolate"),
	intercept: /* @__PURE__ */ Symbol.for("cordis.intercept"),
	init: /* @__PURE__ */ Symbol.for("cordis.init"),
	check: /* @__PURE__ */ Symbol.for("cordis.check"),
	config: /* @__PURE__ */ Symbol.for("cordis.config"),
	invoke: /* @__PURE__ */ Symbol.for("cordis.invoke"),
	extend: /* @__PURE__ */ Symbol.for("cordis.extend"),
	tracker: /* @__PURE__ */ Symbol.for("cordis.tracker"),
	resolveConfig: /* @__PURE__ */ Symbol.for("cordis.resolveConfig")
};
var GeneratorFunction = function* () {}.constructor;
var AsyncGeneratorFunction = async function* () {}.constructor;
function isConstructor(func) {
	if (!func.prototype) return false;
	if (func instanceof GeneratorFunction) return false;
	if (AsyncGeneratorFunction !== Function && func instanceof AsyncGeneratorFunction) return false;
	return true;
}
__name$7(isConstructor, "isConstructor");
function joinPrototype(proto1, proto2) {
	if (proto1 === Object.prototype) return proto2;
	const result = Object.create(joinPrototype(Object.getPrototypeOf(proto1), proto2));
	for (const key of Reflect.ownKeys(proto1)) Object.defineProperty(result, key, Object.getOwnPropertyDescriptor(proto1, key));
	return result;
}
__name$7(joinPrototype, "joinPrototype");
function isObject$2(value) {
	return value && (typeof value === "object" || typeof value === "function");
}
__name$7(isObject$2, "isObject");
function getPropertyDescriptor(target, prop) {
	let proto = target;
	while (proto) {
		const desc = Reflect.getOwnPropertyDescriptor(proto, prop);
		if (desc) return desc;
		proto = Object.getPrototypeOf(proto);
	}
}
__name$7(getPropertyDescriptor, "getPropertyDescriptor");
function getTraceable(ctx, value) {
	if (!isObject$2(value)) return value;
	if (Object.hasOwn(value, symbols.shadow)) return Object.getPrototypeOf(value);
	const tracker = value[symbols.tracker];
	if (!tracker) return value;
	return createTraceable(ctx, value, tracker);
}
__name$7(getTraceable, "getTraceable");
function withProps(target, props) {
	if (!props) return target;
	return new Proxy(target, {
		get: /* @__PURE__ */ __name$7((target2, prop, receiver) => {
			if (prop in props && prop !== "constructor") return Reflect.get(props, prop, receiver);
			return Reflect.get(target2, prop, receiver);
		}, "get"),
		set: /* @__PURE__ */ __name$7((target2, prop, value, receiver) => {
			if (prop in props && prop !== "constructor") return Reflect.set(props, prop, value, receiver);
			return Reflect.set(target2, prop, value, receiver);
		}, "set")
	});
}
__name$7(withProps, "withProps");
function withProp(target, prop, value) {
	return withProps(target, Object.defineProperty(/* @__PURE__ */ Object.create(null), prop, {
		value,
		writable: false
	}));
}
__name$7(withProp, "withProp");
function createShadow(ctx, target, property, receiver) {
	if (!property) return receiver;
	const origin = Reflect.getOwnPropertyDescriptor(target, property)?.value;
	if (!origin) return receiver;
	return withProp(receiver, property, ctx.extend({ [symbols.shadow]: origin }));
}
__name$7(createShadow, "createShadow");
function createShadowMethod(ctx, value, outer, shadow) {
	return new Proxy(value, { apply: /* @__PURE__ */ __name$7((target, thisArg, args) => {
		if (thisArg === outer) thisArg = shadow;
		return getTraceable(ctx, Reflect.apply(target, thisArg, args));
	}, "apply") });
}
__name$7(createShadowMethod, "createShadowMethod");
function createTraceable(ctx, value, tracker) {
	if (ctx[symbols.shadow] && !tracker.noShadow) ctx = Object.getPrototypeOf(ctx);
	const proxy = new Proxy(value, {
		get: /* @__PURE__ */ __name$7((target, prop, receiver) => {
			if (prop === symbols.original) return target;
			if (prop === tracker.property) return ctx;
			if (typeof prop === "symbol") return Reflect.get(target, prop, receiver);
			if (tracker.associate && ctx.reflect.props[`${tracker.associate}.${prop}`]) return Reflect.get(ctx, `${tracker.associate}.${prop}`, withProp(ctx, symbols.receiver, receiver));
			let shadow, innerValue;
			const desc = getPropertyDescriptor(target, prop);
			if (desc && "value" in desc) innerValue = desc.value;
			else {
				shadow = createShadow(ctx, target, tracker.property, receiver);
				innerValue = Reflect.get(target, prop, shadow);
			}
			const innerTracker = innerValue?.[symbols.tracker];
			if (innerTracker) return createTraceable(ctx, innerValue, innerTracker);
			else if (!tracker.noShadow && typeof innerValue === "function") {
				shadow ??= createShadow(ctx, target, tracker.property, receiver);
				return createShadowMethod(ctx, innerValue, receiver, shadow);
			} else return innerValue;
		}, "get"),
		set: /* @__PURE__ */ __name$7((target, prop, value2, receiver) => {
			if (prop === symbols.original) return false;
			if (prop === tracker.property) return false;
			if (typeof prop === "symbol") return Reflect.set(target, prop, value2, receiver);
			if (tracker.associate && ctx.reflect.props[`${tracker.associate}.${prop}`]) return Reflect.set(ctx, `${tracker.associate}.${prop}`, value2, withProp(ctx, symbols.receiver, receiver));
			const shadow = createShadow(ctx, target, tracker.property, receiver);
			return Reflect.set(target, prop, value2, shadow);
		}, "set"),
		apply: /* @__PURE__ */ __name$7((target, thisArg, args) => {
			return applyTraceable(proxy, target, thisArg, args);
		}, "apply")
	});
	return proxy;
}
__name$7(createTraceable, "createTraceable");
function applyTraceable(proxy, value, thisArg, args) {
	if (!value[symbols.invoke]) return Reflect.apply(value, thisArg, args);
	return value[symbols.invoke].apply(proxy, args);
}
__name$7(applyTraceable, "applyTraceable");
function createCallable(name, proto, tracker) {
	const self = /* @__PURE__ */ __name$7(function(...args) {
		return applyTraceable(createTraceable(self["ctx"], self, tracker), self, this, args);
	}, "self");
	defineProperty(self, "name", name);
	return Object.setPrototypeOf(self, proto);
}
__name$7(createCallable, "createCallable");
function handleError(info, reason, getOuterStack) {
	const innerLines = info.error.stack.split("\n");
	if (typeof reason?.stack !== "string") {
		const outerError = new Error(reason);
		const lines2 = outerError.stack.split("\n");
		lines2.splice(1, Infinity, ...getOuterStack());
		outerError.stack = lines2.join("\n");
		throw outerError;
	}
	const lines = reason.stack.split("\n");
	let index = lines.indexOf(innerLines[2]);
	if (index === -1) throw reason;
	index -= info.offset;
	while (index > 0) {
		if (!lines[index - 1].endsWith(" (<anonymous>)")) break;
		index -= 1;
	}
	lines.splice(index, Infinity, ...getOuterStack());
	reason.stack = lines.join("\n");
	throw reason;
}
__name$7(handleError, "handleError");
function composeError(callback, getOuterStack = buildOuterStack()) {
	const info = {
		offset: 1,
		error: /* @__PURE__ */ new Error()
	};
	try {
		const result = callback(info);
		if (isObject$2(result) && "then" in result) return result.then(void 0, (reason) => handleError(info, reason, getOuterStack));
		else return result;
	} catch (reason) {
		handleError(info, reason, getOuterStack);
	}
}
__name$7(composeError, "composeError");
function buildOuterStack(offset = 0) {
	const outerError = /* @__PURE__ */ new Error();
	return () => outerError.stack.split("\n").slice(3 + offset);
}
__name$7(buildOuterStack, "buildOuterStack");
function isBailed(value) {
	return value !== null && value !== false && value !== void 0;
}
__name$7(isBailed, "isBailed");
var EventsService = class {
	constructor(ctx) {
		this.ctx = ctx;
		defineProperty(this, symbols.tracker, {
			property: "ctx",
			noShadow: true
		});
		this.on("internal/listener", function(name, listener, options) {
			if (name === "internal/update" && !options.global) return (this.fiber._hooks["internal/update"] ??= new DisposableList())[options.prepend ? "unshift" : "push"](listener);
		});
		this.on("internal/update", function(config, noSave, next) {
			const cbs = [...this._hooks["internal/update"] || []];
			const _next = /* @__PURE__ */ __name$7(() => {
				return (cbs.shift() ?? next).call(this, config, noSave, _next);
			}, "_next");
			return _next();
		}, {
			global: true,
			prepend: true
		});
	}
	ctx;
	static {
		__name$7(this, "EventsService");
	}
	_hooks = {};
	dispatch(type, args) {
		const thisArg = typeof args[0] === "object" || typeof args[0] === "function" ? args.shift() : null;
		const name = args.shift();
		if (!name.startsWith("internal/")) this.emit("internal/dispatch", type, name, args, thisArg);
		const filter = thisArg?.[Context$1.filter];
		return (this._hooks[name] || []).filter((hook) => hook.global || !filter || filter.call(thisArg, hook.ctx)).map((hook) => hook.callback.bind(thisArg));
	}
	async parallel(...args) {
		const errors = (await Promise.allSettled(this.dispatch("emit", args).map(async (cb) => cb(...args)))).filter((result) => result.status === "rejected");
		if (errors.length) throw new AggregateError(errors.map((error) => error.reason));
	}
	emit(...args) {
		this.dispatch("emit", args).map((cb) => cb(...args));
	}
	async serial(...args) {
		for (const cb of this.dispatch("serial", args)) {
			const result = await cb(...args);
			if (isBailed(result)) return result;
		}
	}
	bail(...args) {
		for (const cb of this.dispatch("bail", args)) {
			const result = cb(...args);
			if (isBailed(result)) return result;
		}
	}
	waterfall(...args) {
		const cbs = this.dispatch("waterfall", args);
		const inner = args.pop();
		const next = /* @__PURE__ */ __name$7(() => {
			return (cbs.shift() ?? inner)(...args);
		}, "next");
		args.push(next);
		return next();
	}
	register(label, hooks, callback, options) {
		const method = options.prepend ? "unshift" : "push";
		return this.ctx.fiber.effect(() => {
			hooks[method]({
				ctx: this.ctx,
				callback,
				...options
			});
			return () => this.unregister(hooks, callback);
		}, label);
	}
	unregister(hooks, callback) {
		const index = hooks.findIndex((hook) => hook.callback === callback);
		if (index >= 0) {
			hooks.splice(index, 1);
			return true;
		}
	}
	on(name, listener, options) {
		if (typeof options !== "object") options = { prepend: options };
		this.ctx.fiber.assertActive();
		listener = this.ctx.reflect.bind(listener);
		const result = this.bail(this.ctx, "internal/listener", name, listener, options);
		if (result) return result;
		const hooks = this._hooks[name] ||= [];
		const label = `ctx.on(${typeof name === "string" ? JSON.stringify(name) : name.toString()})`;
		return this.register(label, hooks, listener, options);
	}
	once(name, listener, options) {
		const dispose = this.on(name, function(...args) {
			dispose();
			return listener.apply(this, args);
		}, options);
		return dispose;
	}
};
var defaultFormatters = {
	s: /* @__PURE__ */ __name$7((value) => String(value), "s"),
	d: /* @__PURE__ */ __name$7((value) => Math.trunc(Number(value)), "d"),
	i: /* @__PURE__ */ __name$7((value) => Math.trunc(Number(value)), "i"),
	f: /* @__PURE__ */ __name$7((value) => Number(value), "f"),
	o: /* @__PURE__ */ __name$7((value) => JSON.stringify(value), "o"),
	O: /* @__PURE__ */ __name$7((value) => JSON.stringify(value), "O"),
	c: /* @__PURE__ */ __name$7(() => "", "c"),
	C: /* @__PURE__ */ __name$7((value, exporter, message) => {
		return Logger.color(exporter, Logger.code(message.name, exporter.colors), value);
	}, "C")
};
function isAggregateError(error) {
	return error instanceof Error && Array.isArray(error["errors"]);
}
__name$7(isAggregateError, "isAggregateError");
var Logger = class {
	constructor(options, service) {
		this.service = service;
		Object.assign(this, options);
		this.error = this._method("error", 0);
		this.info = this._method("info", 1);
		this.warn = this._method("warn", 2);
		this.debug = this._method("debug", 3);
	}
	service;
	static {
		__name$7(this, "Logger");
	}
	static color(exporter, code, value, decoration = "") {
		if (!exporter.colors) return "" + value;
		return `\x1B[3${code < 8 ? code : "8;5;" + code}${exporter.colors >= 2 ? decoration : ""}m${value}\x1B[0m`;
	}
	static code(name, level) {
		let hash = 0;
		for (let i = 0; i < name.length; i++) {
			hash = (hash << 3) - hash + name.charCodeAt(i) + 13;
			hash |= 0;
		}
		const colors = !level ? [] : level >= 2 ? c256 : c16;
		return colors[Math.abs(hash) % colors.length];
	}
	static format(exporter, message) {
		const args = message.args.slice();
		if (args[0] instanceof Error) {
			args[0] = args[0].stack || args[0].message;
			args.unshift("%s");
		} else if (typeof args[0] !== "string") args.unshift("%o");
		let format = args.shift();
		format = format.replace(/%([a-zA-Z%])/g, (match, char) => {
			if (match === "%%") return "%";
			const formatter = exporter.formatters?.[char] ?? defaultFormatters[char];
			if (typeof formatter === "function") return formatter(args.shift(), exporter, message);
			return match;
		});
		const oFormatter = exporter.formatters?.o ?? defaultFormatters.o;
		for (let arg of args) {
			if (typeof arg === "object" && arg) arg = oFormatter(arg, exporter, message);
			format += " " + arg;
		}
		const { maxLength = 10240 } = exporter;
		return format.split(/\r?\n/g).map((line) => {
			return line.slice(0, maxLength) + (line.length > maxLength ? "..." : "");
		}).join("\n");
	}
	_method(type, level) {
		return (...args) => {
			if (args.length === 1 && args[0] instanceof Error) {
				if (args[0].cause) this[type](args[0].cause);
				else if (isAggregateError(args[0])) {
					args[0].errors.forEach((error) => this[type](error));
					return;
				}
			}
			const sn = ++this.service._snMessage;
			const ts = Date.now();
			for (const exporter of this.service.exporters.values()) {
				if ((exporter.levels?.[this.name] ?? exporter.levels?.default ?? this.level ?? 1) < level) continue;
				const message = {
					sn,
					ts,
					type,
					level,
					name: this.name,
					...this.meta,
					args
				};
				exporter.export(message);
			}
		};
	}
};
var c16 = [
	6,
	2,
	3,
	4,
	5,
	1
];
var c256 = [
	20,
	21,
	26,
	27,
	32,
	33,
	38,
	39,
	40,
	41,
	42,
	43,
	44,
	45,
	56,
	57,
	62,
	63,
	68,
	69,
	74,
	75,
	76,
	77,
	78,
	79,
	80,
	81,
	92,
	93,
	98,
	99,
	112,
	113,
	129,
	134,
	135,
	148,
	149,
	160,
	161,
	162,
	163,
	164,
	165,
	166,
	167,
	168,
	169,
	170,
	171,
	172,
	173,
	178,
	179,
	184,
	185,
	196,
	197,
	198,
	199,
	200,
	201,
	202,
	203,
	204,
	205,
	206,
	207,
	208,
	209,
	214,
	215,
	220,
	221
];
var LoggerService = class _LoggerService {
	static {
		__name$7(this, "LoggerService");
	}
	bufferSize = 1e3;
	buffer = [];
	ctx;
	_snMessage = 0;
	_snExporter = 0;
	exporters = /* @__PURE__ */ new Map();
	constructor(ctx) {
		const tracker = {
			property: "ctx",
			noShadow: true
		};
		const self = createCallable("logger", joinPrototype(Object.getPrototypeOf(this), Function.prototype), tracker);
		Object.assign(self, this);
		self.ctx = ctx;
		defineProperty(self, symbols.tracker, tracker);
		self.exporter({
			colors: 3,
			export: /* @__PURE__ */ __name$7((message) => {
				self.buffer.push(message);
				if (self.buffer.length > self.bufferSize) self.buffer = self.buffer.slice(-self.bufferSize);
			}, "export")
		});
		return self;
	}
	exporter(exporter) {
		return this.ctx.effect(() => {
			this.exporters.set(++this._snExporter, exporter);
			return () => this.exporters.delete(this._snExporter);
		}, "ctx.logger.exporter()");
	}
	_resolveConfig() {
		let intercept = this.ctx[symbols.intercept];
		const configs = [];
		while ("logger" in intercept) {
			if (Object.hasOwn(intercept, "logger")) configs.unshift(intercept["logger"]);
			intercept = Object.getPrototypeOf(intercept);
		}
		return Object.assign({}, ...configs);
	}
	[symbols.invoke](name) {
		const config = this._resolveConfig();
		const fiber = (this.ctx[symbols.shadow] ?? this.ctx).fiber;
		name ??= config.name;
		name ??= hyphenate(fiber.name);
		return new Logger({
			name,
			level: config.level,
			meta: { fiber: new WeakRef(fiber) }
		}, this);
	}
	static {
		for (const type of [
			"error",
			"info",
			"warn",
			"debug"
		]) _LoggerService.prototype[type] = function(...args) {
			return this()[type](...args);
		};
	}
};
var kValidationError = /* @__PURE__ */ Symbol.for("ValidationError");
var ValidationError = class extends TypeError {
	static {
		__name$7(this, "ValidationError");
	}
	name = "ValidationError";
	constructor(issues) {
		super(`invalid config:
` + issues.map((issue) => {
			if (issue.path) return `  - ${issue.message} (at ${issue.path.join(".")})`;
			else return `  - ${issue.message}`;
		}).join("\n"));
	}
};
Object.defineProperty(ValidationError.prototype, kValidationError, { value: true });
function resolveConfig(runtime, config) {
	if (!runtime.Config) return config;
	const result = runtime.Config["~standard"].validate(config);
	if ("then" in result) throw new TypeError("Async config validation is not supported");
	if (result.issues) throw new ValidationError(result.issues);
	else return result.value;
}
__name$7(resolveConfig, "resolveConfig");
var CordisError = class _CordisError extends Error {
	constructor(code, message) {
		super(message ?? _CordisError.Code[code]);
		this.code = code;
	}
	code;
	static {
		__name$7(this, "CordisError");
	}
};
((CordisError2) => {
	CordisError2.Code = { INACTIVE_EFFECT: "cannot create effect on inactive context" };
})(CordisError || (CordisError = {}));
var INACTIVE = "__INACTIVE__";
var Fiber = class {
	constructor(parent, config, inject, runtime, getOuterStack) {
		this.parent = parent;
		this.inject = inject;
		this.runtime = runtime;
		const collect = /* @__PURE__ */ __name$7((dispose) => {
			this._disposables.push(dispose);
		}, "collect");
		if (runtime) {
			this.uid = parent.registry.counter;
			this.ctx = this.context = parent.extend({ fiber: this });
			const injectEntries = Object.entries(this.inject);
			if (injectEntries.length) {
				this.ctx[Context$1.intercept] = Object.create(parent[Context$1.intercept]);
				for (const [name, config2] of injectEntries) {
					if (isNullable(config2)) continue;
					this.ctx[Context$1.intercept][name] = config2;
				}
			}
			this._runner = {
				epoch: INACTIVE,
				getOuterStack,
				execute: /* @__PURE__ */ __name$7(function() {
					if (isConstructor(runtime.callback)) {
						const instance = new runtime.callback(this.ctx, this.config);
						for (const hook of instance?.[symbols.initHooks] ?? []) hook();
						return instance?.[symbols.init]?.();
					} else return runtime.callback(this.ctx, this.config);
				}, "execute"),
				collect
			};
			this.context.emit("internal/plugin", this);
			for (const name of Object.keys(this.inject)) this._checkImpl(name);
			this.dispose = parent.fiber.effect(() => {
				const remove = runtime.fibers.push(this);
				try {
					this.config = resolveConfig(runtime, config);
					this._refresh();
				} catch (error) {
					this.ctx.logger.error(error);
					this._error = error;
				}
				return async () => {
					this.uid = null;
					this.context.emit("internal/plugin", this);
					if (this.ctx.registry.has(runtime.callback)) {
						remove();
						if (!runtime.fibers.length) this.ctx.registry.delete(runtime.callback);
					}
					this._setEpoch(INACTIVE);
					while (this.inertia) await this.inertia;
				};
			}, "ctx.plugin()");
		} else {
			this.uid = 0;
			this.ctx = this.context = parent;
			this.state = 2;
			this.store = /* @__PURE__ */ Object.create(null);
			this._runner = {
				epoch: "",
				getOuterStack,
				execute: /* @__PURE__ */ __name$7(() => {}, "execute"),
				collect
			};
			this.dispose = () => this.restart();
		}
	}
	parent;
	inject;
	runtime;
	static {
		__name$7(this, "Fiber");
	}
	uid;
	ctx;
	config;
	state = 0;
	dispose;
	store;
	inertia;
	_hooks = /* @__PURE__ */ Object.create(null);
	_disposables = new DisposableList();
	context;
	_error;
	_runner;
	_store = /* @__PURE__ */ Object.create(null);
	get name() {
		let fiber = this;
		do {
			if (fiber.runtime?.name) return fiber.runtime.name;
			fiber = fiber.parent.fiber;
		} while (fiber !== fiber.parent.fiber);
		return "root";
	}
	assertActive() {
		if (this.uid !== null) return;
		throw new CordisError("INACTIVE_EFFECT");
	}
	_execute(runner) {
		const oldEpoch = runner.epoch;
		return composeError((info) => {
			const safeCollect = /* @__PURE__ */ __name$7((dispose) => {
				if (typeof dispose === "function") runner.collect(dispose);
				else if (!isNullable(dispose)) throw new TypeError("Invalid effect");
			}, "safeCollect");
			const effect = runner.execute.call(this);
			if (typeof effect === "function") return runner.collect(effect);
			else if (isNullable(effect)) {} else if (!isObject$2(effect)) throw new TypeError("Invalid effect");
			else if ("then" in effect) return effect.then(safeCollect);
			else if (Symbol.iterator in effect) {
				info.error = /* @__PURE__ */ new Error();
				const iter = effect[Symbol.iterator]();
				while (true) {
					const result = iter.next();
					safeCollect(result.value);
					if (result.done) return;
				}
			} else if (Symbol.asyncIterator in effect) {
				const iter = effect[Symbol.asyncIterator]();
				return (async () => {
					await Promise.resolve();
					info.error = /* @__PURE__ */ new Error();
					while (true) {
						if (runner.epoch !== oldEpoch) return;
						const result = await iter.next();
						safeCollect(result.value);
						if (result.done) return;
					}
				})();
			} else throw new TypeError("Invalid effect");
		}, runner.getOuterStack);
	}
	effect(execute, label = "anonymous") {
		this.assertActive();
		const disposables = [];
		const dispose = /* @__PURE__ */ __name$7(() => {
			let task2;
			for (const dispose2 of disposables.splice(0).reverse()) if (task2) task2 = task2.then(dispose2);
			else {
				const result = dispose2();
				if (isObject$2(result) && "then" in result) task2 = result;
			}
			return task2;
		}, "dispose");
		const meta = {
			label,
			children: []
		};
		const runner = {
			execute,
			epoch: true,
			collect: /* @__PURE__ */ __name$7((dispose2) => {
				disposables.push(dispose2);
				this._disposables.delete(dispose2);
				if (dispose2[symbols.effect]) meta.children.push(dispose2[symbols.effect]);
			}, "collect"),
			getOuterStack: buildOuterStack()
		};
		let task;
		try {
			task = this._execute(runner);
		} catch (reason) {
			dispose();
			throw reason;
		}
		task?.catch(dispose).catch((error) => this.ctx.logger.error(error));
		const wrapper = defineProperty(() => {
			if (!runner.epoch) return;
			runner.epoch = false;
			return task ? task.then(dispose) : dispose();
		}, symbols.effect, meta);
		const disposeAsync = /* @__PURE__ */ __name$7(() => {
			if (!runner.epoch) return;
			runner.epoch = false;
			return dispose();
		}, "disposeAsync");
		wrapper.then = async (onFulfilled, onRejected) => {
			return Promise.resolve(task).then(() => disposeAsync).then(onFulfilled, onRejected);
		};
		disposables.push(this._disposables.push(wrapper));
		return wrapper;
	}
	getEffects() {
		return [...this._disposables].map((dispose) => dispose[symbols.effect]).filter(Boolean);
	}
	_getState() {
		if (this.uid === null) return 4;
		if (this._error) return 3;
		if (this._runner.epoch !== INACTIVE) return 2;
		return 0;
	}
	_updateState(callback) {
		const oldState = this.state;
		this.state = callback() ?? this._getState();
		if (oldState === this.state) return;
		this.context.emit("internal/status", this, oldState);
		if (oldState !== 2 && this.state !== 2) return;
		for (const key of Reflect.ownKeys(this.ctx.reflect.store)) {
			const impl = this.ctx.reflect.store[key];
			if (impl.fiber !== this) continue;
			this.ctx.reflect.notify([impl.name]);
		}
	}
	_checkImpl(name) {
		const impl = this.ctx.reflect._getImpl(name, true);
		if (!impl) return delete this._store[name];
		try {
			if (impl.check && !impl.check.call(getTraceable(this.ctx, impl.value))) return delete this._store[name];
		} catch (error) {
			impl.fiber.ctx.logger.error(error);
			return delete this._store[name];
		}
		this._store[name] = impl;
	}
	_refresh() {
		let epoch = false;
		epoch = "";
		for (const name of Object.keys(this.inject)) {
			const impl = this._store[name];
			if (!impl) {
				epoch = INACTIVE;
				break;
			}
			epoch += ":" + impl.fiber.uid;
		}
		this._setEpoch(epoch);
	}
	_setEpoch(epoch) {
		const oldEpoch = this._runner.epoch;
		if (epoch === oldEpoch) return;
		this._runner.epoch = epoch;
		if (this.inertia) return;
		this._updateState(() => {
			if (epoch !== INACTIVE && oldEpoch === INACTIVE) {
				this.inertia = this._reload();
				return 1;
			} else {
				this.inertia = this._unload();
				return 5;
			}
		});
	}
	async _reload() {
		this.store = { ...this._store };
		const oldEpoch = this._runner.epoch;
		try {
			await Promise.resolve();
			await this._execute(this._runner);
		} catch (reason) {
			this.ctx.logger.error(reason);
			this._error = reason;
			this._runner.epoch = INACTIVE;
		}
		this._updateState(() => {
			if (this._runner.epoch === oldEpoch) this.inertia = void 0;
			else {
				this.inertia = this._unload();
				return 5;
			}
		});
	}
	async _unload() {
		await Promise.all(this._disposables.clear().map(async (dispose) => {
			try {
				await composeError(async (info) => {
					await Promise.resolve();
					info.error = /* @__PURE__ */ new Error();
					await dispose();
				}, this._runner.getOuterStack);
			} catch (reason) {
				this.ctx.logger.error(reason);
			}
		}));
		this.store = void 0;
		this._updateState(() => {
			if (this._runner.epoch === INACTIVE) this.inertia = void 0;
			else {
				this.inertia = this._reload();
				return 1;
			}
		});
	}
	async await() {
		while (this.inertia) await this.inertia;
		if (this._error) throw this._error;
		return this;
	}
	async restart() {
		this.assertActive();
		this._setEpoch(INACTIVE);
		this._refresh();
		await this.await();
	}
	update(config, noSave = false) {
		this.assertActive();
		config = resolveConfig(this.runtime, config);
		this.context.waterfall(this, "internal/update", config, noSave, () => {
			this.config = config;
			this._error = void 0;
			return this.restart();
		});
	}
};
function enhanceError(error) {
	const lines = error.stack.split("\n");
	lines.splice(0, 2, `Error: ${error.message}`);
	error.stack = lines.join("\n");
	return error;
}
__name$7(enhanceError, "enhanceError");
var RESERVED_WORDS = ["prototype", "then"];
function isSpecialProperty(prop) {
	return typeof prop === "symbol" || RESERVED_WORDS.includes(prop) || parseInt(prop).toString() === prop || prop.startsWith("_");
}
__name$7(isSpecialProperty, "isSpecialProperty");
var ReflectService = class {
	constructor(ctx) {
		this.ctx = ctx;
		defineProperty(this, symbols.tracker, {
			property: "ctx",
			noShadow: true
		});
		this.mixin("reflect", [
			"get",
			"set",
			"provide",
			"accessor",
			"mixin"
		]);
		this.mixin("fiber", ["runtime", "effect"]);
		this.mixin("registry", ["inject", "plugin"]);
		this.mixin("events", [
			"on",
			"once",
			"parallel",
			"emit",
			"serial",
			"bail",
			"waterfall"
		]);
	}
	ctx;
	static {
		__name$7(this, "ReflectService");
	}
	static handler = {
		get: /* @__PURE__ */ __name$7((target, prop, ctx) => {
			if (isSpecialProperty(prop)) return Reflect.get(target, prop, ctx);
			if (Reflect.has(target, prop)) return getTraceable(ctx, Reflect.get(target, prop, ctx));
			const error = /* @__PURE__ */ new Error(`cannot get property "${prop}" without inject`);
			try {
				const def = target.reflect.props[prop];
				if (def?.type === "accessor") return def.get.call(ctx, ctx[symbols.receiver], error);
				if (!ctx.fiber.runtime) return ctx.reflect.get(prop, false);
				return ctx.events.waterfall("internal/get", ctx, prop, error, () => {
					const key = target[symbols.isolate][prop];
					let fiber = (ctx[symbols.shadow] ?? ctx).fiber;
					while (true) {
						const impl = fiber.store?.[prop];
						if (impl) return getTraceable(ctx, impl.value);
						if (prop in fiber.inject) {
							error.message = `cannot get required service "${prop}" in inactive context`;
							throw error;
						}
						if (!fiber.runtime) throw error;
						if (fiber.parent[symbols.isolate][prop] !== key) throw error;
						fiber = fiber.parent.fiber;
					}
				});
			} catch (e) {
				throw e === error ? enhanceError(e) : e;
			}
		}, "get"),
		set: /* @__PURE__ */ __name$7((target, prop, value, ctx) => {
			if (isSpecialProperty(prop)) return Reflect.set(target, prop, value, ctx);
			const error = /* @__PURE__ */ new Error(`cannot set property "${prop}" without provide`);
			const def = target.reflect.props[prop];
			if (!def) {
				if (!ctx.fiber.runtime) return Reflect.set(target, prop, value, ctx);
				throw enhanceError(error);
			}
			try {
				if (def.type === "accessor") {
					if (!def.set) return false;
					return def.set.call(ctx, value, ctx[symbols.receiver], error);
				}
				return ctx.events.waterfall("internal/set", ctx, prop, value, error, () => {
					return ctx.reflect.set(prop, value, error);
				});
			} catch (e) {
				throw e === error ? enhanceError(e) : e;
			}
		}, "set"),
		has: /* @__PURE__ */ __name$7((target, prop) => {
			if (isSpecialProperty(prop)) return Reflect.has(target, prop);
			if (Reflect.has(target, prop)) return true;
			return !!target.reflect.props[prop];
		}, "has")
	};
	store = /* @__PURE__ */ Object.create(null);
	props = /* @__PURE__ */ Object.create(null);
	get(name, strict = true) {
		return getTraceable(this.ctx, this._getImpl(name, strict)?.value);
	}
	_getImpl(name, strict = true) {
		const key = this.ctx[symbols.isolate][name];
		const impl = key && this.store[key];
		if (!impl) return;
		if (strict && impl.fiber.state !== 2) return;
		return impl;
	}
	set(name, value, error) {
		const key = this.ctx[symbols.isolate][name];
		const impl = this.store[key];
		if (!impl) throw new Error(`cannot set property "${name}" without provide`);
		if (impl.fiber !== this.ctx.fiber) throw new Error(`cannot set property "${name}" in multiple fibers`);
		impl.value = value;
		return true;
	}
	provide(name, value, check) {
		return this.ctx.fiber.effect(() => {
			if (!this.props[name]) this.props[name] ??= { type: "service" };
			else if (this.props[name].type !== "service") throw new Error(`property "${name}" is already declared as ${this.props[name].type}`);
			this.props[name] = { type: "service" };
			this.ctx.root[symbols.isolate][name] ??= Symbol(name);
			const key = this.ctx[symbols.isolate][name];
			const impl = {
				name,
				value,
				fiber: this.ctx.fiber,
				check
			};
			if (this.store[key]) throw new Error(`service "${name}" has been registered at <${this.store[key].fiber.name}>`);
			this.store[key] = impl;
			this.ctx.fiber.store[name] = impl;
			if (this.ctx.fiber.state === 2) this.notify([name]);
			return async () => {
				delete this.store[key];
				const fibers = this.notify([name]);
				await Promise.allSettled(fibers.map((fiber) => fiber.await()));
				delete this.ctx.fiber.store[name];
			};
		}, `ctx.provide(${JSON.stringify(name)})`);
	}
	notify(names, filter = (ctx, name) => ctx[symbols.isolate][name] === this.ctx[symbols.isolate][name]) {
		const fibers = [];
		for (const runtime of this.ctx.registry.values()) for (const fiber of runtime.fibers) {
			let hasUpdate = false;
			for (const name of names) {
				if (!(name in fiber.inject)) continue;
				if (!filter(fiber.ctx, name)) continue;
				hasUpdate = true;
				fiber._checkImpl(name);
			}
			if (!hasUpdate) continue;
			fiber._refresh();
			fibers.push(fiber);
		}
		for (const name of names) {
			const self = Object.create(this.ctx);
			self[symbols.filter] = (target) => filter(target, name);
			this.ctx.events.emit(self, "internal/service", name, this._getImpl(name, false)?.value);
		}
		return fibers;
	}
	accessor(name, options) {
		return this.ctx.fiber.effect(() => {
			if (name in this.props) throw new Error(`property "${name}" is already declared as ${this.props[name].type}`);
			this.props[name] = {
				type: "accessor",
				...options
			};
			return () => delete this.props[name];
		}, `ctx.accessor(${JSON.stringify(name)})`);
	}
	mixin(source, mixins) {
		const self = this;
		return this.ctx.fiber.effect(function* () {
			const entries = Array.isArray(mixins) ? mixins.map((key) => [key, key]) : Object.entries(mixins);
			const getTarget = /* @__PURE__ */ __name$7((ctx, error) => {
				return ctx[source];
			}, "getTarget");
			for (const [key, value] of entries) yield self.accessor(value, {
				get(receiver, error) {
					const service = getTarget(this, error);
					if (isNullable(service)) return service;
					const mixin = receiver ? withProps(receiver, service) : service;
					const value2 = Reflect.get(service, key, mixin);
					if (typeof value2 !== "function") return value2;
					return value2.bind(mixin ?? service);
				},
				set(value2, receiver, error) {
					const service = getTarget(this, error);
					const mixin = receiver ? withProps(receiver, service) : service;
					return Reflect.set(service, key, value2, mixin);
				}
			});
		}, `ctx.mixin(${JSON.stringify(source)})`);
	}
	trace(value) {
		return getTraceable(this.ctx, value);
	}
	bind(callback) {
		return new Proxy(callback, {
			apply: /* @__PURE__ */ __name$7((target, thisArg, args) => {
				return Reflect.apply(target, this.trace(thisArg), args.map((arg) => this.trace(arg)));
			}, "apply"),
			construct: /* @__PURE__ */ __name$7((target, args, newTarget) => {
				return Reflect.construct(target, args.map((arg) => this.trace(arg)), newTarget);
			}, "construct")
		});
	}
};
function isApplicable(object) {
	return object && typeof object === "object" && typeof object.apply === "function";
}
__name$7(isApplicable, "isApplicable");
function Inject(name, config) {
	return function(value, decorator) {
		if (decorator.kind === "class") {
			if (!Object.hasOwn(value, "inject")) {
				defineProperty(value, "inject", Object.create(Object.getPrototypeOf(value).inject ?? null));
				defineProperty(value.inject, symbols.checkProto, true);
			}
			value.inject[name] = config;
		} else if (decorator.kind === "method") {
			const inject = (value[symbols.metadata] ??= {}).inject ??= /* @__PURE__ */ Object.create(null);
			inject[name] = config;
			decorator.addInitializer(function() {
				const property = this[symbols.tracker]?.property;
				(this[symbols.initHooks] ??= []).push(() => {
					this.ctx.inject(inject, (ctx) => {
						return value.call(property ? withProps(this, { [property]: ctx }) : this);
					});
				});
			});
		} else throw new Error("@Inject() can only be used on class or class methods");
	};
}
__name$7(Inject, "Inject");
((Inject2) => {
	function resolve(inject, result = /* @__PURE__ */ Object.create(null)) {
		if (!inject) return result;
		if (Array.isArray(inject)) for (const name of inject) result[name] = null;
		else if (Reflect.has(inject, symbols.checkProto)) {
			Object.assign(result, resolve(Object.getPrototypeOf(inject)));
			for (const name of Object.keys(inject)) result[name] = inject[name] ?? null;
		} else for (const name of Object.keys(inject)) result[name] = inject[name] ?? null;
		return result;
	}
	Inject2.resolve = resolve;
	__name$7(resolve, "resolve");
})(Inject || (Inject = {}));
var RegistryService = class {
	constructor(ctx) {
		this.ctx = ctx;
		defineProperty(this, symbols.tracker, {
			property: "ctx",
			noShadow: true
		});
	}
	ctx;
	static {
		__name$7(this, "RegistryService");
	}
	_counter = 0;
	_internal = /* @__PURE__ */ new Map();
	get counter() {
		return ++this._counter;
	}
	get size() {
		return this._internal.size;
	}
	resolve(plugin) {
		try {
			if (typeof plugin === "function") return plugin;
			if (isApplicable(plugin)) return plugin.apply;
		} catch {}
	}
	get(plugin) {
		const key = this.resolve(plugin);
		return key && this._internal.get(key);
	}
	has(plugin) {
		const key = this.resolve(plugin);
		return !!key && this._internal.has(key);
	}
	delete(plugin) {
		const key = this.resolve(plugin);
		const runtime = key && this._internal.get(key);
		if (!runtime) return;
		this._internal.delete(key);
		for (const fiber of runtime.fibers) fiber.dispose();
		return runtime;
	}
	keys() {
		return this._internal.keys();
	}
	values() {
		return this._internal.values();
	}
	entries() {
		return this._internal.entries();
	}
	forEach(callback) {
		return this._internal.forEach(callback);
	}
	inject(inject, callback) {
		return this.plugin({
			inject,
			apply: callback,
			name: callback.name
		});
	}
	plugin(plugin, config, getOuterStack = buildOuterStack()) {
		const callback = this.resolve(plugin);
		if (!callback) throw new Error("invalid plugin, expect function or object with an \"apply\" method, received " + typeof plugin);
		this.ctx.fiber.assertActive();
		let runtime = this._internal.get(callback);
		if (!runtime) {
			let name = plugin.name;
			if (name === "apply") name = void 0;
			runtime = {
				name,
				callback,
				fibers: new DisposableList(),
				Config: plugin.Config
			};
			this._internal.set(callback, runtime);
		}
		const fiber = new Fiber(this.ctx, config, Inject.resolve(plugin.inject), runtime, getOuterStack);
		const wrapped = Object.create(fiber);
		wrapped.then = (onFulfilled, onRejected) => {
			return fiber.await().then(onFulfilled, onRejected);
		};
		return wrapped;
	}
};
var Context$1 = class _Context {
	static {
		__name$7(this, "Context");
	}
	static effect = symbols.effect;
	static filter = symbols.filter;
	static isolate = symbols.isolate;
	static intercept = symbols.intercept;
	static is(value) {
		return !!value?.[_Context.is];
	}
	static {
		_Context.is[Symbol.toPrimitive] = () => /* @__PURE__ */ Symbol.for("cordis.is");
		_Context.prototype[_Context.is] = true;
	}
	constructor() {
		this[symbols.isolate] = /* @__PURE__ */ Object.create(null);
		this[symbols.intercept] = /* @__PURE__ */ Object.create(null);
		const self = new Proxy(this, ReflectService.handler);
		this.root = self;
		this.baseUrl = void 0;
		this.fiber = new Fiber(self, {}, /* @__PURE__ */ Object.create(null), null, () => []);
		this.reflect = new ReflectService(self);
		this.registry = new RegistryService(self);
		this.events = new EventsService(self);
		this.logger = new LoggerService(self);
		this.fiber._disposables.clear();
		return self;
	}
	[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
		return `Context <${this.fiber.name}>`;
	}
	extend(meta = {}) {
		const shadow = Reflect.getOwnPropertyDescriptor(this, symbols.shadow)?.value;
		const self = Object.create(getTraceable(this, this));
		for (const prop of Reflect.ownKeys(meta)) Object.defineProperty(self, prop, Reflect.getOwnPropertyDescriptor(meta, prop));
		if (!shadow) return self;
		return Object.assign(Object.create(self), { [symbols.shadow]: shadow });
	}
	isolate(name, label) {
		const shadow = Object.create(this[symbols.isolate]);
		shadow[name] = label ?? Symbol(name);
		return this.extend({ [symbols.isolate]: shadow });
	}
	intercept(name, config) {
		const intercept = Object.create(this[symbols.intercept]);
		intercept[name] = config;
		return this.extend({ [symbols.intercept]: intercept });
	}
};
var Service = class _Service {
	constructor(ctx, name) {
		this.ctx = ctx;
		name ??= this.constructor["provide"];
		let self = this;
		const tracker = {
			associate: name,
			property: "ctx"
		};
		if (self[symbols.invoke]) self = createCallable(name, joinPrototype(Object.getPrototypeOf(this), Function.prototype), tracker);
		self.ctx = ctx;
		self.name = name;
		defineProperty(self, symbols.tracker, tracker);
		self.ctx.reflect.provide(name, self, this[symbols.check]);
		return self;
	}
	ctx;
	static {
		__name$7(this, "Service");
	}
	static init = symbols.init;
	static check = symbols.check;
	static config = symbols.config;
	static invoke = symbols.invoke;
	static extend = symbols.extend;
	static tracker = symbols.tracker;
	static resolveConfig = symbols.resolveConfig;
	name;
	[symbols.filter](ctx) {
		return ctx[symbols.isolate][this.name] === this.ctx[symbols.isolate][this.name];
	}
	[symbols.extend](props) {
		let self;
		if (this[_Service.invoke]) self = createCallable(this.name, this, this[symbols.tracker]);
		else self = Object.create(this);
		return Object.assign(self, props);
	}
	[symbols.resolveConfig](base, head) {
		let intercept = this.ctx[Context$1.intercept];
		const configs = [];
		while (this.name in intercept) {
			if (Object.hasOwn(intercept, this.name)) configs.unshift(intercept[this.name]);
			intercept = Object.getPrototypeOf(intercept);
		}
		if (base) configs.unshift(base);
		if (head) configs.push(head);
		if (this["Config"]?.merge) return this["Config"].merge(...configs);
		else return Object.assign({}, ...configs);
	}
	static [Symbol.hasInstance](instance) {
		if (!instance) return false;
		let constructor = instance.constructor;
		while (constructor) {
			constructor = constructor.prototype?.constructor;
			if (constructor === this) return true;
			constructor &&= Object.getPrototypeOf(constructor);
		}
		return false;
	}
};
//#endregion
//#region src/common/globalVars.ts
var DATA_DIR = path.resolve("data");
if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR);
var TEMP_DIR = path.join(DATA_DIR, "temp");
var LOG_DIR = path.join(DATA_DIR, "logs");
var dbDir = path.join(DATA_DIR, "database");
if (!existsSync(dbDir)) mkdirSync(dbDir);
var selfInfo = {
	uid: "",
	uin: "",
	nick: "",
	online: false
};
var authTokenStatus = {
	hasToken: false,
	validation: "idle",
	message: "",
	loginError: ""
};
//#endregion
//#region src/common/logger.ts
defaultFormatters.h = (value) => Buffer.isBuffer(value) ? value.toString("hex") : value == null ? "" : String(value);
var DEBUG_ARGV = process.argv.includes("--debug");
var configDebug = false;
var makeLogger;
var cache$1 = /* @__PURE__ */ new Map();
function isDebugEnabled() {
	return DEBUG_ARGV || configDebug;
}
/** config 加载 / 热更新时同步进来. logLevel 目前只区分 'info' (默认) 与 'debug'. */
function setConfigLogLevel(level) {
	configDebug = level === "debug";
}
/** main 启动时注入 ctx.logger 工厂. 之后无 ctx 的模块经 getLogger 也能走统一 cordis logger。 */
function bindLoggerFactory(factory) {
	makeLogger = factory;
}
/**
* 给拿不到 ctx.logger 的模块 (client / sign / connection 等) 用的命名空间 logger。
* 返回稳定句柄, 每次调用时才解析真 logger (模块 import 时工厂常还没注入); 注入前退回 console。
* 用法与 ctx.logger 一致: logger.info(...) / logger.warn(...) / logger.error(...) / logger.debug(`...%h`, buf)。
*/
function getLogger(namespace) {
	const forward = (level) => (...args) => resolve(namespace)[level](...args);
	return {
		error: forward("error"),
		warn: forward("warn"),
		info: forward("info"),
		debug: forward("debug")
	};
}
function resolve(namespace) {
	const factory = makeLogger;
	if (!factory) return consoleShim(namespace);
	let lg = cache$1.get(namespace);
	if (!lg) {
		lg = factory(namespace);
		cache$1.set(namespace, lg);
	}
	return lg;
}
function consoleShim(namespace) {
	const p = `[${namespace}]`;
	return {
		error: (...a) => console.error(p, ...a),
		warn: (...a) => console.warn(p, ...a),
		info: (...a) => console.info(p, ...a),
		debug: (...a) => {
			if (isDebugEnabled()) console.debug(p, ...a);
		}
	};
}
//#endregion
//#region src/main/log.ts
var MAX_FILE_SIZE = 5242880;
var MAX_ENTRIES = 1e4;
function generateLogFilename() {
	return `llbot-${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}.log`.replace(/\//g, "-").replace(/:/g, "-");
}
var LOG_CACHE_SIZE = 800;
var logCache = [];
function getLogCache() {
	return logCache;
}
var inspectFormatter = (value, target) => {
	return inspect(value, {
		colors: !!target.colors,
		depth: Infinity,
		compact: true,
		breakLength: Infinity
	});
};
var Log = class {
	ctx;
	static name = "log";
	exportFile;
	currentFile;
	currentEntries;
	currentSize;
	colors;
	showTime;
	levels;
	maxLength;
	label;
	formatters;
	constructor(ctx) {
		this.ctx = ctx;
		this.exportFile = true;
		this.currentFile = path.join(LOG_DIR, generateLogFilename());
		this.currentEntries = 0;
		this.currentSize = 0;
		this.colors = false;
		this.showTime = "yyyy-MM-dd hh:mm:ss ";
		this.levels = { default: isDebugEnabled() ? 3 : 2 };
		this.formatters = {
			o: inspectFormatter,
			O: inspectFormatter
		};
		stat(this.currentFile, (err, stats) => {
			if (!err && stats) this.currentSize = stats.size;
		});
		ctx.on("llob/config-updated", (input) => {
			this.exportFile = input.log;
		});
		ctx.logger.exporter(this);
	}
	export(message) {
		const dateTime = new Date(message.ts);
		const dateTimeStr = `${dateTime.getFullYear()}-${(dateTime.getMonth() + 1).toString().padStart(2, "0")}-${dateTime.getDate().toString().padStart(2, "0")} ${dateTime.getHours().toString().padStart(2, "0")}:${dateTime.getMinutes().toString().padStart(2, "0")}:${dateTime.getSeconds().toString().padStart(2, "0")}`;
		const logRecord = {
			timestamp: message.ts,
			type: message.type,
			content: Logger.format(this, message),
			dateTimeStr
		};
		logCache.push(logRecord);
		if (logCache.length > LOG_CACHE_SIZE) logCache.shift();
		this.ctx.parallel("llob/log", logRecord);
		if (!this.exportFile) return;
		if (this.currentSize >= MAX_FILE_SIZE || this.currentEntries >= MAX_ENTRIES) this.rotate();
		try {
			const content = this.render(message) + "\n";
			appendFile(this.currentFile, content, noop);
			this.currentEntries++;
			this.currentSize += Buffer.byteLength(content);
		} catch {}
	}
	render(message) {
		const prefix = `[${message.type[0].toUpperCase()}]`;
		const space = " ".repeat(this.label?.margin ?? 1);
		let indent = 3 + space.length, output = "";
		if (this.showTime) {
			indent += this.showTime.length;
			output += Logger.color(this, 8, Time.template(this.showTime));
		}
		const code = Logger.code(message.name, this.colors);
		const label = Logger.color(this, code, message.name, ";1");
		const padLength = (this.label?.width ?? 0) + label.length - message.name.length;
		if (this.label?.align === "right") {
			output += label.padStart(padLength) + space + prefix + space;
			indent += (this.label.width ?? 0) + space.length;
		} else output += prefix + space + label.padEnd(padLength) + space;
		output += Logger.format(this, message).replace(/\n/g, "\n" + " ".repeat(indent));
		return output;
	}
	rotate() {
		this.currentFile = path.join(LOG_DIR, generateLogFilename());
		this.currentEntries = 0;
		this.currentSize = 0;
	}
};
//#endregion
//#region src/ntqqapi/types/user.ts
var Sex = /* @__PURE__ */ function(Sex) {
	Sex[Sex["Unknown"] = 0] = "Unknown";
	Sex[Sex["Male"] = 1] = "Male";
	Sex[Sex["Female"] = 2] = "Female";
	Sex[Sex["Hidden"] = 255] = "Hidden";
	return Sex;
}({});
//#endregion
//#region src/ntqqapi/types/group.ts
var GroupMsgMask = /* @__PURE__ */ function(GroupMsgMask) {
	/** 允许提醒 */
	GroupMsgMask[GroupMsgMask["AllowNotify"] = 1] = "AllowNotify";
	/** 接受消息不提醒 */
	GroupMsgMask[GroupMsgMask["AllowNotNotify"] = 4] = "AllowNotNotify";
	/** 收进群助手不提醒 */
	GroupMsgMask[GroupMsgMask["BoxNotNotify"] = 2] = "BoxNotNotify";
	/** 屏蔽 */
	GroupMsgMask[GroupMsgMask["NotAllow"] = 3] = "NotAllow";
	return GroupMsgMask;
}({});
var GroupMemberRole = /* @__PURE__ */ function(GroupMemberRole) {
	GroupMemberRole[GroupMemberRole["NotApplicable"] = 0] = "NotApplicable";
	GroupMemberRole[GroupMemberRole["Normal"] = 2] = "Normal";
	GroupMemberRole[GroupMemberRole["Admin"] = 3] = "Admin";
	GroupMemberRole[GroupMemberRole["Owner"] = 4] = "Owner";
	return GroupMemberRole;
}({});
//#endregion
//#region src/ntqqapi/types/msg.ts
var ElementType = /* @__PURE__ */ function(ElementType) {
	ElementType[ElementType["Text"] = 1] = "Text";
	ElementType[ElementType["Pic"] = 2] = "Pic";
	ElementType[ElementType["File"] = 3] = "File";
	ElementType[ElementType["Ptt"] = 4] = "Ptt";
	ElementType[ElementType["Video"] = 5] = "Video";
	ElementType[ElementType["Face"] = 6] = "Face";
	ElementType[ElementType["Reply"] = 7] = "Reply";
	ElementType[ElementType["GrayTip"] = 8] = "GrayTip";
	ElementType[ElementType["Ark"] = 10] = "Ark";
	ElementType[ElementType["MarketFace"] = 11] = "MarketFace";
	ElementType[ElementType["LiveGift"] = 12] = "LiveGift";
	ElementType[ElementType["StructLongMsg"] = 13] = "StructLongMsg";
	ElementType[ElementType["Markdown"] = 14] = "Markdown";
	ElementType[ElementType["Giphy"] = 15] = "Giphy";
	ElementType[ElementType["MultiForward"] = 16] = "MultiForward";
	ElementType[ElementType["InlineKeyboard"] = 17] = "InlineKeyboard";
	ElementType[ElementType["Calendar"] = 19] = "Calendar";
	ElementType[ElementType["YoloGameResult"] = 20] = "YoloGameResult";
	ElementType[ElementType["AvRecord"] = 21] = "AvRecord";
	ElementType[ElementType["TofuRecord"] = 23] = "TofuRecord";
	ElementType[ElementType["FaceBubble"] = 27] = "FaceBubble";
	ElementType[ElementType["ShareLocation"] = 28] = "ShareLocation";
	ElementType[ElementType["TaskTopMsg"] = 29] = "TaskTopMsg";
	ElementType[ElementType["RecommendedMsg"] = 43] = "RecommendedMsg";
	ElementType[ElementType["ActionBar"] = 44] = "ActionBar";
	return ElementType;
}({});
var AtType = /* @__PURE__ */ function(AtType) {
	AtType[AtType["Unknown"] = 0] = "Unknown";
	AtType[AtType["All"] = 1] = "All";
	AtType[AtType["One"] = 2] = "One";
	return AtType;
}({});
var IMAGE_HTTP_HOST = "https://gchat.qpic.cn";
var IMAGE_HTTP_HOST_NT = "https://multimedia.nt.qq.com.cn";
var FaceIndex = /* @__PURE__ */ function(FaceIndex) {
	FaceIndex[FaceIndex["Dice"] = 358] = "Dice";
	FaceIndex[FaceIndex["RPS"] = 359] = "RPS";
	return FaceIndex;
}({});
var FaceType = /* @__PURE__ */ function(FaceType) {
	FaceType[FaceType["Old"] = 1] = "Old";
	FaceType[FaceType["Normal"] = 2] = "Normal";
	FaceType[FaceType["Super"] = 3] = "Super";
	FaceType[FaceType["Poke"] = 5] = "Poke";
	return FaceType;
}({});
var ChatType = /* @__PURE__ */ function(ChatType) {
	ChatType[ChatType["C2C"] = 1] = "C2C";
	ChatType[ChatType["Group"] = 2] = "Group";
	ChatType[ChatType["TempC2CFromGroup"] = 100] = "TempC2CFromGroup";
	return ChatType;
}({});
//#endregion
//#region src/ntqqapi/types/notify.ts
var FriendReqType = /* @__PURE__ */ function(FriendReqType) {
	FriendReqType[FriendReqType["MeInitiator"] = 0] = "MeInitiator";
	FriendReqType[FriendReqType["PeerInitiator"] = 1] = "PeerInitiator";
	FriendReqType[FriendReqType["MeAgreed"] = 2] = "MeAgreed";
	FriendReqType[FriendReqType["MeAgreedAndAdded"] = 3] = "MeAgreedAndAdded";
	FriendReqType[FriendReqType["PeerAgreed"] = 4] = "PeerAgreed";
	FriendReqType[FriendReqType["PeerAgreedAndAdded"] = 5] = "PeerAgreedAndAdded";
	FriendReqType[FriendReqType["PeerRefused"] = 6] = "PeerRefused";
	FriendReqType[FriendReqType["MeRefused"] = 7] = "MeRefused";
	FriendReqType[FriendReqType["MeIgnored"] = 8] = "MeIgnored";
	FriendReqType[FriendReqType["MeAgreeAnyone"] = 9] = "MeAgreeAnyone";
	FriendReqType[FriendReqType["MeSetQuestion"] = 10] = "MeSetQuestion";
	FriendReqType[FriendReqType["MeAgreeAndAddFailed"] = 11] = "MeAgreeAndAddFailed";
	FriendReqType[FriendReqType["MsgInfo"] = 12] = "MsgInfo";
	FriendReqType[FriendReqType["MeInitiatorWaitPeerConfirm"] = 13] = "MeInitiatorWaitPeerConfirm";
	return FriendReqType;
}({});
var GroupNotificationType = /* @__PURE__ */ function(GroupNotificationType) {
	GroupNotificationType[GroupNotificationType["JoinRequest"] = 1] = "JoinRequest";
	GroupNotificationType[GroupNotificationType["Invitation"] = 2] = "Invitation";
	GroupNotificationType[GroupNotificationType["SetAdmin"] = 3] = "SetAdmin";
	GroupNotificationType[GroupNotificationType["Kick"] = 6] = "Kick";
	GroupNotificationType[GroupNotificationType["Quit"] = 13] = "Quit";
	GroupNotificationType[GroupNotificationType["UnsetAdmin"] = 16] = "UnsetAdmin";
	GroupNotificationType[GroupNotificationType["InvitedJoinRequest"] = 22] = "InvitedJoinRequest";
	return GroupNotificationType;
}({});
var RequestState = /* @__PURE__ */ function(RequestState) {
	RequestState[RequestState["Init"] = 0] = "Init";
	RequestState[RequestState["Unhandle"] = 1] = "Unhandle";
	RequestState[RequestState["Agreed"] = 2] = "Agreed";
	RequestState[RequestState["Refused"] = 3] = "Refused";
	RequestState[RequestState["Ignored"] = 4] = "Ignored";
	return RequestState;
}({});
//#endregion
//#region src/ntqqapi/log.ts
async function logSummaryMessage(ctx, message) {
	const direction = message.senderUid == selfInfo.uid ? "发" : "收";
	let sender = message.sendMemberName || message.sendNickName;
	const senderUin = message.senderUin;
	let summary = "";
	for (const msgEle of message.elements) switch (msgEle.elementType) {
		case ElementType.Text:
			summary += `${msgEle.textElement?.content}`;
			break;
		case ElementType.Pic:
			summary += `[图片]${msgEle.picElement?.fileName}`;
			break;
		case ElementType.Face:
			summary += `[表情]${msgEle.faceElement?.faceText || "未知表情"}`;
			break;
		case ElementType.Ptt:
			summary += `[语音]${msgEle.pttElement?.fileName}`;
			break;
		case ElementType.Video:
			summary += `[视频]${msgEle.videoElement?.fileName}`;
			break;
		case ElementType.File:
			summary += `[文件]${msgEle.fileElement?.fileName}`;
			break;
		case ElementType.Ark:
			summary += `[卡片]`;
			break;
		case ElementType.MultiForward: summary += `[合并转发]`;
	}
	if (!summary) return;
	let peerName = "";
	if (message.chatType == ChatType.Group) peerName = `群] ${message.peerName}(${message.peerUid}) ${sender}(${senderUin})`;
	else if (message.chatType == ChatType.C2C) try {
		const userUid = message.peerUid;
		const userInfo = await ctx.ntFriendApi.getFriendByUid(userUid, false);
		sender = userInfo.remark || userInfo.nick;
		peerName = `私] ${sender}(${message.peerUin})`;
	} catch {
		peerName = `私] ${sender}(${message.peerUin})`;
	}
	else if (message.chatType == ChatType.TempC2CFromGroup) peerName = `临] ${message.peerName}(${message.peerUin})`;
	const logMsg = `[${direction}-${peerName}：${summary}`;
	ctx.logger.info(logMsg);
}
//#endregion
//#region node_modules/isexe/windows.js
var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = isexe;
	isexe.sync = sync;
	var fs$10 = __require("fs");
	function checkPathExt(path, options) {
		var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
		if (!pathext) return true;
		pathext = pathext.split(";");
		if (pathext.indexOf("") !== -1) return true;
		for (var i = 0; i < pathext.length; i++) {
			var p = pathext[i].toLowerCase();
			if (p && path.substr(-p.length).toLowerCase() === p) return true;
		}
		return false;
	}
	function checkStat(stat, path, options) {
		if (!stat.isSymbolicLink() && !stat.isFile()) return false;
		return checkPathExt(path, options);
	}
	function isexe(path, options, cb) {
		fs$10.stat(path, function(er, stat) {
			cb(er, er ? false : checkStat(stat, path, options));
		});
	}
	function sync(path, options) {
		return checkStat(fs$10.statSync(path), path, options);
	}
}));
//#endregion
//#region node_modules/isexe/mode.js
var require_mode$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = isexe;
	isexe.sync = sync;
	var fs$9 = __require("fs");
	function isexe(path, options, cb) {
		fs$9.stat(path, function(er, stat) {
			cb(er, er ? false : checkStat(stat, options));
		});
	}
	function sync(path, options) {
		return checkStat(fs$9.statSync(path), options);
	}
	function checkStat(stat, options) {
		return stat.isFile() && checkMode(stat, options);
	}
	function checkMode(stat, options) {
		var mod = stat.mode;
		var uid = stat.uid;
		var gid = stat.gid;
		var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
		var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
		var u = parseInt("100", 8);
		var g = parseInt("010", 8);
		var o = parseInt("001", 8);
		var ug = u | g;
		return mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
	}
}));
//#endregion
//#region node_modules/isexe/index.js
var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	__require("fs");
	var core;
	if (process.platform === "win32" || global.TESTING_WINDOWS) core = require_windows();
	else core = require_mode$1();
	module.exports = isexe;
	isexe.sync = sync;
	function isexe(path, options, cb) {
		if (typeof options === "function") {
			cb = options;
			options = {};
		}
		if (!cb) {
			if (typeof Promise !== "function") throw new TypeError("callback not provided");
			return new Promise(function(resolve, reject) {
				isexe(path, options || {}, function(er, is) {
					if (er) reject(er);
					else resolve(is);
				});
			});
		}
		core(path, options || {}, function(er, is) {
			if (er) {
				if (er.code === "EACCES" || options && options.ignoreErrors) {
					er = null;
					is = false;
				}
			}
			cb(er, is);
		});
	}
	function sync(path, options) {
		try {
			return core.sync(path, options || {});
		} catch (er) {
			if (options && options.ignoreErrors || er.code === "EACCES") return false;
			else throw er;
		}
	}
}));
//#endregion
//#region node_modules/which/which.js
var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = which;
	which.sync = whichSync;
	var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
	var path$9 = __require("path");
	var COLON = isWindows ? ";" : ":";
	var isexe = require_isexe();
	function getNotFoundError(cmd) {
		var er = /* @__PURE__ */ new Error("not found: " + cmd);
		er.code = "ENOENT";
		return er;
	}
	function getPathInfo(cmd, opt) {
		var colon = opt.colon || COLON;
		var pathEnv = opt.path || process.env.PATH || "";
		var pathExt = [""];
		pathEnv = pathEnv.split(colon);
		var pathExtExe = "";
		if (isWindows) {
			pathEnv.unshift(process.cwd());
			pathExtExe = opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM";
			pathExt = pathExtExe.split(colon);
			if (cmd.indexOf(".") !== -1 && pathExt[0] !== "") pathExt.unshift("");
		}
		if (cmd.match(/\//) || isWindows && cmd.match(/\\/)) pathEnv = [""];
		return {
			env: pathEnv,
			ext: pathExt,
			extExe: pathExtExe
		};
	}
	function which(cmd, opt, cb) {
		if (typeof opt === "function") {
			cb = opt;
			opt = {};
		}
		var info = getPathInfo(cmd, opt);
		var pathEnv = info.env;
		var pathExt = info.ext;
		var pathExtExe = info.extExe;
		var found = [];
		(function F(i, l) {
			if (i === l) if (opt.all && found.length) return cb(null, found);
			else return cb(getNotFoundError(cmd));
			var pathPart = pathEnv[i];
			if (pathPart.charAt(0) === "\"" && pathPart.slice(-1) === "\"") pathPart = pathPart.slice(1, -1);
			var p = path$9.join(pathPart, cmd);
			if (!pathPart && /^\.[\\\/]/.test(cmd)) p = cmd.slice(0, 2) + p;
			(function E(ii, ll) {
				if (ii === ll) return F(i + 1, l);
				var ext = pathExt[ii];
				isexe(p + ext, { pathExt: pathExtExe }, function(er, is) {
					if (!er && is) if (opt.all) found.push(p + ext);
					else return cb(null, p + ext);
					return E(ii + 1, ll);
				});
			})(0, pathExt.length);
		})(0, pathEnv.length);
	}
	function whichSync(cmd, opt) {
		opt = opt || {};
		var info = getPathInfo(cmd, opt);
		var pathEnv = info.env;
		var pathExt = info.ext;
		var pathExtExe = info.extExe;
		var found = [];
		for (var i = 0, l = pathEnv.length; i < l; i++) {
			var pathPart = pathEnv[i];
			if (pathPart.charAt(0) === "\"" && pathPart.slice(-1) === "\"") pathPart = pathPart.slice(1, -1);
			var p = path$9.join(pathPart, cmd);
			if (!pathPart && /^\.[\\\/]/.test(cmd)) p = cmd.slice(0, 2) + p;
			for (var j = 0, ll = pathExt.length; j < ll; j++) {
				var cur = p + pathExt[j];
				var is;
				try {
					is = isexe.sync(cur, { pathExt: pathExtExe });
					if (is) if (opt.all) found.push(cur);
					else return cur;
				} catch (ex) {}
			}
		}
		if (opt.all && found.length) return found;
		if (opt.nothrow) return null;
		throw getNotFoundError(cmd);
	}
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/utils.js
var require_utils$2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	__require("child_process").exec;
	var isWindows = __require("os").platform().match(/win(32|64)/);
	var which = require_which();
	var nlRegexp = /\r\n|\r|\n/g;
	var streamRegexp = /^\[?(.*?)\]?$/;
	var filterEscapeRegexp = /[,]/;
	var whichCache = {};
	/**
	* Parse progress line from ffmpeg stderr
	*
	* @param {String} line progress line
	* @return progress object
	* @private
	*/
	function parseProgressLine(line) {
		var progress = {};
		line = line.replace(/=\s+/g, "=").trim();
		var progressParts = line.split(" ");
		for (var i = 0; i < progressParts.length; i++) {
			var progressSplit = progressParts[i].split("=", 2);
			var key = progressSplit[0];
			var value = progressSplit[1];
			if (typeof value === "undefined") return null;
			progress[key] = value;
		}
		return progress;
	}
	var utils = module.exports = {
		isWindows,
		streamRegexp,
		/**
		* Copy an object keys into another one
		*
		* @param {Object} source source object
		* @param {Object} dest destination object
		* @private
		*/
		copy: function(source, dest) {
			Object.keys(source).forEach(function(key) {
				dest[key] = source[key];
			});
		},
		/**
		* Create an argument list
		*
		* Returns a function that adds new arguments to the list.
		* It also has the following methods:
		* - clear() empties the argument list
		* - get() returns the argument list
		* - find(arg, count) finds 'arg' in the list and return the following 'count' items, or undefined if not found
		* - remove(arg, count) remove 'arg' in the list as well as the following 'count' items
		*
		* @private
		*/
		args: function() {
			var list = [];
			var argfunc = function() {
				if (arguments.length === 1 && Array.isArray(arguments[0])) list = list.concat(arguments[0]);
				else list = list.concat([].slice.call(arguments));
			};
			argfunc.clear = function() {
				list = [];
			};
			argfunc.get = function() {
				return list;
			};
			argfunc.find = function(arg, count) {
				var index = list.indexOf(arg);
				if (index !== -1) return list.slice(index + 1, index + 1 + (count || 0));
			};
			argfunc.remove = function(arg, count) {
				var index = list.indexOf(arg);
				if (index !== -1) list.splice(index, (count || 0) + 1);
			};
			argfunc.clone = function() {
				var cloned = utils.args();
				cloned(list);
				return cloned;
			};
			return argfunc;
		},
		/**
		* Generate filter strings
		*
		* @param {String[]|Object[]} filters filter specifications. When using objects,
		*   each must have the following properties:
		* @param {String} filters.filter filter name
		* @param {String|Array} [filters.inputs] (array of) input stream specifier(s) for the filter,
		*   defaults to ffmpeg automatically choosing the first unused matching streams
		* @param {String|Array} [filters.outputs] (array of) output stream specifier(s) for the filter,
		*   defaults to ffmpeg automatically assigning the output to the output file
		* @param {Object|String|Array} [filters.options] filter options, can be omitted to not set any options
		* @return String[]
		* @private
		*/
		makeFilterStrings: function(filters) {
			return filters.map(function(filterSpec) {
				if (typeof filterSpec === "string") return filterSpec;
				var filterString = "";
				if (Array.isArray(filterSpec.inputs)) filterString += filterSpec.inputs.map(function(streamSpec) {
					return streamSpec.replace(streamRegexp, "[$1]");
				}).join("");
				else if (typeof filterSpec.inputs === "string") filterString += filterSpec.inputs.replace(streamRegexp, "[$1]");
				filterString += filterSpec.filter;
				if (filterSpec.options) {
					if (typeof filterSpec.options === "string" || typeof filterSpec.options === "number") filterString += "=" + filterSpec.options;
					else if (Array.isArray(filterSpec.options)) filterString += "=" + filterSpec.options.map(function(option) {
						if (typeof option === "string" && option.match(filterEscapeRegexp)) return "'" + option + "'";
						else return option;
					}).join(":");
					else if (Object.keys(filterSpec.options).length) filterString += "=" + Object.keys(filterSpec.options).map(function(option) {
						var value = filterSpec.options[option];
						if (typeof value === "string" && value.match(filterEscapeRegexp)) value = "'" + value + "'";
						return option + "=" + value;
					}).join(":");
				}
				if (Array.isArray(filterSpec.outputs)) filterString += filterSpec.outputs.map(function(streamSpec) {
					return streamSpec.replace(streamRegexp, "[$1]");
				}).join("");
				else if (typeof filterSpec.outputs === "string") filterString += filterSpec.outputs.replace(streamRegexp, "[$1]");
				return filterString;
			});
		},
		/**
		* Search for an executable
		*
		* Uses 'which' or 'where' depending on platform
		*
		* @param {String} name executable name
		* @param {Function} callback callback with signature (err, path)
		* @private
		*/
		which: function(name, callback) {
			if (name in whichCache) return callback(null, whichCache[name]);
			which(name, function(err, result) {
				if (err) return callback(null, whichCache[name] = "");
				callback(null, whichCache[name] = result);
			});
		},
		/**
		* Convert a [[hh:]mm:]ss[.xxx] timemark into seconds
		*
		* @param {String} timemark timemark string
		* @return Number
		* @private
		*/
		timemarkToSeconds: function(timemark) {
			if (typeof timemark === "number") return timemark;
			if (timemark.indexOf(":") === -1 && timemark.indexOf(".") >= 0) return Number(timemark);
			var parts = timemark.split(":");
			var secs = Number(parts.pop());
			if (parts.length) secs += Number(parts.pop()) * 60;
			if (parts.length) secs += Number(parts.pop()) * 3600;
			return secs;
		},
		/**
		* Extract codec data from ffmpeg stderr and emit 'codecData' event if appropriate
		* Call it with an initially empty codec object once with each line of stderr output until it returns true
		*
		* @param {FfmpegCommand} command event emitter
		* @param {String} stderrLine ffmpeg stderr output line
		* @param {Object} codecObject object used to accumulate codec data between calls
		* @return {Boolean} true if codec data is complete (and event was emitted), false otherwise
		* @private
		*/
		extractCodecData: function(command, stderrLine, codecsObject) {
			var inputPattern = /Input #[0-9]+, ([^ ]+),/;
			var durPattern = /Duration\: ([^,]+)/;
			var audioPattern = /Audio\: (.*)/;
			var videoPattern = /Video\: (.*)/;
			if (!("inputStack" in codecsObject)) {
				codecsObject.inputStack = [];
				codecsObject.inputIndex = -1;
				codecsObject.inInput = false;
			}
			var inputStack = codecsObject.inputStack;
			var inputIndex = codecsObject.inputIndex;
			var inInput = codecsObject.inInput;
			var format, dur, audio, video;
			if (format = stderrLine.match(inputPattern)) {
				inInput = codecsObject.inInput = true;
				inputIndex = codecsObject.inputIndex = codecsObject.inputIndex + 1;
				inputStack[inputIndex] = {
					format: format[1],
					audio: "",
					video: "",
					duration: ""
				};
			} else if (inInput && (dur = stderrLine.match(durPattern))) inputStack[inputIndex].duration = dur[1];
			else if (inInput && (audio = stderrLine.match(audioPattern))) {
				audio = audio[1].split(", ");
				inputStack[inputIndex].audio = audio[0];
				inputStack[inputIndex].audio_details = audio;
			} else if (inInput && (video = stderrLine.match(videoPattern))) {
				video = video[1].split(", ");
				inputStack[inputIndex].video = video[0];
				inputStack[inputIndex].video_details = video;
			} else if (/Output #\d+/.test(stderrLine)) inInput = codecsObject.inInput = false;
			else if (/Stream mapping:|Press (\[q\]|ctrl-c) to stop/.test(stderrLine)) {
				command.emit.apply(command, ["codecData"].concat(inputStack));
				return true;
			}
			return false;
		},
		/**
		* Extract progress data from ffmpeg stderr and emit 'progress' event if appropriate
		*
		* @param {FfmpegCommand} command event emitter
		* @param {String} stderrLine ffmpeg stderr data
		* @private
		*/
		extractProgress: function(command, stderrLine) {
			var progress = parseProgressLine(stderrLine);
			if (progress) {
				var ret = {
					frames: parseInt(progress.frame, 10),
					currentFps: parseInt(progress.fps, 10),
					currentKbps: progress.bitrate ? parseFloat(progress.bitrate.replace("kbits/s", "")) : 0,
					targetSize: parseInt(progress.size || progress.Lsize, 10),
					timemark: progress.time
				};
				if (command._ffprobeData && command._ffprobeData.format && command._ffprobeData.format.duration) {
					var duration = Number(command._ffprobeData.format.duration);
					if (!isNaN(duration)) ret.percent = utils.timemarkToSeconds(ret.timemark) / duration * 100;
				}
				command.emit("progress", ret);
			}
		},
		/**
		* Extract error message(s) from ffmpeg stderr
		*
		* @param {String} stderr ffmpeg stderr data
		* @return {String}
		* @private
		*/
		extractError: function(stderr) {
			return stderr.split(nlRegexp).reduce(function(messages, message) {
				if (message.charAt(0) === " " || message.charAt(0) === "[") return [];
				else {
					messages.push(message);
					return messages;
				}
			}, []).join("\n");
		},
		/**
		* Creates a line ring buffer object with the following methods:
		* - append(str) : appends a string or buffer
		* - get() : returns the whole string
		* - close() : prevents further append() calls and does a last call to callbacks
		* - callback(cb) : calls cb for each line (incl. those already in the ring)
		*
		* @param {Number} maxLines maximum number of lines to store (<= 0 for unlimited)
		*/
		linesRing: function(maxLines) {
			var cbs = [];
			var lines = [];
			var current = null;
			var closed = false;
			var max = maxLines - 1;
			function emit(line) {
				cbs.forEach(function(cb) {
					cb(line);
				});
			}
			return {
				callback: function(cb) {
					lines.forEach(function(l) {
						cb(l);
					});
					cbs.push(cb);
				},
				append: function(str) {
					if (closed) return;
					if (str instanceof Buffer) str = "" + str;
					if (!str || str.length === 0) return;
					var newLines = str.split(nlRegexp);
					if (newLines.length === 1) if (current !== null) current = current + newLines.shift();
					else current = newLines.shift();
					else {
						if (current !== null) {
							current = current + newLines.shift();
							emit(current);
							lines.push(current);
						}
						current = newLines.pop();
						newLines.forEach(function(l) {
							emit(l);
							lines.push(l);
						});
						if (max > -1 && lines.length > max) lines.splice(0, lines.length - max);
					}
				},
				get: function() {
					if (current !== null) return lines.concat([current]).join("\n");
					else return lines.join("\n");
				},
				close: function() {
					if (closed) return;
					if (current !== null) {
						emit(current);
						lines.push(current);
						if (max > -1 && lines.length > max) lines.shift();
						current = null;
					}
					closed = true;
				}
			};
		}
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/inputs.js
var require_inputs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var utils = require_utils$2();
	module.exports = function(proto) {
		/**
		* Add an input to command
		*
		* Also switches "current input", that is the input that will be affected
		* by subsequent input-related methods.
		*
		* Note: only one stream input is supported for now.
		*
		* @method FfmpegCommand#input
		* @category Input
		* @aliases mergeAdd,addInput
		*
		* @param {String|Readable} source input file path or readable stream
		* @return FfmpegCommand
		*/
		proto.mergeAdd = proto.addInput = proto.input = function(source) {
			var isFile = false;
			var isStream = false;
			if (typeof source !== "string") {
				if (!("readable" in source) || !source.readable) throw new Error("Invalid input");
				if (this._inputs.some(function(input) {
					return input.isStream;
				})) throw new Error("Only one input stream is supported");
				isStream = true;
				source.pause();
			} else {
				var protocol = source.match(/^([a-z]{2,}):/i);
				isFile = !protocol || protocol[0] === "file";
			}
			this._inputs.push(this._currentInput = {
				source,
				isFile,
				isStream,
				options: utils.args()
			});
			return this;
		};
		/**
		* Specify input format for the last specified input
		*
		* @method FfmpegCommand#inputFormat
		* @category Input
		* @aliases withInputFormat,fromFormat
		*
		* @param {String} format input format
		* @return FfmpegCommand
		*/
		proto.withInputFormat = proto.inputFormat = proto.fromFormat = function(format) {
			if (!this._currentInput) throw new Error("No input specified");
			this._currentInput.options("-f", format);
			return this;
		};
		/**
		* Specify input FPS for the last specified input
		* (only valid for raw video formats)
		*
		* @method FfmpegCommand#inputFps
		* @category Input
		* @aliases withInputFps,withInputFPS,withFpsInput,withFPSInput,inputFPS,inputFps,fpsInput
		*
		* @param {Number} fps input FPS
		* @return FfmpegCommand
		*/
		proto.withInputFps = proto.withInputFPS = proto.withFpsInput = proto.withFPSInput = proto.inputFPS = proto.inputFps = proto.fpsInput = proto.FPSInput = function(fps) {
			if (!this._currentInput) throw new Error("No input specified");
			this._currentInput.options("-r", fps);
			return this;
		};
		/**
		* Use native framerate for the last specified input
		*
		* @method FfmpegCommand#native
		* @category Input
		* @aliases nativeFramerate,withNativeFramerate
		*
		* @return FfmmegCommand
		*/
		proto.nativeFramerate = proto.withNativeFramerate = proto.native = function() {
			if (!this._currentInput) throw new Error("No input specified");
			this._currentInput.options("-re");
			return this;
		};
		/**
		* Specify input seek time for the last specified input
		*
		* @method FfmpegCommand#seekInput
		* @category Input
		* @aliases setStartTime,seekTo
		*
		* @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
		* @return FfmpegCommand
		*/
		proto.setStartTime = proto.seekInput = function(seek) {
			if (!this._currentInput) throw new Error("No input specified");
			this._currentInput.options("-ss", seek);
			return this;
		};
		/**
		* Loop over the last specified input
		*
		* @method FfmpegCommand#loop
		* @category Input
		*
		* @param {String|Number} [duration] loop duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
		* @return FfmpegCommand
		*/
		proto.loop = function(duration) {
			if (!this._currentInput) throw new Error("No input specified");
			this._currentInput.options("-loop", "1");
			if (typeof duration !== "undefined") this.duration(duration);
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/audio.js
var require_audio = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var utils = require_utils$2();
	module.exports = function(proto) {
		/**
		* Disable audio in the output
		*
		* @method FfmpegCommand#noAudio
		* @category Audio
		* @aliases withNoAudio
		* @return FfmpegCommand
		*/
		proto.withNoAudio = proto.noAudio = function() {
			this._currentOutput.audio.clear();
			this._currentOutput.audioFilters.clear();
			this._currentOutput.audio("-an");
			return this;
		};
		/**
		* Specify audio codec
		*
		* @method FfmpegCommand#audioCodec
		* @category Audio
		* @aliases withAudioCodec
		*
		* @param {String} codec audio codec name
		* @return FfmpegCommand
		*/
		proto.withAudioCodec = proto.audioCodec = function(codec) {
			this._currentOutput.audio("-acodec", codec);
			return this;
		};
		/**
		* Specify audio bitrate
		*
		* @method FfmpegCommand#audioBitrate
		* @category Audio
		* @aliases withAudioBitrate
		*
		* @param {String|Number} bitrate audio bitrate in kbps (with an optional 'k' suffix)
		* @return FfmpegCommand
		*/
		proto.withAudioBitrate = proto.audioBitrate = function(bitrate) {
			this._currentOutput.audio("-b:a", ("" + bitrate).replace(/k?$/, "k"));
			return this;
		};
		/**
		* Specify audio channel count
		*
		* @method FfmpegCommand#audioChannels
		* @category Audio
		* @aliases withAudioChannels
		*
		* @param {Number} channels channel count
		* @return FfmpegCommand
		*/
		proto.withAudioChannels = proto.audioChannels = function(channels) {
			this._currentOutput.audio("-ac", channels);
			return this;
		};
		/**
		* Specify audio frequency
		*
		* @method FfmpegCommand#audioFrequency
		* @category Audio
		* @aliases withAudioFrequency
		*
		* @param {Number} freq audio frequency in Hz
		* @return FfmpegCommand
		*/
		proto.withAudioFrequency = proto.audioFrequency = function(freq) {
			this._currentOutput.audio("-ar", freq);
			return this;
		};
		/**
		* Specify audio quality
		*
		* @method FfmpegCommand#audioQuality
		* @category Audio
		* @aliases withAudioQuality
		*
		* @param {Number} quality audio quality factor
		* @return FfmpegCommand
		*/
		proto.withAudioQuality = proto.audioQuality = function(quality) {
			this._currentOutput.audio("-aq", quality);
			return this;
		};
		/**
		* Specify custom audio filter(s)
		*
		* Can be called both with one or many filters, or a filter array.
		*
		* @example
		* command.audioFilters('filter1');
		*
		* @example
		* command.audioFilters('filter1', 'filter2=param1=value1:param2=value2');
		*
		* @example
		* command.audioFilters(['filter1', 'filter2']);
		*
		* @example
		* command.audioFilters([
		*   {
		*     filter: 'filter1'
		*   },
		*   {
		*     filter: 'filter2',
		*     options: 'param=value:param=value'
		*   }
		* ]);
		*
		* @example
		* command.audioFilters(
		*   {
		*     filter: 'filter1',
		*     options: ['value1', 'value2']
		*   },
		*   {
		*     filter: 'filter2',
		*     options: { param1: 'value1', param2: 'value2' }
		*   }
		* );
		*
		* @method FfmpegCommand#audioFilters
		* @aliases withAudioFilter,withAudioFilters,audioFilter
		* @category Audio
		*
		* @param {...String|String[]|Object[]} filters audio filter strings, string array or
		*   filter specification array, each with the following properties:
		* @param {String} filters.filter filter name
		* @param {String|String[]|Object} [filters.options] filter option string, array, or object
		* @return FfmpegCommand
		*/
		proto.withAudioFilter = proto.withAudioFilters = proto.audioFilter = proto.audioFilters = function(filters) {
			if (arguments.length > 1) filters = [].slice.call(arguments);
			if (!Array.isArray(filters)) filters = [filters];
			this._currentOutput.audioFilters(utils.makeFilterStrings(filters));
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/video.js
var require_video = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var utils = require_utils$2();
	module.exports = function(proto) {
		/**
		* Disable video in the output
		*
		* @method FfmpegCommand#noVideo
		* @category Video
		* @aliases withNoVideo
		*
		* @return FfmpegCommand
		*/
		proto.withNoVideo = proto.noVideo = function() {
			this._currentOutput.video.clear();
			this._currentOutput.videoFilters.clear();
			this._currentOutput.video("-vn");
			return this;
		};
		/**
		* Specify video codec
		*
		* @method FfmpegCommand#videoCodec
		* @category Video
		* @aliases withVideoCodec
		*
		* @param {String} codec video codec name
		* @return FfmpegCommand
		*/
		proto.withVideoCodec = proto.videoCodec = function(codec) {
			this._currentOutput.video("-vcodec", codec);
			return this;
		};
		/**
		* Specify video bitrate
		*
		* @method FfmpegCommand#videoBitrate
		* @category Video
		* @aliases withVideoBitrate
		*
		* @param {String|Number} bitrate video bitrate in kbps (with an optional 'k' suffix)
		* @param {Boolean} [constant=false] enforce constant bitrate
		* @return FfmpegCommand
		*/
		proto.withVideoBitrate = proto.videoBitrate = function(bitrate, constant) {
			bitrate = ("" + bitrate).replace(/k?$/, "k");
			this._currentOutput.video("-b:v", bitrate);
			if (constant) this._currentOutput.video("-maxrate", bitrate, "-minrate", bitrate, "-bufsize", "3M");
			return this;
		};
		/**
		* Specify custom video filter(s)
		*
		* Can be called both with one or many filters, or a filter array.
		*
		* @example
		* command.videoFilters('filter1');
		*
		* @example
		* command.videoFilters('filter1', 'filter2=param1=value1:param2=value2');
		*
		* @example
		* command.videoFilters(['filter1', 'filter2']);
		*
		* @example
		* command.videoFilters([
		*   {
		*     filter: 'filter1'
		*   },
		*   {
		*     filter: 'filter2',
		*     options: 'param=value:param=value'
		*   }
		* ]);
		*
		* @example
		* command.videoFilters(
		*   {
		*     filter: 'filter1',
		*     options: ['value1', 'value2']
		*   },
		*   {
		*     filter: 'filter2',
		*     options: { param1: 'value1', param2: 'value2' }
		*   }
		* );
		*
		* @method FfmpegCommand#videoFilters
		* @category Video
		* @aliases withVideoFilter,withVideoFilters,videoFilter
		*
		* @param {...String|String[]|Object[]} filters video filter strings, string array or
		*   filter specification array, each with the following properties:
		* @param {String} filters.filter filter name
		* @param {String|String[]|Object} [filters.options] filter option string, array, or object
		* @return FfmpegCommand
		*/
		proto.withVideoFilter = proto.withVideoFilters = proto.videoFilter = proto.videoFilters = function(filters) {
			if (arguments.length > 1) filters = [].slice.call(arguments);
			if (!Array.isArray(filters)) filters = [filters];
			this._currentOutput.videoFilters(utils.makeFilterStrings(filters));
			return this;
		};
		/**
		* Specify output FPS
		*
		* @method FfmpegCommand#fps
		* @category Video
		* @aliases withOutputFps,withOutputFPS,withFpsOutput,withFPSOutput,withFps,withFPS,outputFPS,outputFps,fpsOutput,FPSOutput,FPS
		*
		* @param {Number} fps output FPS
		* @return FfmpegCommand
		*/
		proto.withOutputFps = proto.withOutputFPS = proto.withFpsOutput = proto.withFPSOutput = proto.withFps = proto.withFPS = proto.outputFPS = proto.outputFps = proto.fpsOutput = proto.FPSOutput = proto.fps = proto.FPS = function(fps) {
			this._currentOutput.video("-r", fps);
			return this;
		};
		/**
		* Only transcode a certain number of frames
		*
		* @method FfmpegCommand#frames
		* @category Video
		* @aliases takeFrames,withFrames
		*
		* @param {Number} frames frame count
		* @return FfmpegCommand
		*/
		proto.takeFrames = proto.withFrames = proto.frames = function(frames) {
			this._currentOutput.video("-vframes", frames);
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/videosize.js
var require_videosize = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/**
	* Return filters to pad video to width*height,
	*
	* @param {Number} width output width
	* @param {Number} height output height
	* @param {Number} aspect video aspect ratio (without padding)
	* @param {Number} color padding color
	* @return scale/pad filters
	* @private
	*/
	function getScalePadFilters(width, height, aspect, color) {
		return [{
			filter: "scale",
			options: {
				w: "if(gt(a," + aspect + ")," + width + ",trunc(" + height + "*a/2)*2)",
				h: "if(lt(a," + aspect + ")," + height + ",trunc(" + width + "/a/2)*2)"
			}
		}, {
			filter: "pad",
			options: {
				w: width,
				h: height,
				x: "if(gt(a," + aspect + "),0,(" + width + "-iw)/2)",
				y: "if(lt(a," + aspect + "),0,(" + height + "-ih)/2)",
				color
			}
		}];
	}
	/**
	* Recompute size filters
	*
	* @param {Object} output
	* @param {String} key newly-added parameter name ('size', 'aspect' or 'pad')
	* @param {String} value newly-added parameter value
	* @return filter string array
	* @private
	*/
	function createSizeFilters(output, key, value) {
		var data = output.sizeData = output.sizeData || {};
		data[key] = value;
		if (!("size" in data)) return [];
		var fixedSize = data.size.match(/([0-9]+)x([0-9]+)/);
		var fixedWidth = data.size.match(/([0-9]+)x\?/);
		var fixedHeight = data.size.match(/\?x([0-9]+)/);
		var percentRatio = data.size.match(/\b([0-9]{1,3})%/);
		var width, height, aspect;
		if (percentRatio) {
			var ratio = Number(percentRatio[1]) / 100;
			return [{
				filter: "scale",
				options: {
					w: "trunc(iw*" + ratio + "/2)*2",
					h: "trunc(ih*" + ratio + "/2)*2"
				}
			}];
		} else if (fixedSize) {
			width = Math.round(Number(fixedSize[1]) / 2) * 2;
			height = Math.round(Number(fixedSize[2]) / 2) * 2;
			aspect = width / height;
			if (data.pad) return getScalePadFilters(width, height, aspect, data.pad);
			else return [{
				filter: "scale",
				options: {
					w: width,
					h: height
				}
			}];
		} else if (fixedWidth || fixedHeight) if ("aspect" in data) {
			width = fixedWidth ? fixedWidth[1] : Math.round(Number(fixedHeight[1]) * data.aspect);
			height = fixedHeight ? fixedHeight[1] : Math.round(Number(fixedWidth[1]) / data.aspect);
			width = Math.round(width / 2) * 2;
			height = Math.round(height / 2) * 2;
			if (data.pad) return getScalePadFilters(width, height, data.aspect, data.pad);
			else return [{
				filter: "scale",
				options: {
					w: width,
					h: height
				}
			}];
		} else if (fixedWidth) return [{
			filter: "scale",
			options: {
				w: Math.round(Number(fixedWidth[1]) / 2) * 2,
				h: "trunc(ow/a/2)*2"
			}
		}];
		else return [{
			filter: "scale",
			options: {
				w: "trunc(oh*a/2)*2",
				h: Math.round(Number(fixedHeight[1]) / 2) * 2
			}
		}];
		else throw new Error("Invalid size specified: " + data.size);
	}
	module.exports = function(proto) {
		/**
		* Keep display aspect ratio
		*
		* This method is useful when converting an input with non-square pixels to an output format
		* that does not support non-square pixels.  It rescales the input so that the display aspect
		* ratio is the same.
		*
		* @method FfmpegCommand#keepDAR
		* @category Video size
		* @aliases keepPixelAspect,keepDisplayAspect,keepDisplayAspectRatio
		*
		* @return FfmpegCommand
		*/
		proto.keepPixelAspect = proto.keepDisplayAspect = proto.keepDisplayAspectRatio = proto.keepDAR = function() {
			return this.videoFilters([{
				filter: "scale",
				options: {
					w: "if(gt(sar,1),iw*sar,iw)",
					h: "if(lt(sar,1),ih/sar,ih)"
				}
			}, {
				filter: "setsar",
				options: "1"
			}]);
		};
		/**
		* Set output size
		*
		* The 'size' parameter can have one of 4 forms:
		* - 'X%': rescale to xx % of the original size
		* - 'WxH': specify width and height
		* - 'Wx?': specify width and compute height from input aspect ratio
		* - '?xH': specify height and compute width from input aspect ratio
		*
		* Note: both dimensions will be truncated to multiples of 2.
		*
		* @method FfmpegCommand#size
		* @category Video size
		* @aliases withSize,setSize
		*
		* @param {String} size size string, eg. '33%', '320x240', '320x?', '?x240'
		* @return FfmpegCommand
		*/
		proto.withSize = proto.setSize = proto.size = function(size) {
			var filters = createSizeFilters(this._currentOutput, "size", size);
			this._currentOutput.sizeFilters.clear();
			this._currentOutput.sizeFilters(filters);
			return this;
		};
		/**
		* Set output aspect ratio
		*
		* @method FfmpegCommand#aspect
		* @category Video size
		* @aliases withAspect,withAspectRatio,setAspect,setAspectRatio,aspectRatio
		*
		* @param {String|Number} aspect aspect ratio (number or 'X:Y' string)
		* @return FfmpegCommand
		*/
		proto.withAspect = proto.withAspectRatio = proto.setAspect = proto.setAspectRatio = proto.aspect = proto.aspectRatio = function(aspect) {
			var a = Number(aspect);
			if (isNaN(a)) {
				var match = aspect.match(/^(\d+):(\d+)$/);
				if (match) a = Number(match[1]) / Number(match[2]);
				else throw new Error("Invalid aspect ratio: " + aspect);
			}
			var filters = createSizeFilters(this._currentOutput, "aspect", a);
			this._currentOutput.sizeFilters.clear();
			this._currentOutput.sizeFilters(filters);
			return this;
		};
		/**
		* Enable auto-padding the output
		*
		* @method FfmpegCommand#autopad
		* @category Video size
		* @aliases applyAutopadding,applyAutoPadding,applyAutopad,applyAutoPad,withAutopadding,withAutoPadding,withAutopad,withAutoPad,autoPad
		*
		* @param {Boolean} [pad=true] enable/disable auto-padding
		* @param {String} [color='black'] pad color
		*/
		proto.applyAutopadding = proto.applyAutoPadding = proto.applyAutopad = proto.applyAutoPad = proto.withAutopadding = proto.withAutoPadding = proto.withAutopad = proto.withAutoPad = proto.autoPad = proto.autopad = function(pad, color) {
			if (typeof pad === "string") {
				color = pad;
				pad = true;
			}
			if (typeof pad === "undefined") pad = true;
			var filters = createSizeFilters(this._currentOutput, "pad", pad ? color || "black" : false);
			this._currentOutput.sizeFilters.clear();
			this._currentOutput.sizeFilters(filters);
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/output.js
var require_output = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var utils = require_utils$2();
	module.exports = function(proto) {
		/**
		* Add output
		*
		* @method FfmpegCommand#output
		* @category Output
		* @aliases addOutput
		*
		* @param {String|Writable} target target file path or writable stream
		* @param {Object} [pipeopts={}] pipe options (only applies to streams)
		* @return FfmpegCommand
		*/
		proto.addOutput = proto.output = function(target, pipeopts) {
			var isFile = false;
			if (!target && this._currentOutput) throw new Error("Invalid output");
			if (target && typeof target !== "string") {
				if (!("writable" in target) || !target.writable) throw new Error("Invalid output");
			} else if (typeof target === "string") {
				var protocol = target.match(/^([a-z]{2,}):/i);
				isFile = !protocol || protocol[0] === "file";
			}
			if (target && !("target" in this._currentOutput)) {
				this._currentOutput.target = target;
				this._currentOutput.isFile = isFile;
				this._currentOutput.pipeopts = pipeopts || {};
			} else {
				if (target && typeof target !== "string") {
					if (this._outputs.some(function(output) {
						return typeof output.target !== "string";
					})) throw new Error("Only one output stream is supported");
				}
				this._outputs.push(this._currentOutput = {
					target,
					isFile,
					flags: {},
					pipeopts: pipeopts || {}
				});
				var self = this;
				[
					"audio",
					"audioFilters",
					"video",
					"videoFilters",
					"sizeFilters",
					"options"
				].forEach(function(key) {
					self._currentOutput[key] = utils.args();
				});
				if (!target) delete this._currentOutput.target;
			}
			return this;
		};
		/**
		* Specify output seek time
		*
		* @method FfmpegCommand#seek
		* @category Input
		* @aliases seekOutput
		*
		* @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
		* @return FfmpegCommand
		*/
		proto.seekOutput = proto.seek = function(seek) {
			this._currentOutput.options("-ss", seek);
			return this;
		};
		/**
		* Set output duration
		*
		* @method FfmpegCommand#duration
		* @category Output
		* @aliases withDuration,setDuration
		*
		* @param {String|Number} duration duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
		* @return FfmpegCommand
		*/
		proto.withDuration = proto.setDuration = proto.duration = function(duration) {
			this._currentOutput.options("-t", duration);
			return this;
		};
		/**
		* Set output format
		*
		* @method FfmpegCommand#format
		* @category Output
		* @aliases toFormat,withOutputFormat,outputFormat
		*
		* @param {String} format output format name
		* @return FfmpegCommand
		*/
		proto.toFormat = proto.withOutputFormat = proto.outputFormat = proto.format = function(format) {
			this._currentOutput.options("-f", format);
			return this;
		};
		/**
		* Add stream mapping to output
		*
		* @method FfmpegCommand#map
		* @category Output
		*
		* @param {String} spec stream specification string, with optional square brackets
		* @return FfmpegCommand
		*/
		proto.map = function(spec) {
			this._currentOutput.options("-map", spec.replace(utils.streamRegexp, "[$1]"));
			return this;
		};
		/**
		* Run flvtool2/flvmeta on output
		*
		* @method FfmpegCommand#flvmeta
		* @category Output
		* @aliases updateFlvMetadata
		*
		* @return FfmpegCommand
		*/
		proto.updateFlvMetadata = proto.flvmeta = function() {
			this._currentOutput.flags.flvmeta = true;
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/custom.js
var require_custom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var utils = require_utils$2();
	module.exports = function(proto) {
		/**
		* Add custom input option(s)
		*
		* When passing a single string or an array, each string containing two
		* words is split (eg. inputOptions('-option value') is supported) for
		* compatibility reasons.  This is not the case when passing more than
		* one argument.
		*
		* @example
		* command.inputOptions('option1');
		*
		* @example
		* command.inputOptions('option1', 'option2');
		*
		* @example
		* command.inputOptions(['option1', 'option2']);
		*
		* @method FfmpegCommand#inputOptions
		* @category Custom options
		* @aliases addInputOption,addInputOptions,withInputOption,withInputOptions,inputOption
		*
		* @param {...String} options option string(s) or string array
		* @return FfmpegCommand
		*/
		proto.addInputOption = proto.addInputOptions = proto.withInputOption = proto.withInputOptions = proto.inputOption = proto.inputOptions = function(options) {
			if (!this._currentInput) throw new Error("No input specified");
			var doSplit = true;
			if (arguments.length > 1) {
				options = [].slice.call(arguments);
				doSplit = false;
			}
			if (!Array.isArray(options)) options = [options];
			this._currentInput.options(options.reduce(function(options, option) {
				var split = String(option).split(" ");
				if (doSplit && split.length === 2) options.push(split[0], split[1]);
				else options.push(option);
				return options;
			}, []));
			return this;
		};
		/**
		* Add custom output option(s)
		*
		* @example
		* command.outputOptions('option1');
		*
		* @example
		* command.outputOptions('option1', 'option2');
		*
		* @example
		* command.outputOptions(['option1', 'option2']);
		*
		* @method FfmpegCommand#outputOptions
		* @category Custom options
		* @aliases addOutputOption,addOutputOptions,addOption,addOptions,withOutputOption,withOutputOptions,withOption,withOptions,outputOption
		*
		* @param {...String} options option string(s) or string array
		* @return FfmpegCommand
		*/
		proto.addOutputOption = proto.addOutputOptions = proto.addOption = proto.addOptions = proto.withOutputOption = proto.withOutputOptions = proto.withOption = proto.withOptions = proto.outputOption = proto.outputOptions = function(options) {
			var doSplit = true;
			if (arguments.length > 1) {
				options = [].slice.call(arguments);
				doSplit = false;
			}
			if (!Array.isArray(options)) options = [options];
			this._currentOutput.options(options.reduce(function(options, option) {
				var split = String(option).split(" ");
				if (doSplit && split.length === 2) options.push(split[0], split[1]);
				else options.push(option);
				return options;
			}, []));
			return this;
		};
		/**
		* Specify a complex filtergraph
		*
		* Calling this method will override any previously set filtergraph, but you can set
		* as many filters as needed in one call.
		*
		* @example <caption>Overlay an image over a video (using a filtergraph string)</caption>
		*   ffmpeg()
		*     .input('video.avi')
		*     .input('image.png')
		*     .complexFilter('[0:v][1:v]overlay[out]', ['out']);
		*
		* @example <caption>Overlay an image over a video (using a filter array)</caption>
		*   ffmpeg()
		*     .input('video.avi')
		*     .input('image.png')
		*     .complexFilter([{
		*       filter: 'overlay',
		*       inputs: ['0:v', '1:v'],
		*       outputs: ['out']
		*     }], ['out']);
		*
		* @example <caption>Split video into RGB channels and output a 3x1 video with channels side to side</caption>
		*  ffmpeg()
		*    .input('video.avi')
		*    .complexFilter([
		*      // Duplicate video stream 3 times into streams a, b, and c
		*      { filter: 'split', options: '3', outputs: ['a', 'b', 'c'] },
		*
		*      // Create stream 'red' by cancelling green and blue channels from stream 'a'
		*      { filter: 'lutrgb', options: { g: 0, b: 0 }, inputs: 'a', outputs: 'red' },
		*
		*      // Create stream 'green' by cancelling red and blue channels from stream 'b'
		*      { filter: 'lutrgb', options: { r: 0, b: 0 }, inputs: 'b', outputs: 'green' },
		*
		*      // Create stream 'blue' by cancelling red and green channels from stream 'c'
		*      { filter: 'lutrgb', options: { r: 0, g: 0 }, inputs: 'c', outputs: 'blue' },
		*
		*      // Pad stream 'red' to 3x width, keeping the video on the left, and name output 'padded'
		*      { filter: 'pad', options: { w: 'iw*3', h: 'ih' }, inputs: 'red', outputs: 'padded' },
		*
		*      // Overlay 'green' onto 'padded', moving it to the center, and name output 'redgreen'
		*      { filter: 'overlay', options: { x: 'w', y: 0 }, inputs: ['padded', 'green'], outputs: 'redgreen'},
		*
		*      // Overlay 'blue' onto 'redgreen', moving it to the right
		*      { filter: 'overlay', options: { x: '2*w', y: 0 }, inputs: ['redgreen', 'blue']},
		*    ]);
		*
		* @method FfmpegCommand#complexFilter
		* @category Custom options
		* @aliases filterGraph
		*
		* @param {String|Array} spec filtergraph string or array of filter specification
		*   objects, each having the following properties:
		* @param {String} spec.filter filter name
		* @param {String|Array} [spec.inputs] (array of) input stream specifier(s) for the filter,
		*   defaults to ffmpeg automatically choosing the first unused matching streams
		* @param {String|Array} [spec.outputs] (array of) output stream specifier(s) for the filter,
		*   defaults to ffmpeg automatically assigning the output to the output file
		* @param {Object|String|Array} [spec.options] filter options, can be omitted to not set any options
		* @param {Array} [map] (array of) stream specifier(s) from the graph to include in
		*   ffmpeg output, defaults to ffmpeg automatically choosing the first matching streams.
		* @return FfmpegCommand
		*/
		proto.filterGraph = proto.complexFilter = function(spec, map) {
			this._complexFilters.clear();
			if (!Array.isArray(spec)) spec = [spec];
			this._complexFilters("-filter_complex", utils.makeFilterStrings(spec).join(";"));
			if (Array.isArray(map)) {
				var self = this;
				map.forEach(function(streamSpec) {
					self._complexFilters("-map", streamSpec.replace(utils.streamRegexp, "[$1]"));
				});
			} else if (typeof map === "string") this._complexFilters("-map", map.replace(utils.streamRegexp, "[$1]"));
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/options/misc.js
var require_misc = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var path$8 = __require("path");
	module.exports = function(proto) {
		/**
		* Use preset
		*
		* @method FfmpegCommand#preset
		* @category Miscellaneous
		* @aliases usingPreset
		*
		* @param {String|Function} preset preset name or preset function
		*/
		proto.usingPreset = proto.preset = function(preset) {
			if (typeof preset === "function") preset(this);
			else try {
				var modulePath = path$8.join(this.options.presets, preset);
				var module$7 = __require(modulePath);
				if (typeof module$7.load === "function") module$7.load(this);
				else throw new Error("preset " + modulePath + " has no load() function");
			} catch (err) {
				throw new Error("preset " + modulePath + " could not be loaded: " + err.message);
			}
			return this;
		};
	};
}));
//#endregion
//#region node_modules/async/lib/async.js
var require_async = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	(function() {
		var async = {};
		var root = this, previous_async;
		if (root != null) previous_async = root.async;
		async.noConflict = function() {
			root.async = previous_async;
			return async;
		};
		function only_once(fn) {
			var called = false;
			return function() {
				if (called) throw new Error("Callback was already called.");
				called = true;
				fn.apply(root, arguments);
			};
		}
		var _each = function(arr, iterator) {
			if (arr.forEach) return arr.forEach(iterator);
			for (var i = 0; i < arr.length; i += 1) iterator(arr[i], i, arr);
		};
		var _map = function(arr, iterator) {
			if (arr.map) return arr.map(iterator);
			var results = [];
			_each(arr, function(x, i, a) {
				results.push(iterator(x, i, a));
			});
			return results;
		};
		var _reduce = function(arr, iterator, memo) {
			if (arr.reduce) return arr.reduce(iterator, memo);
			_each(arr, function(x, i, a) {
				memo = iterator(memo, x, i, a);
			});
			return memo;
		};
		var _keys = function(obj) {
			if (Object.keys) return Object.keys(obj);
			var keys = [];
			for (var k in obj) if (obj.hasOwnProperty(k)) keys.push(k);
			return keys;
		};
		if (typeof process === "undefined" || !process.nextTick) if (typeof setImmediate === "function") {
			async.nextTick = function(fn) {
				setImmediate(fn);
			};
			async.setImmediate = async.nextTick;
		} else {
			async.nextTick = function(fn) {
				setTimeout(fn, 0);
			};
			async.setImmediate = async.nextTick;
		}
		else {
			async.nextTick = process.nextTick;
			if (typeof setImmediate !== "undefined") async.setImmediate = function(fn) {
				setImmediate(fn);
			};
			else async.setImmediate = async.nextTick;
		}
		async.each = function(arr, iterator, callback) {
			callback = callback || function() {};
			if (!arr.length) return callback();
			var completed = 0;
			_each(arr, function(x) {
				iterator(x, only_once(function(err) {
					if (err) {
						callback(err);
						callback = function() {};
					} else {
						completed += 1;
						if (completed >= arr.length) callback(null);
					}
				}));
			});
		};
		async.forEach = async.each;
		async.eachSeries = function(arr, iterator, callback) {
			callback = callback || function() {};
			if (!arr.length) return callback();
			var completed = 0;
			var iterate = function() {
				iterator(arr[completed], function(err) {
					if (err) {
						callback(err);
						callback = function() {};
					} else {
						completed += 1;
						if (completed >= arr.length) callback(null);
						else iterate();
					}
				});
			};
			iterate();
		};
		async.forEachSeries = async.eachSeries;
		async.eachLimit = function(arr, limit, iterator, callback) {
			_eachLimit(limit).apply(null, [
				arr,
				iterator,
				callback
			]);
		};
		async.forEachLimit = async.eachLimit;
		var _eachLimit = function(limit) {
			return function(arr, iterator, callback) {
				callback = callback || function() {};
				if (!arr.length || limit <= 0) return callback();
				var completed = 0;
				var started = 0;
				var running = 0;
				(function replenish() {
					if (completed >= arr.length) return callback();
					while (running < limit && started < arr.length) {
						started += 1;
						running += 1;
						iterator(arr[started - 1], function(err) {
							if (err) {
								callback(err);
								callback = function() {};
							} else {
								completed += 1;
								running -= 1;
								if (completed >= arr.length) callback();
								else replenish();
							}
						});
					}
				})();
			};
		};
		var doParallel = function(fn) {
			return function() {
				var args = Array.prototype.slice.call(arguments);
				return fn.apply(null, [async.each].concat(args));
			};
		};
		var doParallelLimit = function(limit, fn) {
			return function() {
				var args = Array.prototype.slice.call(arguments);
				return fn.apply(null, [_eachLimit(limit)].concat(args));
			};
		};
		var doSeries = function(fn) {
			return function() {
				var args = Array.prototype.slice.call(arguments);
				return fn.apply(null, [async.eachSeries].concat(args));
			};
		};
		var _asyncMap = function(eachfn, arr, iterator, callback) {
			var results = [];
			arr = _map(arr, function(x, i) {
				return {
					index: i,
					value: x
				};
			});
			eachfn(arr, function(x, callback) {
				iterator(x.value, function(err, v) {
					results[x.index] = v;
					callback(err);
				});
			}, function(err) {
				callback(err, results);
			});
		};
		async.map = doParallel(_asyncMap);
		async.mapSeries = doSeries(_asyncMap);
		async.mapLimit = function(arr, limit, iterator, callback) {
			return _mapLimit(limit)(arr, iterator, callback);
		};
		var _mapLimit = function(limit) {
			return doParallelLimit(limit, _asyncMap);
		};
		async.reduce = function(arr, memo, iterator, callback) {
			async.eachSeries(arr, function(x, callback) {
				iterator(memo, x, function(err, v) {
					memo = v;
					callback(err);
				});
			}, function(err) {
				callback(err, memo);
			});
		};
		async.inject = async.reduce;
		async.foldl = async.reduce;
		async.reduceRight = function(arr, memo, iterator, callback) {
			var reversed = _map(arr, function(x) {
				return x;
			}).reverse();
			async.reduce(reversed, memo, iterator, callback);
		};
		async.foldr = async.reduceRight;
		var _filter = function(eachfn, arr, iterator, callback) {
			var results = [];
			arr = _map(arr, function(x, i) {
				return {
					index: i,
					value: x
				};
			});
			eachfn(arr, function(x, callback) {
				iterator(x.value, function(v) {
					if (v) results.push(x);
					callback();
				});
			}, function(err) {
				callback(_map(results.sort(function(a, b) {
					return a.index - b.index;
				}), function(x) {
					return x.value;
				}));
			});
		};
		async.filter = doParallel(_filter);
		async.filterSeries = doSeries(_filter);
		async.select = async.filter;
		async.selectSeries = async.filterSeries;
		var _reject = function(eachfn, arr, iterator, callback) {
			var results = [];
			arr = _map(arr, function(x, i) {
				return {
					index: i,
					value: x
				};
			});
			eachfn(arr, function(x, callback) {
				iterator(x.value, function(v) {
					if (!v) results.push(x);
					callback();
				});
			}, function(err) {
				callback(_map(results.sort(function(a, b) {
					return a.index - b.index;
				}), function(x) {
					return x.value;
				}));
			});
		};
		async.reject = doParallel(_reject);
		async.rejectSeries = doSeries(_reject);
		var _detect = function(eachfn, arr, iterator, main_callback) {
			eachfn(arr, function(x, callback) {
				iterator(x, function(result) {
					if (result) {
						main_callback(x);
						main_callback = function() {};
					} else callback();
				});
			}, function(err) {
				main_callback();
			});
		};
		async.detect = doParallel(_detect);
		async.detectSeries = doSeries(_detect);
		async.some = function(arr, iterator, main_callback) {
			async.each(arr, function(x, callback) {
				iterator(x, function(v) {
					if (v) {
						main_callback(true);
						main_callback = function() {};
					}
					callback();
				});
			}, function(err) {
				main_callback(false);
			});
		};
		async.any = async.some;
		async.every = function(arr, iterator, main_callback) {
			async.each(arr, function(x, callback) {
				iterator(x, function(v) {
					if (!v) {
						main_callback(false);
						main_callback = function() {};
					}
					callback();
				});
			}, function(err) {
				main_callback(true);
			});
		};
		async.all = async.every;
		async.sortBy = function(arr, iterator, callback) {
			async.map(arr, function(x, callback) {
				iterator(x, function(err, criteria) {
					if (err) callback(err);
					else callback(null, {
						value: x,
						criteria
					});
				});
			}, function(err, results) {
				if (err) return callback(err);
				else {
					var fn = function(left, right) {
						var a = left.criteria, b = right.criteria;
						return a < b ? -1 : a > b ? 1 : 0;
					};
					callback(null, _map(results.sort(fn), function(x) {
						return x.value;
					}));
				}
			});
		};
		async.auto = function(tasks, callback) {
			callback = callback || function() {};
			var keys = _keys(tasks);
			if (!keys.length) return callback(null);
			var results = {};
			var listeners = [];
			var addListener = function(fn) {
				listeners.unshift(fn);
			};
			var removeListener = function(fn) {
				for (var i = 0; i < listeners.length; i += 1) if (listeners[i] === fn) {
					listeners.splice(i, 1);
					return;
				}
			};
			var taskComplete = function() {
				_each(listeners.slice(0), function(fn) {
					fn();
				});
			};
			addListener(function() {
				if (_keys(results).length === keys.length) {
					callback(null, results);
					callback = function() {};
				}
			});
			_each(keys, function(k) {
				var task = tasks[k] instanceof Function ? [tasks[k]] : tasks[k];
				var taskCallback = function(err) {
					var args = Array.prototype.slice.call(arguments, 1);
					if (args.length <= 1) args = args[0];
					if (err) {
						var safeResults = {};
						_each(_keys(results), function(rkey) {
							safeResults[rkey] = results[rkey];
						});
						safeResults[k] = args;
						callback(err, safeResults);
						callback = function() {};
					} else {
						results[k] = args;
						async.setImmediate(taskComplete);
					}
				};
				var requires = task.slice(0, Math.abs(task.length - 1)) || [];
				var ready = function() {
					return _reduce(requires, function(a, x) {
						return a && results.hasOwnProperty(x);
					}, true) && !results.hasOwnProperty(k);
				};
				if (ready()) task[task.length - 1](taskCallback, results);
				else {
					var listener = function() {
						if (ready()) {
							removeListener(listener);
							task[task.length - 1](taskCallback, results);
						}
					};
					addListener(listener);
				}
			});
		};
		async.waterfall = function(tasks, callback) {
			callback = callback || function() {};
			if (tasks.constructor !== Array) return callback(/* @__PURE__ */ new Error("First argument to waterfall must be an array of functions"));
			if (!tasks.length) return callback();
			var wrapIterator = function(iterator) {
				return function(err) {
					if (err) {
						callback.apply(null, arguments);
						callback = function() {};
					} else {
						var args = Array.prototype.slice.call(arguments, 1);
						var next = iterator.next();
						if (next) args.push(wrapIterator(next));
						else args.push(callback);
						async.setImmediate(function() {
							iterator.apply(null, args);
						});
					}
				};
			};
			wrapIterator(async.iterator(tasks))();
		};
		var _parallel = function(eachfn, tasks, callback) {
			callback = callback || function() {};
			if (tasks.constructor === Array) eachfn.map(tasks, function(fn, callback) {
				if (fn) fn(function(err) {
					var args = Array.prototype.slice.call(arguments, 1);
					if (args.length <= 1) args = args[0];
					callback.call(null, err, args);
				});
			}, callback);
			else {
				var results = {};
				eachfn.each(_keys(tasks), function(k, callback) {
					tasks[k](function(err) {
						var args = Array.prototype.slice.call(arguments, 1);
						if (args.length <= 1) args = args[0];
						results[k] = args;
						callback(err);
					});
				}, function(err) {
					callback(err, results);
				});
			}
		};
		async.parallel = function(tasks, callback) {
			_parallel({
				map: async.map,
				each: async.each
			}, tasks, callback);
		};
		async.parallelLimit = function(tasks, limit, callback) {
			_parallel({
				map: _mapLimit(limit),
				each: _eachLimit(limit)
			}, tasks, callback);
		};
		async.series = function(tasks, callback) {
			callback = callback || function() {};
			if (tasks.constructor === Array) async.mapSeries(tasks, function(fn, callback) {
				if (fn) fn(function(err) {
					var args = Array.prototype.slice.call(arguments, 1);
					if (args.length <= 1) args = args[0];
					callback.call(null, err, args);
				});
			}, callback);
			else {
				var results = {};
				async.eachSeries(_keys(tasks), function(k, callback) {
					tasks[k](function(err) {
						var args = Array.prototype.slice.call(arguments, 1);
						if (args.length <= 1) args = args[0];
						results[k] = args;
						callback(err);
					});
				}, function(err) {
					callback(err, results);
				});
			}
		};
		async.iterator = function(tasks) {
			var makeCallback = function(index) {
				var fn = function() {
					if (tasks.length) tasks[index].apply(null, arguments);
					return fn.next();
				};
				fn.next = function() {
					return index < tasks.length - 1 ? makeCallback(index + 1) : null;
				};
				return fn;
			};
			return makeCallback(0);
		};
		async.apply = function(fn) {
			var args = Array.prototype.slice.call(arguments, 1);
			return function() {
				return fn.apply(null, args.concat(Array.prototype.slice.call(arguments)));
			};
		};
		var _concat = function(eachfn, arr, fn, callback) {
			var r = [];
			eachfn(arr, function(x, cb) {
				fn(x, function(err, y) {
					r = r.concat(y || []);
					cb(err);
				});
			}, function(err) {
				callback(err, r);
			});
		};
		async.concat = doParallel(_concat);
		async.concatSeries = doSeries(_concat);
		async.whilst = function(test, iterator, callback) {
			if (test()) iterator(function(err) {
				if (err) return callback(err);
				async.whilst(test, iterator, callback);
			});
			else callback();
		};
		async.doWhilst = function(iterator, test, callback) {
			iterator(function(err) {
				if (err) return callback(err);
				if (test()) async.doWhilst(iterator, test, callback);
				else callback();
			});
		};
		async.until = function(test, iterator, callback) {
			if (!test()) iterator(function(err) {
				if (err) return callback(err);
				async.until(test, iterator, callback);
			});
			else callback();
		};
		async.doUntil = function(iterator, test, callback) {
			iterator(function(err) {
				if (err) return callback(err);
				if (!test()) async.doUntil(iterator, test, callback);
				else callback();
			});
		};
		async.queue = function(worker, concurrency) {
			if (concurrency === void 0) concurrency = 1;
			function _insert(q, data, pos, callback) {
				if (data.constructor !== Array) data = [data];
				_each(data, function(task) {
					var item = {
						data: task,
						callback: typeof callback === "function" ? callback : null
					};
					if (pos) q.tasks.unshift(item);
					else q.tasks.push(item);
					if (q.saturated && q.tasks.length === concurrency) q.saturated();
					async.setImmediate(q.process);
				});
			}
			var workers = 0;
			var q = {
				tasks: [],
				concurrency,
				saturated: null,
				empty: null,
				drain: null,
				push: function(data, callback) {
					_insert(q, data, false, callback);
				},
				unshift: function(data, callback) {
					_insert(q, data, true, callback);
				},
				process: function() {
					if (workers < q.concurrency && q.tasks.length) {
						var task = q.tasks.shift();
						if (q.empty && q.tasks.length === 0) q.empty();
						workers += 1;
						var next = function() {
							workers -= 1;
							if (task.callback) task.callback.apply(task, arguments);
							if (q.drain && q.tasks.length + workers === 0) q.drain();
							q.process();
						};
						var cb = only_once(next);
						worker(task.data, cb);
					}
				},
				length: function() {
					return q.tasks.length;
				},
				running: function() {
					return workers;
				}
			};
			return q;
		};
		async.cargo = function(worker, payload) {
			var working = false, tasks = [];
			var cargo = {
				tasks,
				payload,
				saturated: null,
				empty: null,
				drain: null,
				push: function(data, callback) {
					if (data.constructor !== Array) data = [data];
					_each(data, function(task) {
						tasks.push({
							data: task,
							callback: typeof callback === "function" ? callback : null
						});
						if (cargo.saturated && tasks.length === payload) cargo.saturated();
					});
					async.setImmediate(cargo.process);
				},
				process: function process() {
					if (working) return;
					if (tasks.length === 0) {
						if (cargo.drain) cargo.drain();
						return;
					}
					var ts = typeof payload === "number" ? tasks.splice(0, payload) : tasks.splice(0);
					var ds = _map(ts, function(task) {
						return task.data;
					});
					if (cargo.empty) cargo.empty();
					working = true;
					worker(ds, function() {
						working = false;
						var args = arguments;
						_each(ts, function(data) {
							if (data.callback) data.callback.apply(null, args);
						});
						process();
					});
				},
				length: function() {
					return tasks.length;
				},
				running: function() {
					return working;
				}
			};
			return cargo;
		};
		var _console_fn = function(name) {
			return function(fn) {
				var args = Array.prototype.slice.call(arguments, 1);
				fn.apply(null, args.concat([function(err) {
					var args = Array.prototype.slice.call(arguments, 1);
					if (typeof console !== "undefined") {
						if (err) {
							if (console.error) console.error(err);
						} else if (console[name]) _each(args, function(x) {
							console[name](x);
						});
					}
				}]));
			};
		};
		async.log = _console_fn("log");
		async.dir = _console_fn("dir");
		async.memoize = function(fn, hasher) {
			var memo = {};
			var queues = {};
			hasher = hasher || function(x) {
				return x;
			};
			var memoized = function() {
				var args = Array.prototype.slice.call(arguments);
				var callback = args.pop();
				var key = hasher.apply(null, args);
				if (key in memo) callback.apply(null, memo[key]);
				else if (key in queues) queues[key].push(callback);
				else {
					queues[key] = [callback];
					fn.apply(null, args.concat([function() {
						memo[key] = arguments;
						var q = queues[key];
						delete queues[key];
						for (var i = 0, l = q.length; i < l; i++) q[i].apply(null, arguments);
					}]));
				}
			};
			memoized.memo = memo;
			memoized.unmemoized = fn;
			return memoized;
		};
		async.unmemoize = function(fn) {
			return function() {
				return (fn.unmemoized || fn).apply(null, arguments);
			};
		};
		async.times = function(count, iterator, callback) {
			var counter = [];
			for (var i = 0; i < count; i++) counter.push(i);
			return async.map(counter, iterator, callback);
		};
		async.timesSeries = function(count, iterator, callback) {
			var counter = [];
			for (var i = 0; i < count; i++) counter.push(i);
			return async.mapSeries(counter, iterator, callback);
		};
		async.compose = function() {
			var fns = Array.prototype.reverse.call(arguments);
			return function() {
				var that = this;
				var args = Array.prototype.slice.call(arguments);
				var callback = args.pop();
				async.reduce(fns, args, function(newargs, fn, cb) {
					fn.apply(that, newargs.concat([function() {
						var err = arguments[0];
						cb(err, Array.prototype.slice.call(arguments, 1));
					}]));
				}, function(err, results) {
					callback.apply(that, [err].concat(results));
				});
			};
		};
		var _applyEach = function(eachfn, fns) {
			var go = function() {
				var that = this;
				var args = Array.prototype.slice.call(arguments);
				return eachfn(fns, function(fn, cb) {
					fn.apply(that, args.concat([cb]));
				}, args.pop());
			};
			if (arguments.length > 2) {
				var args = Array.prototype.slice.call(arguments, 2);
				return go.apply(this, args);
			} else return go;
		};
		async.applyEach = doParallel(_applyEach);
		async.applyEachSeries = doSeries(_applyEach);
		async.forever = function(fn, callback) {
			function next(err) {
				if (err) {
					if (callback) return callback(err);
					throw err;
				}
				fn(next);
			}
			next();
		};
		if (typeof define !== "undefined" && define.amd) define([], function() {
			return async;
		});
		else if (typeof module !== "undefined" && module.exports) module.exports = async;
		else root.async = async;
	})();
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/processor.js
var require_processor = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var spawn$2 = __require("child_process").spawn;
	__require("path");
	__require("fs");
	var async = require_async();
	var utils = require_utils$2();
	/**
	* Run ffprobe asynchronously and store data in command
	*
	* @param {FfmpegCommand} command
	* @private
	*/
	function runFfprobe(command) {
		const inputProbeIndex = 0;
		if (command._inputs[inputProbeIndex].isStream) return;
		command.ffprobe(inputProbeIndex, function(err, data) {
			command._ffprobeData = data;
		});
	}
	module.exports = function(proto) {
		/**
		* Emitted just after ffmpeg has been spawned.
		*
		* @event FfmpegCommand#start
		* @param {String} command ffmpeg command line
		*/
		/**
		* Emitted when ffmpeg reports progress information
		*
		* @event FfmpegCommand#progress
		* @param {Object} progress progress object
		* @param {Number} progress.frames number of frames transcoded
		* @param {Number} progress.currentFps current processing speed in frames per second
		* @param {Number} progress.currentKbps current output generation speed in kilobytes per second
		* @param {Number} progress.targetSize current output file size
		* @param {String} progress.timemark current video timemark
		* @param {Number} [progress.percent] processing progress (may not be available depending on input)
		*/
		/**
		* Emitted when ffmpeg outputs to stderr
		*
		* @event FfmpegCommand#stderr
		* @param {String} line stderr output line
		*/
		/**
		* Emitted when ffmpeg reports input codec data
		*
		* @event FfmpegCommand#codecData
		* @param {Object} codecData codec data object
		* @param {String} codecData.format input format name
		* @param {String} codecData.audio input audio codec name
		* @param {String} codecData.audio_details input audio codec parameters
		* @param {String} codecData.video input video codec name
		* @param {String} codecData.video_details input video codec parameters
		*/
		/**
		* Emitted when an error happens when preparing or running a command
		*
		* @event FfmpegCommand#error
		* @param {Error} error error object, with optional properties 'inputStreamError' / 'outputStreamError' for errors on their respective streams
		* @param {String|null} stdout ffmpeg stdout, unless outputting to a stream
		* @param {String|null} stderr ffmpeg stderr
		*/
		/**
		* Emitted when a command finishes processing
		*
		* @event FfmpegCommand#end
		* @param {Array|String|null} [filenames|stdout] generated filenames when taking screenshots, ffmpeg stdout when not outputting to a stream, null otherwise
		* @param {String|null} stderr ffmpeg stderr
		*/
		/**
		* Spawn an ffmpeg process
		*
		* The 'options' argument may contain the following keys:
		* - 'niceness': specify process niceness, ignored on Windows (default: 0)
		* - `cwd`: change working directory
		* - 'captureStdout': capture stdout and pass it to 'endCB' as its 2nd argument (default: false)
		* - 'stdoutLines': override command limit (default: use command limit)
		*
		* The 'processCB' callback, if present, is called as soon as the process is created and
		* receives a nodejs ChildProcess object.  It may not be called at all if an error happens
		* before spawning the process.
		*
		* The 'endCB' callback is called either when an error occurs or when the ffmpeg process finishes.
		*
		* @method FfmpegCommand#_spawnFfmpeg
		* @param {Array} args ffmpeg command line argument list
		* @param {Object} [options] spawn options (see above)
		* @param {Function} [processCB] callback called with process object and stdout/stderr ring buffers when process has been created
		* @param {Function} endCB callback called with error (if applicable) and stdout/stderr ring buffers when process finished
		* @private
		*/
		proto._spawnFfmpeg = function(args, options, processCB, endCB) {
			if (typeof options === "function") {
				endCB = processCB;
				processCB = options;
				options = {};
			}
			if (typeof endCB === "undefined") {
				endCB = processCB;
				processCB = function() {};
			}
			var maxLines = "stdoutLines" in options ? options.stdoutLines : this.options.stdoutLines;
			this._getFfmpegPath(function(err, command) {
				if (err) return endCB(err);
				else if (!command || command.length === 0) return endCB(/* @__PURE__ */ new Error("Cannot find ffmpeg"));
				if (options.niceness && options.niceness !== 0 && !utils.isWindows) {
					args.unshift("-n", options.niceness, command);
					command = "nice";
				}
				var stdoutRing = utils.linesRing(maxLines);
				var stdoutClosed = false;
				var stderrRing = utils.linesRing(maxLines);
				var stderrClosed = false;
				var ffmpegProc = spawn$2(command, args, options);
				if (ffmpegProc.stderr) ffmpegProc.stderr.setEncoding("utf8");
				ffmpegProc.on("error", function(err) {
					endCB(err);
				});
				var exitError = null;
				function handleExit(err) {
					if (err) exitError = err;
					if (processExited && (stdoutClosed || !options.captureStdout) && stderrClosed) endCB(exitError, stdoutRing, stderrRing);
				}
				var processExited = false;
				ffmpegProc.on("exit", function(code, signal) {
					processExited = true;
					if (signal) handleExit(/* @__PURE__ */ new Error("ffmpeg was killed with signal " + signal));
					else if (code) handleExit(/* @__PURE__ */ new Error("ffmpeg exited with code " + code));
					else handleExit();
				});
				if (options.captureStdout) {
					ffmpegProc.stdout.on("data", function(data) {
						stdoutRing.append(data);
					});
					ffmpegProc.stdout.on("close", function() {
						stdoutRing.close();
						stdoutClosed = true;
						handleExit();
					});
				}
				ffmpegProc.stderr.on("data", function(data) {
					stderrRing.append(data);
				});
				ffmpegProc.stderr.on("close", function() {
					stderrRing.close();
					stderrClosed = true;
					handleExit();
				});
				processCB(ffmpegProc, stdoutRing, stderrRing);
			});
		};
		/**
		* Build the argument list for an ffmpeg command
		*
		* @method FfmpegCommand#_getArguments
		* @return argument list
		* @private
		*/
		proto._getArguments = function() {
			var complexFilters = this._complexFilters.get();
			var fileOutput = this._outputs.some(function(output) {
				return output.isFile;
			});
			return [].concat(this._inputs.reduce(function(args, input) {
				var source = typeof input.source === "string" ? input.source : "pipe:0";
				return args.concat(input.options.get(), ["-i", source]);
			}, []), this._global.get(), fileOutput ? ["-y"] : [], complexFilters, this._outputs.reduce(function(args, output) {
				var sizeFilters = utils.makeFilterStrings(output.sizeFilters.get());
				var audioFilters = output.audioFilters.get();
				var videoFilters = output.videoFilters.get().concat(sizeFilters);
				var outputArg;
				if (!output.target) outputArg = [];
				else if (typeof output.target === "string") outputArg = [output.target];
				else outputArg = ["pipe:1"];
				return args.concat(output.audio.get(), audioFilters.length ? ["-filter:a", audioFilters.join(",")] : [], output.video.get(), videoFilters.length ? ["-filter:v", videoFilters.join(",")] : [], output.options.get(), outputArg);
			}, []));
		};
		/**
		* Prepare execution of an ffmpeg command
		*
		* Checks prerequisites for the execution of the command (codec/format availability, flvtool...),
		* then builds the argument list for ffmpeg and pass them to 'callback'.
		*
		* @method FfmpegCommand#_prepare
		* @param {Function} callback callback with signature (err, args)
		* @param {Boolean} [readMetadata=false] read metadata before processing
		* @private
		*/
		proto._prepare = function(callback, readMetadata) {
			var self = this;
			async.waterfall([
				function(cb) {
					self._checkCapabilities(cb);
				},
				function(cb) {
					if (!readMetadata) return cb();
					self.ffprobe(0, function(err, data) {
						if (!err) self._ffprobeData = data;
						cb();
					});
				},
				function(cb) {
					if (self._outputs.some(function(output) {
						if (output.flags.flvmeta && !output.isFile) {
							self.logger.warn("Updating flv metadata is only supported for files");
							output.flags.flvmeta = false;
						}
						return output.flags.flvmeta;
					})) self._getFlvtoolPath(function(err) {
						cb(err);
					});
					else cb();
				},
				function(cb) {
					var args;
					try {
						args = self._getArguments();
					} catch (e) {
						return cb(e);
					}
					cb(null, args);
				},
				function(args, cb) {
					self.availableEncoders(function(err, encoders) {
						for (var i = 0; i < args.length; i++) if (args[i] === "-acodec" || args[i] === "-vcodec") {
							i++;
							if (args[i] in encoders && encoders[args[i]].experimental) {
								args.splice(i + 1, 0, "-strict", "experimental");
								i += 2;
							}
						}
						cb(null, args);
					});
				}
			], callback);
			if (!readMetadata) if (this.listeners("progress").length > 0) runFfprobe(this);
			else this.once("newListener", function(event) {
				if (event === "progress") runFfprobe(this);
			});
		};
		/**
		* Run ffmpeg command
		*
		* @method FfmpegCommand#run
		* @category Processing
		* @aliases exec,execute
		*/
		proto.exec = proto.execute = proto.run = function() {
			var self = this;
			if (!this._outputs.some(function(output) {
				return "target" in output;
			})) throw new Error("No output specified");
			var outputStream = this._outputs.filter(function(output) {
				return typeof output.target !== "string";
			})[0];
			var inputStream = this._inputs.filter(function(input) {
				return typeof input.source !== "string";
			})[0];
			var ended = false;
			function emitEnd(err, stdout, stderr) {
				if (!ended) {
					ended = true;
					if (err) self.emit("error", err, stdout, stderr);
					else self.emit("end", stdout, stderr);
				}
			}
			self._prepare(function(err, args) {
				if (err) return emitEnd(err);
				self._spawnFfmpeg(args, {
					captureStdout: !outputStream,
					niceness: self.options.niceness,
					cwd: self.options.cwd,
					windowsHide: true
				}, function processCB(ffmpegProc, stdoutRing, stderrRing) {
					self.ffmpegProc = ffmpegProc;
					self.emit("start", "ffmpeg " + args.join(" "));
					if (inputStream) {
						inputStream.source.on("error", function(err) {
							var reportingErr = /* @__PURE__ */ new Error("Input stream error: " + err.message);
							reportingErr.inputStreamError = err;
							emitEnd(reportingErr);
							ffmpegProc.kill();
						});
						inputStream.source.resume();
						inputStream.source.pipe(ffmpegProc.stdin);
						ffmpegProc.stdin.on("error", function() {});
					}
					if (self.options.timeout) self.processTimer = setTimeout(function() {
						var msg = "process ran into a timeout (" + self.options.timeout + "s)";
						emitEnd(new Error(msg), stdoutRing.get(), stderrRing.get());
						ffmpegProc.kill();
					}, self.options.timeout * 1e3);
					if (outputStream) {
						ffmpegProc.stdout.pipe(outputStream.target, outputStream.pipeopts);
						outputStream.target.on("close", function() {
							self.logger.debug("Output stream closed, scheduling kill for ffmpeg process");
							setTimeout(function() {
								emitEnd(/* @__PURE__ */ new Error("Output stream closed"));
								ffmpegProc.kill();
							}, 20);
						});
						outputStream.target.on("error", function(err) {
							self.logger.debug("Output stream error, killing ffmpeg process");
							var reportingErr = /* @__PURE__ */ new Error("Output stream error: " + err.message);
							reportingErr.outputStreamError = err;
							emitEnd(reportingErr, stdoutRing.get(), stderrRing.get());
							ffmpegProc.kill("SIGKILL");
						});
					}
					if (stderrRing) {
						if (self.listeners("stderr").length) stderrRing.callback(function(line) {
							self.emit("stderr", line);
						});
						if (self.listeners("codecData").length) {
							var codecDataSent = false;
							var codecObject = {};
							stderrRing.callback(function(line) {
								if (!codecDataSent) codecDataSent = utils.extractCodecData(self, line, codecObject);
							});
						}
						if (self.listeners("progress").length) stderrRing.callback(function(line) {
							utils.extractProgress(self, line);
						});
					}
				}, function endCB(err, stdoutRing, stderrRing) {
					clearTimeout(self.processTimer);
					delete self.ffmpegProc;
					if (err) {
						if (err.message.match(/ffmpeg exited with code/)) err.message += ": " + utils.extractError(stderrRing.get());
						emitEnd(err, stdoutRing.get(), stderrRing.get());
					} else {
						var flvmeta = self._outputs.filter(function(output) {
							return output.flags.flvmeta;
						});
						if (flvmeta.length) self._getFlvtoolPath(function(err, flvtool) {
							if (err) return emitEnd(err);
							async.each(flvmeta, function(output, cb) {
								spawn$2(flvtool, ["-U", output.target], { windowsHide: true }).on("error", function(err) {
									cb(/* @__PURE__ */ new Error("Error running " + flvtool + " on " + output.target + ": " + err.message));
								}).on("exit", function(code, signal) {
									if (code !== 0 || signal) cb(/* @__PURE__ */ new Error(flvtool + " " + (signal ? "received signal " + signal : "exited with code " + code)) + " when running on " + output.target);
									else cb();
								});
							}, function(err) {
								if (err) emitEnd(err);
								else emitEnd(null, stdoutRing.get(), stderrRing.get());
							});
						});
						else emitEnd(null, stdoutRing.get(), stderrRing.get());
					}
				});
			});
			return this;
		};
		/**
		* Renice current and/or future ffmpeg processes
		*
		* Ignored on Windows platforms.
		*
		* @method FfmpegCommand#renice
		* @category Processing
		*
		* @param {Number} [niceness=0] niceness value between -20 (highest priority) and 20 (lowest priority)
		* @return FfmpegCommand
		*/
		proto.renice = function(niceness) {
			if (!utils.isWindows) {
				niceness = niceness || 0;
				if (niceness < -20 || niceness > 20) this.logger.warn("Invalid niceness value: " + niceness + ", must be between -20 and 20");
				niceness = Math.min(20, Math.max(-20, niceness));
				this.options.niceness = niceness;
				if (this.ffmpegProc) {
					var logger = this.logger;
					var pid = this.ffmpegProc.pid;
					var renice = spawn$2("renice", [
						niceness,
						"-p",
						pid
					], { windowsHide: true });
					renice.on("error", function(err) {
						logger.warn("could not renice process " + pid + ": " + err.message);
					});
					renice.on("exit", function(code, signal) {
						if (signal) logger.warn("could not renice process " + pid + ": renice was killed by signal " + signal);
						else if (code) logger.warn("could not renice process " + pid + ": renice exited with " + code);
						else logger.info("successfully reniced process " + pid + " to " + niceness + " niceness");
					});
				}
			}
			return this;
		};
		/**
		* Kill current ffmpeg process, if any
		*
		* @method FfmpegCommand#kill
		* @category Processing
		*
		* @param {String} [signal=SIGKILL] signal name
		* @return FfmpegCommand
		*/
		proto.kill = function(signal) {
			if (!this.ffmpegProc) this.logger.warn("No running ffmpeg process, cannot send signal");
			else this.ffmpegProc.kill(signal || "SIGKILL");
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/capabilities.js
var require_capabilities = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var fs$8 = __require("fs");
	var path$7 = __require("path");
	var async = require_async();
	var utils = require_utils$2();
	var avCodecRegexp = /^\s*([D ])([E ])([VAS])([S ])([D ])([T ]) ([^ ]+) +(.*)$/;
	var ffCodecRegexp = /^\s*([D\.])([E\.])([VAS])([I\.])([L\.])([S\.]) ([^ ]+) +(.*)$/;
	var ffEncodersRegexp = /\(encoders:([^\)]+)\)/;
	var ffDecodersRegexp = /\(decoders:([^\)]+)\)/;
	var encodersRegexp = /^\s*([VAS\.])([F\.])([S\.])([X\.])([B\.])([D\.]) ([^ ]+) +(.*)$/;
	var formatRegexp = /^\s*([D ])([E ])\s+([^ ]+)\s+(.*)$/;
	var lineBreakRegexp = /\r\n|\r|\n/;
	var filterRegexp = /^(?: [T\.][S\.][C\.] )?([^ ]+) +(AA?|VV?|\|)->(AA?|VV?|\|) +(.*)$/;
	var cache = {};
	module.exports = function(proto) {
		/**
		* Manually define the ffmpeg binary full path.
		*
		* @method FfmpegCommand#setFfmpegPath
		*
		* @param {String} ffmpegPath The full path to the ffmpeg binary.
		* @return FfmpegCommand
		*/
		proto.setFfmpegPath = function(ffmpegPath) {
			cache.ffmpegPath = ffmpegPath;
			return this;
		};
		/**
		* Manually define the ffprobe binary full path.
		*
		* @method FfmpegCommand#setFfprobePath
		*
		* @param {String} ffprobePath The full path to the ffprobe binary.
		* @return FfmpegCommand
		*/
		proto.setFfprobePath = function(ffprobePath) {
			cache.ffprobePath = ffprobePath;
			return this;
		};
		/**
		* Manually define the flvtool2/flvmeta binary full path.
		*
		* @method FfmpegCommand#setFlvtoolPath
		*
		* @param {String} flvtool The full path to the flvtool2 or flvmeta binary.
		* @return FfmpegCommand
		*/
		proto.setFlvtoolPath = function(flvtool) {
			cache.flvtoolPath = flvtool;
			return this;
		};
		/**
		* Forget executable paths
		*
		* (only used for testing purposes)
		*
		* @method FfmpegCommand#_forgetPaths
		* @private
		*/
		proto._forgetPaths = function() {
			delete cache.ffmpegPath;
			delete cache.ffprobePath;
			delete cache.flvtoolPath;
		};
		/**
		* Check for ffmpeg availability
		*
		* If the FFMPEG_PATH environment variable is set, try to use it.
		* If it is unset or incorrect, try to find ffmpeg in the PATH instead.
		*
		* @method FfmpegCommand#_getFfmpegPath
		* @param {Function} callback callback with signature (err, path)
		* @private
		*/
		proto._getFfmpegPath = function(callback) {
			if ("ffmpegPath" in cache) return callback(null, cache.ffmpegPath);
			async.waterfall([function(cb) {
				if (process.env.FFMPEG_PATH) fs$8.exists(process.env.FFMPEG_PATH, function(exists) {
					if (exists) cb(null, process.env.FFMPEG_PATH);
					else cb(null, "");
				});
				else cb(null, "");
			}, function(ffmpeg, cb) {
				if (ffmpeg.length) return cb(null, ffmpeg);
				utils.which("ffmpeg", function(err, ffmpeg) {
					cb(err, ffmpeg);
				});
			}], function(err, ffmpeg) {
				if (err) callback(err);
				else callback(null, cache.ffmpegPath = ffmpeg || "");
			});
		};
		/**
		* Check for ffprobe availability
		*
		* If the FFPROBE_PATH environment variable is set, try to use it.
		* If it is unset or incorrect, try to find ffprobe in the PATH instead.
		* If this still fails, try to find ffprobe in the same directory as ffmpeg.
		*
		* @method FfmpegCommand#_getFfprobePath
		* @param {Function} callback callback with signature (err, path)
		* @private
		*/
		proto._getFfprobePath = function(callback) {
			var self = this;
			if ("ffprobePath" in cache) return callback(null, cache.ffprobePath);
			async.waterfall([
				function(cb) {
					if (process.env.FFPROBE_PATH) fs$8.exists(process.env.FFPROBE_PATH, function(exists) {
						cb(null, exists ? process.env.FFPROBE_PATH : "");
					});
					else cb(null, "");
				},
				function(ffprobe, cb) {
					if (ffprobe.length) return cb(null, ffprobe);
					utils.which("ffprobe", function(err, ffprobe) {
						cb(err, ffprobe);
					});
				},
				function(ffprobe, cb) {
					if (ffprobe.length) return cb(null, ffprobe);
					self._getFfmpegPath(function(err, ffmpeg) {
						if (err) cb(err);
						else if (ffmpeg.length) {
							var name = utils.isWindows ? "ffprobe.exe" : "ffprobe";
							var ffprobe = path$7.join(path$7.dirname(ffmpeg), name);
							fs$8.exists(ffprobe, function(exists) {
								cb(null, exists ? ffprobe : "");
							});
						} else cb(null, "");
					});
				}
			], function(err, ffprobe) {
				if (err) callback(err);
				else callback(null, cache.ffprobePath = ffprobe || "");
			});
		};
		/**
		* Check for flvtool2/flvmeta availability
		*
		* If the FLVTOOL2_PATH or FLVMETA_PATH environment variable are set, try to use them.
		* If both are either unset or incorrect, try to find flvtool2 or flvmeta in the PATH instead.
		*
		* @method FfmpegCommand#_getFlvtoolPath
		* @param {Function} callback callback with signature (err, path)
		* @private
		*/
		proto._getFlvtoolPath = function(callback) {
			if ("flvtoolPath" in cache) return callback(null, cache.flvtoolPath);
			async.waterfall([
				function(cb) {
					if (process.env.FLVMETA_PATH) fs$8.exists(process.env.FLVMETA_PATH, function(exists) {
						cb(null, exists ? process.env.FLVMETA_PATH : "");
					});
					else cb(null, "");
				},
				function(flvtool, cb) {
					if (flvtool.length) return cb(null, flvtool);
					if (process.env.FLVTOOL2_PATH) fs$8.exists(process.env.FLVTOOL2_PATH, function(exists) {
						cb(null, exists ? process.env.FLVTOOL2_PATH : "");
					});
					else cb(null, "");
				},
				function(flvtool, cb) {
					if (flvtool.length) return cb(null, flvtool);
					utils.which("flvmeta", function(err, flvmeta) {
						cb(err, flvmeta);
					});
				},
				function(flvtool, cb) {
					if (flvtool.length) return cb(null, flvtool);
					utils.which("flvtool2", function(err, flvtool2) {
						cb(err, flvtool2);
					});
				}
			], function(err, flvtool) {
				if (err) callback(err);
				else callback(null, cache.flvtoolPath = flvtool || "");
			});
		};
		/**
		* A callback passed to {@link FfmpegCommand#availableFilters}.
		*
		* @callback FfmpegCommand~filterCallback
		* @param {Error|null} err error object or null if no error happened
		* @param {Object} filters filter object with filter names as keys and the following
		*   properties for each filter:
		* @param {String} filters.description filter description
		* @param {String} filters.input input type, one of 'audio', 'video' and 'none'
		* @param {Boolean} filters.multipleInputs whether the filter supports multiple inputs
		* @param {String} filters.output output type, one of 'audio', 'video' and 'none'
		* @param {Boolean} filters.multipleOutputs whether the filter supports multiple outputs
		*/
		/**
		* Query ffmpeg for available filters
		*
		* @method FfmpegCommand#availableFilters
		* @category Capabilities
		* @aliases getAvailableFilters
		*
		* @param {FfmpegCommand~filterCallback} callback callback function
		*/
		proto.availableFilters = proto.getAvailableFilters = function(callback) {
			if ("filters" in cache) return callback(null, cache.filters);
			this._spawnFfmpeg(["-filters"], {
				captureStdout: true,
				stdoutLines: 0
			}, function(err, stdoutRing) {
				if (err) return callback(err);
				var lines = stdoutRing.get().split("\n");
				var data = {};
				var types = {
					A: "audio",
					V: "video",
					"|": "none"
				};
				lines.forEach(function(line) {
					var match = line.match(filterRegexp);
					if (match) data[match[1]] = {
						description: match[4],
						input: types[match[2].charAt(0)],
						multipleInputs: match[2].length > 1,
						output: types[match[3].charAt(0)],
						multipleOutputs: match[3].length > 1
					};
				});
				callback(null, cache.filters = data);
			});
		};
		/**
		* A callback passed to {@link FfmpegCommand#availableCodecs}.
		*
		* @callback FfmpegCommand~codecCallback
		* @param {Error|null} err error object or null if no error happened
		* @param {Object} codecs codec object with codec names as keys and the following
		*   properties for each codec (more properties may be available depending on the
		*   ffmpeg version used):
		* @param {String} codecs.description codec description
		* @param {Boolean} codecs.canDecode whether the codec is able to decode streams
		* @param {Boolean} codecs.canEncode whether the codec is able to encode streams
		*/
		/**
		* Query ffmpeg for available codecs
		*
		* @method FfmpegCommand#availableCodecs
		* @category Capabilities
		* @aliases getAvailableCodecs
		*
		* @param {FfmpegCommand~codecCallback} callback callback function
		*/
		proto.availableCodecs = proto.getAvailableCodecs = function(callback) {
			if ("codecs" in cache) return callback(null, cache.codecs);
			this._spawnFfmpeg(["-codecs"], {
				captureStdout: true,
				stdoutLines: 0
			}, function(err, stdoutRing) {
				if (err) return callback(err);
				var lines = stdoutRing.get().split(lineBreakRegexp);
				var data = {};
				lines.forEach(function(line) {
					var match = line.match(avCodecRegexp);
					if (match && match[7] !== "=") data[match[7]] = {
						type: {
							"V": "video",
							"A": "audio",
							"S": "subtitle"
						}[match[3]],
						description: match[8],
						canDecode: match[1] === "D",
						canEncode: match[2] === "E",
						drawHorizBand: match[4] === "S",
						directRendering: match[5] === "D",
						weirdFrameTruncation: match[6] === "T"
					};
					match = line.match(ffCodecRegexp);
					if (match && match[7] !== "=") {
						var codecData = data[match[7]] = {
							type: {
								"V": "video",
								"A": "audio",
								"S": "subtitle"
							}[match[3]],
							description: match[8],
							canDecode: match[1] === "D",
							canEncode: match[2] === "E",
							intraFrameOnly: match[4] === "I",
							isLossy: match[5] === "L",
							isLossless: match[6] === "S"
						};
						var encoders = codecData.description.match(ffEncodersRegexp);
						encoders = encoders ? encoders[1].trim().split(" ") : [];
						var decoders = codecData.description.match(ffDecodersRegexp);
						decoders = decoders ? decoders[1].trim().split(" ") : [];
						if (encoders.length || decoders.length) {
							var coderData = {};
							utils.copy(codecData, coderData);
							delete coderData.canEncode;
							delete coderData.canDecode;
							encoders.forEach(function(name) {
								data[name] = {};
								utils.copy(coderData, data[name]);
								data[name].canEncode = true;
							});
							decoders.forEach(function(name) {
								if (name in data) data[name].canDecode = true;
								else {
									data[name] = {};
									utils.copy(coderData, data[name]);
									data[name].canDecode = true;
								}
							});
						}
					}
				});
				callback(null, cache.codecs = data);
			});
		};
		/**
		* A callback passed to {@link FfmpegCommand#availableEncoders}.
		*
		* @callback FfmpegCommand~encodersCallback
		* @param {Error|null} err error object or null if no error happened
		* @param {Object} encoders encoders object with encoder names as keys and the following
		*   properties for each encoder:
		* @param {String} encoders.description codec description
		* @param {Boolean} encoders.type "audio", "video" or "subtitle"
		* @param {Boolean} encoders.frameMT whether the encoder is able to do frame-level multithreading
		* @param {Boolean} encoders.sliceMT whether the encoder is able to do slice-level multithreading
		* @param {Boolean} encoders.experimental whether the encoder is experimental
		* @param {Boolean} encoders.drawHorizBand whether the encoder supports draw_horiz_band
		* @param {Boolean} encoders.directRendering whether the encoder supports direct encoding method 1
		*/
		/**
		* Query ffmpeg for available encoders
		*
		* @method FfmpegCommand#availableEncoders
		* @category Capabilities
		* @aliases getAvailableEncoders
		*
		* @param {FfmpegCommand~encodersCallback} callback callback function
		*/
		proto.availableEncoders = proto.getAvailableEncoders = function(callback) {
			if ("encoders" in cache) return callback(null, cache.encoders);
			this._spawnFfmpeg(["-encoders"], {
				captureStdout: true,
				stdoutLines: 0
			}, function(err, stdoutRing) {
				if (err) return callback(err);
				var lines = stdoutRing.get().split(lineBreakRegexp);
				var data = {};
				lines.forEach(function(line) {
					var match = line.match(encodersRegexp);
					if (match && match[7] !== "=") data[match[7]] = {
						type: {
							"V": "video",
							"A": "audio",
							"S": "subtitle"
						}[match[1]],
						description: match[8],
						frameMT: match[2] === "F",
						sliceMT: match[3] === "S",
						experimental: match[4] === "X",
						drawHorizBand: match[5] === "B",
						directRendering: match[6] === "D"
					};
				});
				callback(null, cache.encoders = data);
			});
		};
		/**
		* A callback passed to {@link FfmpegCommand#availableFormats}.
		*
		* @callback FfmpegCommand~formatCallback
		* @param {Error|null} err error object or null if no error happened
		* @param {Object} formats format object with format names as keys and the following
		*   properties for each format:
		* @param {String} formats.description format description
		* @param {Boolean} formats.canDemux whether the format is able to demux streams from an input file
		* @param {Boolean} formats.canMux whether the format is able to mux streams into an output file
		*/
		/**
		* Query ffmpeg for available formats
		*
		* @method FfmpegCommand#availableFormats
		* @category Capabilities
		* @aliases getAvailableFormats
		*
		* @param {FfmpegCommand~formatCallback} callback callback function
		*/
		proto.availableFormats = proto.getAvailableFormats = function(callback) {
			if ("formats" in cache) return callback(null, cache.formats);
			this._spawnFfmpeg(["-formats"], {
				captureStdout: true,
				stdoutLines: 0
			}, function(err, stdoutRing) {
				if (err) return callback(err);
				var lines = stdoutRing.get().split(lineBreakRegexp);
				var data = {};
				lines.forEach(function(line) {
					var match = line.match(formatRegexp);
					if (match) match[3].split(",").forEach(function(format) {
						if (!(format in data)) data[format] = {
							description: match[4],
							canDemux: false,
							canMux: false
						};
						if (match[1] === "D") data[format].canDemux = true;
						if (match[2] === "E") data[format].canMux = true;
					});
				});
				callback(null, cache.formats = data);
			});
		};
		/**
		* Check capabilities before executing a command
		*
		* Checks whether all used codecs and formats are indeed available
		*
		* @method FfmpegCommand#_checkCapabilities
		* @param {Function} callback callback with signature (err)
		* @private
		*/
		proto._checkCapabilities = function(callback) {
			var self = this;
			async.waterfall([
				function(cb) {
					self.availableFormats(cb);
				},
				function(formats, cb) {
					var unavailable = self._outputs.reduce(function(fmts, output) {
						var format = output.options.find("-f", 1);
						if (format) {
							if (!(format[0] in formats) || !formats[format[0]].canMux) fmts.push(format);
						}
						return fmts;
					}, []);
					if (unavailable.length === 1) return cb(/* @__PURE__ */ new Error("Output format " + unavailable[0] + " is not available"));
					else if (unavailable.length > 1) return cb(/* @__PURE__ */ new Error("Output formats " + unavailable.join(", ") + " are not available"));
					unavailable = self._inputs.reduce(function(fmts, input) {
						var format = input.options.find("-f", 1);
						if (format) {
							if (!(format[0] in formats) || !formats[format[0]].canDemux) fmts.push(format[0]);
						}
						return fmts;
					}, []);
					if (unavailable.length === 1) return cb(/* @__PURE__ */ new Error("Input format " + unavailable[0] + " is not available"));
					else if (unavailable.length > 1) return cb(/* @__PURE__ */ new Error("Input formats " + unavailable.join(", ") + " are not available"));
					cb();
				},
				function(cb) {
					self.availableEncoders(cb);
				},
				function(encoders, cb) {
					var unavailable = self._outputs.reduce(function(cdcs, output) {
						var acodec = output.audio.find("-acodec", 1);
						if (acodec && acodec[0] !== "copy") {
							if (!(acodec[0] in encoders) || encoders[acodec[0]].type !== "audio") cdcs.push(acodec[0]);
						}
						return cdcs;
					}, []);
					if (unavailable.length === 1) return cb(/* @__PURE__ */ new Error("Audio codec " + unavailable[0] + " is not available"));
					else if (unavailable.length > 1) return cb(/* @__PURE__ */ new Error("Audio codecs " + unavailable.join(", ") + " are not available"));
					unavailable = self._outputs.reduce(function(cdcs, output) {
						var vcodec = output.video.find("-vcodec", 1);
						if (vcodec && vcodec[0] !== "copy") {
							if (!(vcodec[0] in encoders) || encoders[vcodec[0]].type !== "video") cdcs.push(vcodec[0]);
						}
						return cdcs;
					}, []);
					if (unavailable.length === 1) return cb(/* @__PURE__ */ new Error("Video codec " + unavailable[0] + " is not available"));
					else if (unavailable.length > 1) return cb(/* @__PURE__ */ new Error("Video codecs " + unavailable.join(", ") + " are not available"));
					cb();
				}
			], callback);
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/ffprobe.js
var require_ffprobe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var spawn$1 = __require("child_process").spawn;
	function legacyTag(key) {
		return key.match(/^TAG:/);
	}
	function legacyDisposition(key) {
		return key.match(/^DISPOSITION:/);
	}
	function parseFfprobeOutput(out) {
		var lines = out.split(/\r\n|\r|\n/);
		lines = lines.filter(function(line) {
			return line.length > 0;
		});
		var data = {
			streams: [],
			format: {},
			chapters: []
		};
		function parseBlock(name) {
			var data = {};
			var line = lines.shift();
			while (typeof line !== "undefined") {
				if (line.toLowerCase() == "[/" + name + "]") return data;
				else if (line.match(/^\[/)) {
					line = lines.shift();
					continue;
				}
				var kv = line.match(/^([^=]+)=(.*)$/);
				if (kv) if (!kv[1].match(/^TAG:/) && kv[2].match(/^[0-9]+(\.[0-9]+)?$/)) data[kv[1]] = Number(kv[2]);
				else data[kv[1]] = kv[2];
				line = lines.shift();
			}
			return data;
		}
		var line = lines.shift();
		while (typeof line !== "undefined") {
			if (line.match(/^\[stream/i)) {
				var stream = parseBlock("stream");
				data.streams.push(stream);
			} else if (line.match(/^\[chapter/i)) {
				var chapter = parseBlock("chapter");
				data.chapters.push(chapter);
			} else if (line.toLowerCase() === "[format]") data.format = parseBlock("format");
			line = lines.shift();
		}
		return data;
	}
	module.exports = function(proto) {
		/**
		* A callback passed to the {@link FfmpegCommand#ffprobe} method.
		*
		* @callback FfmpegCommand~ffprobeCallback
		*
		* @param {Error|null} err error object or null if no error happened
		* @param {Object} ffprobeData ffprobe output data; this object
		*   has the same format as what the following command returns:
		*
		*     `ffprobe -print_format json -show_streams -show_format INPUTFILE`
		* @param {Array} ffprobeData.streams stream information
		* @param {Object} ffprobeData.format format information
		*/
		/**
		* Run ffprobe on last specified input
		*
		* @method FfmpegCommand#ffprobe
		* @category Metadata
		*
		* @param {?Number} [index] 0-based index of input to probe (defaults to last input)
		* @param {?String[]} [options] array of output options to return
		* @param {FfmpegCommand~ffprobeCallback} callback callback function
		*
		*/
		proto.ffprobe = function() {
			var input, index = null, options = [], callback;
			var callback = arguments[arguments.length - 1];
			var ended = false;
			function handleCallback(err, data) {
				if (!ended) {
					ended = true;
					callback(err, data);
				}
			}
			switch (arguments.length) {
				case 3:
					index = arguments[0];
					options = arguments[1];
					break;
				case 2: if (typeof arguments[0] === "number") index = arguments[0];
				else if (Array.isArray(arguments[0])) options = arguments[0];
			}
			if (index === null) {
				if (!this._currentInput) return handleCallback(/* @__PURE__ */ new Error("No input specified"));
				input = this._currentInput;
			} else {
				input = this._inputs[index];
				if (!input) return handleCallback(/* @__PURE__ */ new Error("Invalid input index"));
			}
			this._getFfprobePath(function(err, path) {
				if (err) return handleCallback(err);
				else if (!path) return handleCallback(/* @__PURE__ */ new Error("Cannot find ffprobe"));
				var stdout = "";
				var stdoutClosed = false;
				var stderr = "";
				var stderrClosed = false;
				var src = input.isStream ? "pipe:0" : input.source;
				var ffprobe = spawn$1(path, ["-show_streams", "-show_format"].concat(options, src), { windowsHide: true });
				if (input.isStream) {
					ffprobe.stdin.on("error", function(err) {
						if ([
							"ECONNRESET",
							"EPIPE",
							"EOF"
						].indexOf(err.code) >= 0) return;
						handleCallback(err);
					});
					ffprobe.stdin.on("close", function() {
						input.source.pause();
						input.source.unpipe(ffprobe.stdin);
					});
					input.source.pipe(ffprobe.stdin);
				}
				ffprobe.on("error", callback);
				var exitError = null;
				function handleExit(err) {
					if (err) exitError = err;
					if (processExited && stdoutClosed && stderrClosed) {
						if (exitError) {
							if (stderr) exitError.message += "\n" + stderr;
							return handleCallback(exitError);
						}
						var data = parseFfprobeOutput(stdout);
						[data.format].concat(data.streams).forEach(function(target) {
							if (target) {
								var legacyTagKeys = Object.keys(target).filter(legacyTag);
								if (legacyTagKeys.length) {
									target.tags = target.tags || {};
									legacyTagKeys.forEach(function(tagKey) {
										target.tags[tagKey.substr(4)] = target[tagKey];
										delete target[tagKey];
									});
								}
								var legacyDispositionKeys = Object.keys(target).filter(legacyDisposition);
								if (legacyDispositionKeys.length) {
									target.disposition = target.disposition || {};
									legacyDispositionKeys.forEach(function(dispositionKey) {
										target.disposition[dispositionKey.substr(12)] = target[dispositionKey];
										delete target[dispositionKey];
									});
								}
							}
						});
						handleCallback(null, data);
					}
				}
				var processExited = false;
				ffprobe.on("exit", function(code, signal) {
					processExited = true;
					if (code) handleExit(/* @__PURE__ */ new Error("ffprobe exited with code " + code));
					else if (signal) handleExit(/* @__PURE__ */ new Error("ffprobe was killed with signal " + signal));
					else handleExit();
				});
				ffprobe.stdout.on("data", function(data) {
					stdout += data;
				});
				ffprobe.stdout.on("close", function() {
					stdoutClosed = true;
					handleExit();
				});
				ffprobe.stderr.on("data", function(data) {
					stderr += data;
				});
				ffprobe.stderr.on("close", function() {
					stderrClosed = true;
					handleExit();
				});
			});
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/recipes.js
var require_recipes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var fs$7 = __require("fs");
	var path$6 = __require("path");
	var PassThrough$4 = __require("stream").PassThrough;
	var async = require_async();
	var utils = require_utils$2();
	module.exports = function recipes(proto) {
		/**
		* Execute ffmpeg command and save output to a file
		*
		* @method FfmpegCommand#save
		* @category Processing
		* @aliases saveToFile
		*
		* @param {String} output file path
		* @return FfmpegCommand
		*/
		proto.saveToFile = proto.save = function(output) {
			this.output(output).run();
			return this;
		};
		/**
		* Execute ffmpeg command and save output to a stream
		*
		* If 'stream' is not specified, a PassThrough stream is created and returned.
		* 'options' will be used when piping ffmpeg output to the output stream
		* (@see http://nodejs.org/api/stream.html#stream_readable_pipe_destination_options)
		*
		* @method FfmpegCommand#pipe
		* @category Processing
		* @aliases stream,writeToStream
		*
		* @param {stream.Writable} [stream] output stream
		* @param {Object} [options={}] pipe options
		* @return Output stream
		*/
		proto.writeToStream = proto.pipe = proto.stream = function(stream, options) {
			if (stream && !("writable" in stream)) {
				options = stream;
				stream = void 0;
			}
			if (!stream) {
				if (process.version.match(/v0\.8\./)) throw new Error("PassThrough stream is not supported on node v0.8");
				stream = new PassThrough$4();
			}
			this.output(stream, options).run();
			return stream;
		};
		/**
		* Generate images from a video
		*
		* Note: this method makes the command emit a 'filenames' event with an array of
		* the generated image filenames.
		*
		* @method FfmpegCommand#screenshots
		* @category Processing
		* @aliases takeScreenshots,thumbnail,thumbnails,screenshot
		*
		* @param {Number|Object} [config=1] screenshot count or configuration object with
		*   the following keys:
		* @param {Number} [config.count] number of screenshots to take; using this option
		*   takes screenshots at regular intervals (eg. count=4 would take screens at 20%, 40%,
		*   60% and 80% of the video length).
		* @param {String} [config.folder='.'] output folder
		* @param {String} [config.filename='tn.png'] output filename pattern, may contain the following
		*   tokens:
		*   - '%s': offset in seconds
		*   - '%w': screenshot width
		*   - '%h': screenshot height
		*   - '%r': screenshot resolution (same as '%wx%h')
		*   - '%f': input filename
		*   - '%b': input basename (filename w/o extension)
		*   - '%i': index of screenshot in timemark array (can be zero-padded by using it like `%000i`)
		* @param {Number[]|String[]} [config.timemarks] array of timemarks to take screenshots
		*   at; each timemark may be a number of seconds, a '[[hh:]mm:]ss[.xxx]' string or a
		*   'XX%' string.  Overrides 'count' if present.
		* @param {Number[]|String[]} [config.timestamps] alias for 'timemarks'
		* @param {Boolean} [config.fastSeek] use fast seek (less accurate)
		* @param {String} [config.size] screenshot size, with the same syntax as {@link FfmpegCommand#size}
		* @param {String} [folder] output folder (legacy alias for 'config.folder')
		* @return FfmpegCommand
		*/
		proto.takeScreenshots = proto.thumbnail = proto.thumbnails = proto.screenshot = proto.screenshots = function(config, folder) {
			var self = this;
			var source = this._currentInput.source;
			config = config || { count: 1 };
			if (typeof config === "number") config = { count: config };
			if (!("folder" in config)) config.folder = folder || ".";
			if ("timestamps" in config) config.timemarks = config.timestamps;
			if (!("timemarks" in config)) {
				if (!config.count) throw new Error("Cannot take screenshots: neither a count nor a timemark list are specified");
				var interval = 100 / (1 + config.count);
				config.timemarks = [];
				for (var i = 0; i < config.count; i++) config.timemarks.push(interval * (i + 1) + "%");
			}
			if ("size" in config) {
				var fixedSize = config.size.match(/^(\d+)x(\d+)$/);
				var fixedWidth = config.size.match(/^(\d+)x\?$/);
				var fixedHeight = config.size.match(/^\?x(\d+)$/);
				var percentSize = config.size.match(/^(\d+)%$/);
				if (!fixedSize && !fixedWidth && !fixedHeight && !percentSize) throw new Error("Invalid size parameter: " + config.size);
			}
			var metadata;
			function getMetadata(cb) {
				if (metadata) cb(null, metadata);
				else self.ffprobe(function(err, meta) {
					metadata = meta;
					cb(err, meta);
				});
			}
			async.waterfall([
				function computeTimemarks(next) {
					if (config.timemarks.some(function(t) {
						return ("" + t).match(/^[\d.]+%$/);
					})) {
						if (typeof source !== "string") return next(/* @__PURE__ */ new Error("Cannot compute screenshot timemarks with an input stream, please specify fixed timemarks"));
						getMetadata(function(err, meta) {
							if (err) next(err);
							else {
								var vstream = meta.streams.reduce(function(biggest, stream) {
									if (stream.codec_type === "video" && stream.width * stream.height > biggest.width * biggest.height) return stream;
									else return biggest;
								}, {
									width: 0,
									height: 0
								});
								if (vstream.width === 0) return next(/* @__PURE__ */ new Error("No video stream in input, cannot take screenshots"));
								var duration = Number(vstream.duration);
								if (isNaN(duration)) duration = Number(meta.format.duration);
								if (isNaN(duration)) return next(/* @__PURE__ */ new Error("Could not get input duration, please specify fixed timemarks"));
								config.timemarks = config.timemarks.map(function(mark) {
									if (("" + mark).match(/^([\d.]+)%$/)) return duration * parseFloat(mark) / 100;
									else return mark;
								});
								next();
							}
						});
					} else next();
				},
				function normalizeTimemarks(next) {
					config.timemarks = config.timemarks.map(function(mark) {
						return utils.timemarkToSeconds(mark);
					}).sort(function(a, b) {
						return a - b;
					});
					next();
				},
				function fixPattern(next) {
					var pattern = config.filename || "tn.png";
					if (pattern.indexOf(".") === -1) pattern += ".png";
					if (config.timemarks.length > 1 && !pattern.match(/%(s|0*i)/)) {
						var ext = path$6.extname(pattern);
						pattern = path$6.join(path$6.dirname(pattern), path$6.basename(pattern, ext) + "_%i" + ext);
					}
					next(null, pattern);
				},
				function replaceFilenameTokens(pattern, next) {
					if (pattern.match(/%[bf]/)) {
						if (typeof source !== "string") return next(/* @__PURE__ */ new Error("Cannot replace %f or %b when using an input stream"));
						pattern = pattern.replace(/%f/g, path$6.basename(source)).replace(/%b/g, path$6.basename(source, path$6.extname(source)));
					}
					next(null, pattern);
				},
				function getSize(pattern, next) {
					if (pattern.match(/%[whr]/)) {
						if (fixedSize) return next(null, pattern, fixedSize[1], fixedSize[2]);
						getMetadata(function(err, meta) {
							if (err) return next(/* @__PURE__ */ new Error("Could not determine video resolution to replace %w, %h or %r"));
							var vstream = meta.streams.reduce(function(biggest, stream) {
								if (stream.codec_type === "video" && stream.width * stream.height > biggest.width * biggest.height) return stream;
								else return biggest;
							}, {
								width: 0,
								height: 0
							});
							if (vstream.width === 0) return next(/* @__PURE__ */ new Error("No video stream in input, cannot replace %w, %h or %r"));
							var width = vstream.width;
							var height = vstream.height;
							if (fixedWidth) {
								height = height * Number(fixedWidth[1]) / width;
								width = Number(fixedWidth[1]);
							} else if (fixedHeight) {
								width = width * Number(fixedHeight[1]) / height;
								height = Number(fixedHeight[1]);
							} else if (percentSize) {
								width = width * Number(percentSize[1]) / 100;
								height = height * Number(percentSize[1]) / 100;
							}
							next(null, pattern, Math.round(width / 2) * 2, Math.round(height / 2) * 2);
						});
					} else next(null, pattern, -1, -1);
				},
				function replaceSizeTokens(pattern, width, height, next) {
					pattern = pattern.replace(/%r/g, "%wx%h").replace(/%w/g, width).replace(/%h/g, height);
					next(null, pattern);
				},
				function replaceVariableTokens(pattern, next) {
					var filenames = config.timemarks.map(function(t, i) {
						return pattern.replace(/%s/g, utils.timemarkToSeconds(t)).replace(/%(0*)i/g, function(match, padding) {
							var idx = "" + (i + 1);
							return padding.substr(0, Math.max(0, padding.length + 1 - idx.length)) + idx;
						});
					});
					self.emit("filenames", filenames);
					next(null, filenames);
				},
				function createDirectory(filenames, next) {
					fs$7.exists(config.folder, function(exists) {
						if (!exists) fs$7.mkdir(config.folder, function(err) {
							if (err) next(err);
							else next(null, filenames);
						});
						else next(null, filenames);
					});
				}
			], function runCommand(err, filenames) {
				if (err) return self.emit("error", err);
				var count = config.timemarks.length;
				var split;
				var filters = [split = {
					filter: "split",
					options: count,
					outputs: []
				}];
				if ("size" in config) {
					self.size(config.size);
					var sizeFilters = self._currentOutput.sizeFilters.get().map(function(f, i) {
						if (i > 0) f.inputs = "size" + (i - 1);
						f.outputs = "size" + i;
						return f;
					});
					split.inputs = "size" + (sizeFilters.length - 1);
					filters = sizeFilters.concat(filters);
					self._currentOutput.sizeFilters.clear();
				}
				var first = 0;
				for (var i = 0; i < count; i++) {
					var stream = "screen" + i;
					split.outputs.push(stream);
					if (i === 0) {
						first = config.timemarks[i];
						self.seekInput(first);
					}
					self.output(path$6.join(config.folder, filenames[i])).frames(1).map(stream);
					if (i > 0) self.seek(config.timemarks[i] - first);
				}
				self.complexFilter(filters);
				self.run();
			});
			return this;
		};
		/**
		* Merge (concatenate) inputs to a single file
		*
		* @method FfmpegCommand#concat
		* @category Processing
		* @aliases concatenate,mergeToFile
		*
		* @param {String|Writable} target output file or writable stream
		* @param {Object} [options] pipe options (only used when outputting to a writable stream)
		* @return FfmpegCommand
		*/
		proto.mergeToFile = proto.concatenate = proto.concat = function(target, options) {
			var fileInput = this._inputs.filter(function(input) {
				return !input.isStream;
			})[0];
			var self = this;
			this.ffprobe(this._inputs.indexOf(fileInput), function(err, data) {
				if (err) return self.emit("error", err);
				var hasAudioStreams = data.streams.some(function(stream) {
					return stream.codec_type === "audio";
				});
				var hasVideoStreams = data.streams.some(function(stream) {
					return stream.codec_type === "video";
				});
				self.output(target, options).complexFilter({
					filter: "concat",
					options: {
						n: self._inputs.length,
						v: hasVideoStreams ? 1 : 0,
						a: hasAudioStreams ? 1 : 0
					}
				}).run();
			});
			return this;
		};
	};
}));
//#endregion
//#region node_modules/fluent-ffmpeg/lib/fluent-ffmpeg.js
var require_fluent_ffmpeg$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var path$5 = __require("path");
	var util$8 = __require("util");
	var EventEmitter$7 = __require("events").EventEmitter;
	var utils = require_utils$2();
	/**
	* Create an ffmpeg command
	*
	* Can be called with or without the 'new' operator, and the 'input' parameter
	* may be specified as 'options.source' instead (or passed later with the
	* addInput method).
	*
	* @constructor
	* @param {String|ReadableStream} [input] input file path or readable stream
	* @param {Object} [options] command options
	* @param {Object} [options.logger=<no logging>] logger object with 'error', 'warning', 'info' and 'debug' methods
	* @param {Number} [options.niceness=0] ffmpeg process niceness, ignored on Windows
	* @param {Number} [options.priority=0] alias for `niceness`
	* @param {String} [options.presets="fluent-ffmpeg/lib/presets"] directory to load presets from
	* @param {String} [options.preset="fluent-ffmpeg/lib/presets"] alias for `presets`
	* @param {String} [options.stdoutLines=100] maximum lines of ffmpeg output to keep in memory, use 0 for unlimited
	* @param {Number} [options.timeout=<no timeout>] ffmpeg processing timeout in seconds
	* @param {String|ReadableStream} [options.source=<no input>] alias for the `input` parameter
	*/
	function FfmpegCommand(input, options) {
		if (!(this instanceof FfmpegCommand)) return new FfmpegCommand(input, options);
		EventEmitter$7.call(this);
		if (typeof input === "object" && !("readable" in input)) options = input;
		else {
			options = options || {};
			options.source = input;
		}
		this._inputs = [];
		if (options.source) this.input(options.source);
		this._outputs = [];
		this.output();
		var self = this;
		["_global", "_complexFilters"].forEach(function(prop) {
			self[prop] = utils.args();
		});
		options.stdoutLines = "stdoutLines" in options ? options.stdoutLines : 100;
		options.presets = options.presets || options.preset || path$5.join(__dirname, "presets");
		options.niceness = options.niceness || options.priority || 0;
		this.options = options;
		this.logger = options.logger || {
			debug: function() {},
			info: function() {},
			warn: function() {},
			error: function() {}
		};
	}
	util$8.inherits(FfmpegCommand, EventEmitter$7);
	module.exports = FfmpegCommand;
	/**
	* Clone an ffmpeg command
	*
	* This method is useful when you want to process the same input multiple times.
	* It returns a new FfmpegCommand instance with the exact same options.
	*
	* All options set _after_ the clone() call will only be applied to the instance
	* it has been called on.
	*
	* @example
	*   var command = ffmpeg('/path/to/source.avi')
	*     .audioCodec('libfaac')
	*     .videoCodec('libx264')
	*     .format('mp4');
	*
	*   command.clone()
	*     .size('320x200')
	*     .save('/path/to/output-small.mp4');
	*
	*   command.clone()
	*     .size('640x400')
	*     .save('/path/to/output-medium.mp4');
	*
	*   command.save('/path/to/output-original-size.mp4');
	*
	* @method FfmpegCommand#clone
	* @return FfmpegCommand
	*/
	FfmpegCommand.prototype.clone = function() {
		var clone = new FfmpegCommand();
		var self = this;
		clone.options = this.options;
		clone.logger = this.logger;
		clone._inputs = this._inputs.map(function(input) {
			return {
				source: input.source,
				options: input.options.clone()
			};
		});
		if ("target" in this._outputs[0]) {
			clone._outputs = [];
			clone.output();
		} else {
			clone._outputs = [clone._currentOutput = { flags: {} }];
			[
				"audio",
				"audioFilters",
				"video",
				"videoFilters",
				"sizeFilters",
				"options"
			].forEach(function(key) {
				clone._currentOutput[key] = self._currentOutput[key].clone();
			});
			if (this._currentOutput.sizeData) {
				clone._currentOutput.sizeData = {};
				utils.copy(this._currentOutput.sizeData, clone._currentOutput.sizeData);
			}
			utils.copy(this._currentOutput.flags, clone._currentOutput.flags);
		}
		["_global", "_complexFilters"].forEach(function(prop) {
			clone[prop] = self[prop].clone();
		});
		return clone;
	};
	require_inputs()(FfmpegCommand.prototype);
	require_audio()(FfmpegCommand.prototype);
	require_video()(FfmpegCommand.prototype);
	require_videosize()(FfmpegCommand.prototype);
	require_output()(FfmpegCommand.prototype);
	require_custom()(FfmpegCommand.prototype);
	require_misc()(FfmpegCommand.prototype);
	require_processor()(FfmpegCommand.prototype);
	require_capabilities()(FfmpegCommand.prototype);
	FfmpegCommand.setFfmpegPath = function(path) {
		new FfmpegCommand().setFfmpegPath(path);
	};
	FfmpegCommand.setFfprobePath = function(path) {
		new FfmpegCommand().setFfprobePath(path);
	};
	FfmpegCommand.setFlvtoolPath = function(path) {
		new FfmpegCommand().setFlvtoolPath(path);
	};
	FfmpegCommand.availableFilters = FfmpegCommand.getAvailableFilters = function(callback) {
		new FfmpegCommand().availableFilters(callback);
	};
	FfmpegCommand.availableCodecs = FfmpegCommand.getAvailableCodecs = function(callback) {
		new FfmpegCommand().availableCodecs(callback);
	};
	FfmpegCommand.availableFormats = FfmpegCommand.getAvailableFormats = function(callback) {
		new FfmpegCommand().availableFormats(callback);
	};
	FfmpegCommand.availableEncoders = FfmpegCommand.getAvailableEncoders = function(callback) {
		new FfmpegCommand().availableEncoders(callback);
	};
	require_ffprobe()(FfmpegCommand.prototype);
	FfmpegCommand.ffprobe = function(file) {
		var instance = new FfmpegCommand(file);
		instance.ffprobe.apply(instance, Array.prototype.slice.call(arguments, 1));
	};
	require_recipes()(FfmpegCommand.prototype);
}));
//#endregion
//#region src/common/utils/ffmpeg.ts
var import_fluent_ffmpeg = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = require_fluent_ffmpeg$1();
})))(), 1);
function setFFMpegPath(ffmpegPath) {
	const paths = [
		ffmpegPath,
		path.join(import.meta.dirname, "ffmpeg.exe"),
		process.env["FFMPEG_PATH"] || ""
	];
	for (const p of paths) if (fs.existsSync(p)) {
		import_fluent_ffmpeg.default.setFfmpegPath(p);
		getLogger("ffmpeg").info("set ffmpeg successfully", p);
		break;
	}
}
//#endregion
//#region node_modules/@saltify/typeproto/dist/index.mjs
var WireType = /* @__PURE__ */ function(WireType$1) {
	WireType$1[WireType$1["Varint"] = 0] = "Varint";
	WireType$1[WireType$1["Fixed64"] = 1] = "Fixed64";
	WireType$1[WireType$1["LengthDelimited"] = 2] = "LengthDelimited";
	/** @deprecated */
	WireType$1[WireType$1["StartGroup"] = 3] = "StartGroup";
	/** @deprecated */
	WireType$1[WireType$1["EndGroup"] = 4] = "EndGroup";
	WireType$1[WireType$1["Fixed32"] = 5] = "Fixed32";
	return WireType$1;
}({});
var CodedReader = class {
	buffer;
	offset;
	length;
	constructor(buffer) {
		this.buffer = buffer;
		this.offset = 0;
		this.length = buffer.length;
	}
	readByte() {
		return this.buffer[this.offset++];
	}
	readBytes(length) {
		const bytes = this.buffer.subarray(this.offset, this.offset + length);
		this.offset += length;
		return bytes;
	}
	readVarint() {
		let result = 0;
		let shift = 0;
		while (true) {
			const byte = this.readByte();
			result |= (byte & 127) << shift;
			if ((byte & 128) === 0) break;
			shift += 7;
		}
		return result >>> 0;
	}
	readVarintToBigint() {
		let result = BigInt(0);
		let shift = BigInt(0);
		while (true) {
			const byte = BigInt(this.readByte());
			result |= (byte & BigInt(127)) << shift;
			if ((byte & BigInt(128)) === BigInt(0)) break;
			shift += BigInt(7);
		}
		return result;
	}
	readFixed32() {
		const value = this.buffer.readUInt32LE(this.offset);
		this.offset += 4;
		return value;
	}
	readFixed64() {
		const low = this.readFixed32();
		const high = this.readFixed32();
		return BigInt(low) | BigInt(high) << BigInt(32);
	}
	readFloat() {
		const value = this.buffer.readFloatLE(this.offset);
		this.offset += 4;
		return value;
	}
	readDouble() {
		const value = this.buffer.readDoubleLE(this.offset);
		this.offset += 8;
		return value;
	}
	readTag() {
		const tag = this.readVarint();
		return {
			fieldNumber: tag >>> 3,
			wireType: tag & 7
		};
	}
	skip(wireType) {
		if (wireType === WireType.Varint) this.readVarint();
		else if (wireType === WireType.Fixed64) this.offset += 8;
		else if (wireType === WireType.Fixed32) this.offset += 4;
		else if (wireType === WireType.LengthDelimited) {
			const length = this.readVarint();
			this.offset += length;
		}
	}
};
var CodedWriter = class {
	buffer;
	offset;
	constructor(size) {
		this.buffer = Buffer.allocUnsafe(size);
		this.offset = 0;
	}
	writeRawByte(value) {
		this.buffer[this.offset++] = value;
	}
	writeRawBytes(bytes) {
		bytes.copy(this.buffer, this.offset);
		this.offset += bytes.length;
	}
	writeVarint(value) {
		while (value > 127) {
			this.writeRawByte(value & 127 | 128);
			value >>>= 7;
		}
		this.writeRawByte(value & 127);
	}
	writeBigVarint(value) {
		while (value > BigInt(127)) {
			this.writeRawByte(Number(value & BigInt(127) | BigInt(128)));
			value >>= BigInt(7);
		}
		this.writeRawByte(Number(value & BigInt(127)));
	}
	writeFixed32(value) {
		this.buffer.writeUInt32LE(value, this.offset);
		this.offset += 4;
	}
	writeFixed64(value) {
		const low = Number(value & BigInt(4294967295));
		const high = Number(value >> BigInt(32) & BigInt(4294967295));
		this.writeFixed32(low);
		this.writeFixed32(high);
	}
	writeFloat(value) {
		this.buffer.writeFloatLE(value, this.offset);
		this.offset += 4;
	}
	writeDouble(value) {
		this.buffer.writeDoubleLE(value, this.offset);
		this.offset += 8;
	}
	build() {
		return this.buffer;
	}
};
var MAX_UINT64 = 2n ** 64n;
var MAX_INT64 = 2n ** 63n;
var Converter;
(function(_Converter) {
	function tag(fieldNumber, wireType) {
		return fieldNumber << 3 | wireType;
	}
	_Converter.tag = tag;
	function toSigned32(value) {
		return value | 0;
	}
	_Converter.toSigned32 = toSigned32;
	function toSigned64(value) {
		return value >= MAX_INT64 ? value - MAX_UINT64 : value;
	}
	_Converter.toSigned64 = toSigned64;
	function toUnsigned32(value) {
		return value >>> 0;
	}
	_Converter.toUnsigned32 = toUnsigned32;
	function toUnsigned64(value) {
		return value < 0 ? value + MAX_UINT64 : value;
	}
	_Converter.toUnsigned64 = toUnsigned64;
	function zigzagEncode32(n) {
		return n << 1 ^ n >> 31;
	}
	_Converter.zigzagEncode32 = zigzagEncode32;
	function zigzagEncode64(n) {
		return n << BigInt(1) ^ n >> BigInt(63);
	}
	_Converter.zigzagEncode64 = zigzagEncode64;
	function zigzagDecode32(n) {
		return n >>> 1 ^ -(n & 1);
	}
	_Converter.zigzagDecode32 = zigzagDecode32;
	function zigzagDecode64(n) {
		return n >> BigInt(1) ^ -(n & BigInt(1));
	}
	_Converter.zigzagDecode64 = zigzagDecode64;
})(Converter || (Converter = {}));
var Fixed32Size = 4;
var Fixed64Size = 8;
var FloatSize = Fixed32Size;
var DoubleSize = Fixed64Size;
var ScalarDeserializerCompiler = {
	double: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / DoubleSize;
			for (let i = 0; i < count; i++) draft[key].push(reader.readDouble());
		} else draft[key].push(reader.readDouble());
	} : (draft, reader) => {
		draft[key] = reader.readDouble();
	},
	float: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / FloatSize;
			for (let i = 0; i < count; i++) draft[key].push(reader.readFloat());
		} else draft[key].push(reader.readFloat());
	} : (draft, reader) => {
		draft[key] = reader.readFloat();
	},
	int64: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(Converter.toSigned64(reader.readVarintToBigint()));
		} else draft[key].push(Converter.toSigned64(reader.readVarintToBigint()));
	} : (draft, reader) => {
		draft[key] = Converter.toSigned64(reader.readVarintToBigint());
	},
	uint64: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(reader.readVarintToBigint());
		} else draft[key].push(reader.readVarintToBigint());
	} : (draft, reader) => {
		draft[key] = reader.readVarintToBigint();
	},
	int32: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(Converter.toSigned32(reader.readVarint()));
		} else draft[key].push(Converter.toSigned32(reader.readVarint()));
	} : (draft, reader) => {
		draft[key] = Converter.toSigned32(reader.readVarint());
	},
	fixed64: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / Fixed64Size;
			for (let i = 0; i < count; i++) draft[key].push(reader.readFixed64());
		} else draft[key].push(reader.readFixed64());
	} : (draft, reader) => {
		draft[key] = reader.readFixed64();
	},
	fixed32: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / Fixed32Size;
			for (let i = 0; i < count; i++) draft[key].push(reader.readFixed32());
		} else draft[key].push(reader.readFixed32());
	} : (draft, reader) => {
		draft[key] = reader.readFixed32();
	},
	bool: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint();
			for (let i = 0; i < count; i++) draft[key].push(reader.readVarint() !== 0);
		} else draft[key].push(reader.readVarint() !== 0);
	} : (draft, reader) => {
		draft[key] = reader.readVarint() !== 0;
	},
	string: (key, spec) => spec.repeated ? (draft, reader) => {
		draft[key].push(reader.readBytes(reader.readVarint()).toString());
	} : (draft, reader) => {
		draft[key] = reader.readBytes(reader.readVarint()).toString();
	},
	bytes: (key, spec) => spec.repeated ? (draft, reader) => {
		draft[key].push(reader.readBytes(reader.readVarint()));
	} : (draft, reader) => {
		draft[key] = reader.readBytes(reader.readVarint());
	},
	uint32: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(reader.readVarint());
		} else draft[key].push(reader.readVarint());
	} : (draft, reader) => {
		draft[key] = reader.readVarint();
	},
	sfixed32: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / Fixed32Size;
			for (let i = 0; i < count; i++) draft[key].push(Converter.toSigned32(reader.readFixed32()));
		} else draft[key].push(Converter.toSigned32(reader.readFixed32()));
	} : (draft, reader) => {
		draft[key] = Converter.toSigned32(reader.readFixed32());
	},
	sfixed64: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const count = reader.readVarint() / Fixed64Size;
			for (let i = 0; i < count; i++) draft[key].push(Converter.toSigned64(reader.readFixed64()));
		} else draft[key].push(Converter.toSigned64(reader.readFixed64()));
	} : (draft, reader) => {
		draft[key] = Converter.toSigned64(reader.readFixed64());
	},
	sint32: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(Converter.zigzagDecode32(reader.readVarint()));
		} else draft[key].push(Converter.zigzagDecode32(reader.readVarint()));
	} : (draft, reader) => {
		draft[key] = Converter.zigzagDecode32(reader.readVarint());
	},
	sint64: (key, spec) => spec.repeated ? (draft, reader, wireType) => {
		if (wireType === WireType.LengthDelimited) {
			const length = reader.readVarint();
			const endOffset = reader.offset + length;
			while (reader.offset < endOffset) draft[key].push(Converter.zigzagDecode64(reader.readVarintToBigint()));
		} else draft[key].push(Converter.zigzagDecode64(reader.readVarintToBigint()));
	} : (draft, reader) => {
		draft[key] = Converter.zigzagDecode64(reader.readVarintToBigint());
	}
};
var kTag = Symbol("Cached Tag");
var kTagLength = Symbol("Cached Tag Length");
function defineSerializer(s) {
	return s;
}
var ScalarSerializerCompiler = {
	double: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * DoubleSize;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeDouble(value);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeDouble(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeDouble(data);
	}),
	float: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * FloatSize;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeFloat(value);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeFloat(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeFloat(data);
	}),
	int64: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer, lengthCache) => {
		const length = lengthCache.get(data);
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeBigVarint(Converter.toUnsigned64(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeBigVarint(Converter.toUnsigned64(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeBigVarint(Converter.toUnsigned64(data));
	}),
	uint64: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer, lengthCache) => {
		const length = lengthCache.get(data);
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeBigVarint(value);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeBigVarint(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeBigVarint(data);
	}),
	int32: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer, lengthCache) => {
		const length = lengthCache.get(data);
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeVarint(Converter.toUnsigned32(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeVarint(Converter.toUnsigned32(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(Converter.toUnsigned32(data));
	}),
	fixed64: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * Fixed64Size;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeFixed64(value);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeFixed64(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeFixed64(data);
	}),
	fixed32: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * Fixed32Size;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeFixed32(value);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeFixed32(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeFixed32(data);
	}),
	bool: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeRawByte(value ? 1 : 0);
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeRawByte(value ? 1 : 0);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeRawByte(data ? 1 : 0);
	}),
	string: (spec) => spec.repeated ? defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeVarint(Buffer.byteLength(value));
			writer.writeRawBytes(Buffer.from(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(Buffer.byteLength(data));
		writer.writeRawBytes(Buffer.from(data));
	}),
	bytes: (spec) => spec.repeated ? defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeVarint(value.length);
			writer.writeRawBytes(value);
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(data.length);
		writer.writeRawBytes(data);
	}),
	uint32: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer, lengthCache) => {
		const length = lengthCache.get(data);
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeVarint(Converter.toUnsigned32(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeVarint(Converter.toUnsigned32(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(Converter.toUnsigned32(data));
	}),
	sfixed32: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * Fixed32Size;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeFixed32(Converter.toUnsigned32(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeFixed32(Converter.toUnsigned32(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeFixed32(Converter.toUnsigned32(data));
	}),
	sfixed64: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * Fixed64Size;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeFixed64(Converter.toUnsigned64(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeFixed64(Converter.toUnsigned64(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeFixed64(Converter.toUnsigned64(data));
	}),
	sint32: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer) => {
		const length = data.length * Fixed32Size;
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeVarint(Converter.zigzagEncode32(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeVarint(Converter.zigzagEncode32(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(Converter.zigzagEncode32(data));
	}),
	sint64: (spec) => spec.repeated ? spec.packed ? defineSerializer((data, writer, lengthCache) => {
		const length = lengthCache.get(data);
		writer.writeVarint(spec[kTag]);
		writer.writeVarint(length);
		for (const value of data) writer.writeBigVarint(Converter.zigzagEncode64(value));
	}) : defineSerializer((data, writer) => {
		for (const value of data) {
			writer.writeVarint(spec[kTag]);
			writer.writeBigVarint(Converter.zigzagEncode64(value));
		}
	}) : defineSerializer((data, writer) => {
		writer.writeVarint(spec[kTag]);
		writer.writeBigVarint(Converter.zigzagEncode64(data));
	})
};
var VARINT32_BYTE_2 = 128;
var VARINT32_BYTE_3 = 16384;
var VARINT32_BYTE_4 = 2097152;
var VARINT32_BYTE_5 = 268435456;
var VARINT64_BYTE_2 = BigInt(1) << BigInt(7);
var VARINT64_BYTE_3 = BigInt(1) << BigInt(14);
var VARINT64_BYTE_4 = BigInt(1) << BigInt(21);
var VARINT64_BYTE_5 = BigInt(1) << BigInt(28);
var VARINT64_BYTE_6 = BigInt(1) << BigInt(35);
var VARINT64_BYTE_7 = BigInt(1) << BigInt(42);
var VARINT64_BYTE_8 = BigInt(1) << BigInt(49);
var VARINT64_BYTE_9 = BigInt(1) << BigInt(56);
var VARINT64_BYTE_10 = BigInt(1) << BigInt(63);
var SizeOf;
(function(_SizeOf) {
	function varint32(value) {
		value >>>= 0;
		if (value < VARINT32_BYTE_2) return 1;
		if (value < VARINT32_BYTE_3) return 2;
		if (value < VARINT32_BYTE_4) return 3;
		if (value < VARINT32_BYTE_5) return 4;
		return 5;
	}
	_SizeOf.varint32 = varint32;
	function varint64(value) {
		if (value < VARINT64_BYTE_2) return 1;
		if (value < VARINT64_BYTE_3) return 2;
		if (value < VARINT64_BYTE_4) return 3;
		if (value < VARINT64_BYTE_5) return 4;
		if (value < VARINT64_BYTE_6) return 5;
		if (value < VARINT64_BYTE_7) return 6;
		if (value < VARINT64_BYTE_8) return 7;
		if (value < VARINT64_BYTE_9) return 8;
		if (value < VARINT64_BYTE_10) return 9;
		return 10;
	}
	_SizeOf.varint64 = varint64;
})(SizeOf || (SizeOf = {}));
function sumVarint32Array(data, mapper) {
	let total = 0;
	if (mapper) for (let i = 0; i < data.length; i++) total += SizeOf.varint32(mapper(data[i]));
	else for (let i = 0; i < data.length; i++) total += SizeOf.varint32(data[i]);
	return total;
}
function sumVarint64Array(data, mapper) {
	let total = 0;
	if (mapper) for (let i = 0; i < data.length; i++) total += SizeOf.varint64(mapper(data[i]));
	else for (let i = 0; i < data.length; i++) total += SizeOf.varint64(data[i]);
	return total;
}
function sumLengthDelimited(data, sizeOfItem) {
	let total = 0;
	for (let i = 0; i < data.length; i++) {
		const itemSize = sizeOfItem(data[i]);
		total += SizeOf.varint32(itemSize) + itemSize;
	}
	return total;
}
var ScalarSizeCalculatorCompiler = {
	double: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * DoubleSize;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (DoubleSize + spec[kTagLength]) : () => spec[kTagLength] + DoubleSize,
	float: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * FloatSize;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (FloatSize + spec[kTagLength]) : () => spec[kTagLength] + FloatSize,
	int64: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint64Array(data, Converter.toUnsigned64);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint64Array(data, Converter.toUnsigned64) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint64(Converter.toUnsigned64(data)),
	uint64: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint64Array(data);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint64Array(data) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint64(data),
	int32: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint32Array(data, Converter.toUnsigned32);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint32Array(data, Converter.toUnsigned32) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint32(Converter.toUnsigned32(data)),
	fixed64: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * Fixed64Size;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (Fixed64Size + spec[kTagLength]) : () => spec[kTagLength] + Fixed64Size,
	fixed32: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * Fixed32Size;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (Fixed32Size + spec[kTagLength]) : () => spec[kTagLength] + Fixed32Size,
	bool: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (1 + spec[kTagLength]) : () => spec[kTagLength] + 1,
	string: (spec) => spec.repeated ? (data) => {
		return sumLengthDelimited(data, (item) => Buffer.byteLength(item)) + spec[kTagLength] * data.length;
	} : (data) => {
		const itemSize = Buffer.byteLength(data);
		return spec[kTagLength] + SizeOf.varint32(itemSize) + itemSize;
	},
	bytes: (spec) => spec.repeated ? (data) => {
		return sumLengthDelimited(data, (item) => item.length) + spec[kTagLength] * data.length;
	} : (data) => {
		const itemSize = data.length;
		return spec[kTagLength] + SizeOf.varint32(itemSize) + itemSize;
	},
	uint32: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint32Array(data);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint32Array(data) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint32(data),
	sfixed32: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * Fixed32Size;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (Fixed32Size + spec[kTagLength]) : () => spec[kTagLength] + Fixed32Size,
	sfixed64: (spec) => spec.repeated ? spec.packed ? (data) => {
		const bodySize = data.length * Fixed64Size;
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => data.length * (Fixed64Size + spec[kTagLength]) : () => spec[kTagLength] + Fixed64Size,
	sint32: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint32Array(data, Converter.zigzagEncode32);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint32Array(data, Converter.zigzagEncode32) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint32(Converter.zigzagEncode32(data)),
	sint64: (spec) => spec.repeated ? spec.packed ? (data, cache) => {
		const bodySize = sumVarint64Array(data, Converter.zigzagEncode64);
		cache.set(data, bodySize);
		return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
	} : (data) => sumVarint64Array(data, Converter.zigzagEncode64) + spec[kTagLength] * data.length : (data) => spec[kTagLength] + SizeOf.varint64(Converter.zigzagEncode64(data))
};
var ScalarTypeDefaultValue = {
	double: 0,
	float: 0,
	int64: BigInt(0),
	uint64: BigInt(0),
	int32: 0,
	fixed64: BigInt(0),
	fixed32: 0,
	bool: false,
	string: "",
	bytes: Buffer.alloc(0),
	uint32: 0,
	sfixed32: 0,
	sfixed64: BigInt(0),
	sint32: 0,
	sint64: BigInt(0)
};
function isMapFieldType(type) {
	return Array.isArray(type);
}
function isMessageValueType(type) {
	return typeof type === "function" || typeof type === "object" && type !== null && !Array.isArray(type);
}
function isMessageFieldType(type) {
	return typeof type === "function" || typeof type === "object" && type !== null && !Array.isArray(type);
}
function compileScalarSizeCalculator(type, spec) {
	return ScalarSizeCalculatorCompiler[type](spec);
}
function compileScalarSerializer(type, spec) {
	return ScalarSerializerCompiler[type](spec);
}
function compileScalarDeserializer(type, key, spec) {
	return ScalarDeserializerCompiler[type](key, spec);
}
var ProtoMessage = class ProtoMessage {
	static compiledMessages = /* @__PURE__ */ new WeakMap();
	fieldSizeCalculators = /* @__PURE__ */ new Map();
	fieldSerializers = /* @__PURE__ */ new Map();
	fieldDefaultValues = [];
	fieldDeserializers = /* @__PURE__ */ new Map();
	constructor(model) {
		this.model = model;
		for (const key in model) {
			const spec = model[key];
			const type = spec.type;
			if (isMapFieldType(type)) {
				const [keyType, valueType] = type;
				const keySpec = ProtoField(1, keyType);
				const valueSpec = ProtoField(2, valueType);
				const keySizeCalculator = compileScalarSizeCalculator(keyType, keySpec);
				const keySerializer = compileScalarSerializer(keyType, keySpec);
				const keyDeserializer = compileScalarDeserializer(keyType, "key", keySpec);
				let valueSizeCalculator;
				let valueSerializer;
				let valueDeserializer;
				let createValueDefault;
				if (isMessageValueType(valueType)) {
					let modelOrLazy;
					const resolveValueModel = () => {
						if (modelOrLazy === void 0) if (typeof valueType === "function") {
							const modelOrMessage = valueType();
							if (modelOrMessage instanceof ProtoMessage) modelOrLazy = modelOrMessage.model;
							else modelOrLazy = modelOrMessage;
						} else if (valueType instanceof ProtoMessage) modelOrLazy = valueType.model;
						else modelOrLazy = valueType;
						return modelOrLazy;
					};
					valueSizeCalculator = (data, cache) => {
						const message = ProtoMessage.of(resolveValueModel());
						const bodySize = cache.get(data) ?? message.calculateSerializedSize(data, cache);
						return valueSpec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
					};
					valueSerializer = (data, writer, cache) => {
						const message = ProtoMessage.of(resolveValueModel());
						const bodySize = cache.get(data) ?? message.calculateSerializedSize(data, cache);
						writer.writeVarint(valueSpec[kTag]);
						writer.writeVarint(bodySize);
						message.write(data, writer, cache);
					};
					valueDeserializer = (draft, reader) => {
						const message = ProtoMessage.of(resolveValueModel());
						const item = message.createDraft();
						const length = reader.readVarint();
						const offset = reader.offset;
						message.read(item, reader, offset + length);
						draft.value = item;
					};
					createValueDefault = () => ProtoMessage.of(resolveValueModel()).createDraft();
				} else {
					const scalarValueType = valueType;
					const scalarValueSpec = valueSpec;
					valueSizeCalculator = compileScalarSizeCalculator(scalarValueType, scalarValueSpec);
					valueSerializer = compileScalarSerializer(scalarValueType, scalarValueSpec);
					valueDeserializer = compileScalarDeserializer(scalarValueType, "value", scalarValueSpec);
					createValueDefault = () => ScalarTypeDefaultValue[valueType];
				}
				this.fieldSizeCalculators.set(key, (data, cache) => {
					let size = 0;
					for (const [entryKey, entryValue] of data) {
						const bodySize = keySizeCalculator(entryKey, cache) + valueSizeCalculator(entryValue, cache);
						size += spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
					}
					return size;
				});
				this.fieldSerializers.set(key, (data, writer, cache) => {
					for (const [entryKey, entryValue] of data) {
						const bodySize = keySizeCalculator(entryKey, cache) + valueSizeCalculator(entryValue, cache);
						writer.writeVarint(spec[kTag]);
						writer.writeVarint(bodySize);
						keySerializer(entryKey, writer, cache);
						valueSerializer(entryValue, writer, cache);
					}
				});
				if (spec.optional) this.fieldDefaultValues.push([key, void 0]);
				else this.fieldDefaultValues.push([key, () => /* @__PURE__ */ new Map()]);
				this.fieldDeserializers.set(spec.fieldNumber, (draft, reader) => {
					const length = reader.readVarint();
					const offset = reader.offset;
					const entryDraft = {
						key: ScalarTypeDefaultValue[keyType],
						value: createValueDefault()
					};
					while (reader.offset < offset + length) {
						const { fieldNumber, wireType } = reader.readTag();
						if (fieldNumber === 1) keyDeserializer(entryDraft, reader, wireType);
						else if (fieldNumber === 2) valueDeserializer(entryDraft, reader, wireType);
						else reader.skip(wireType);
					}
					if (draft[key] === void 0) draft[key] = /* @__PURE__ */ new Map();
					draft[key].set(entryDraft.key, entryDraft.value);
				});
			} else if (isMessageFieldType(type)) {
				const messageType = type;
				let modelOrLazy;
				function resolveModel() {
					if (modelOrLazy === void 0) if (typeof messageType === "function") {
						const modelOrMessage = messageType();
						if (modelOrMessage instanceof ProtoMessage) modelOrLazy = modelOrMessage.model;
						else modelOrLazy = modelOrMessage;
					} else if (messageType instanceof ProtoMessage) modelOrLazy = messageType.model;
					else modelOrLazy = messageType;
					return modelOrLazy;
				}
				if (spec.repeated) {
					this.fieldSizeCalculators.set(key, (data, cache) => {
						let size = spec[kTagLength] * data.length;
						const message = ProtoMessage.of(resolveModel());
						for (const item of data) {
							const bodySize = message.calculateSerializedSize(item, cache);
							cache.set(item, bodySize);
							size += SizeOf.varint32(bodySize) + bodySize;
						}
						return size;
					});
					this.fieldSerializers.set(key, (data, writer, cache) => {
						const message = ProtoMessage.of(resolveModel());
						for (const item of data) {
							const bodySize = cache.get(item);
							writer.writeVarint(spec[kTag]);
							writer.writeVarint(bodySize);
							message.write(item, writer, cache);
						}
					});
					this.fieldDefaultValues.push([key, () => []]);
					this.fieldDeserializers.set(spec.fieldNumber, (draft, reader) => {
						const message = ProtoMessage.of(resolveModel());
						const item = message.createDraft();
						const length = reader.readVarint();
						const offset = reader.offset;
						message.read(item, reader, offset + length);
						draft[key].push(item);
					});
				} else {
					this.fieldSizeCalculators.set(key, (data, cache) => {
						const bodySize = ProtoMessage.of(resolveModel()).calculateSerializedSize(data, cache);
						return spec[kTagLength] + SizeOf.varint32(bodySize) + bodySize;
					});
					this.fieldSerializers.set(key, (data, writer, cache) => {
						const message = ProtoMessage.of(resolveModel());
						const bodySize = cache.get(data);
						writer.writeVarint(spec[kTag]);
						writer.writeVarint(bodySize);
						message.write(data, writer, cache);
					});
					if (spec.optional) this.fieldDefaultValues.push([key, void 0]);
					else this.fieldDefaultValues.push([key, () => {
						return ProtoMessage.of(resolveModel()).createDraft();
					}]);
					this.fieldDeserializers.set(spec.fieldNumber, (draft, reader) => {
						const message = ProtoMessage.of(resolveModel());
						const item = message.createDraft();
						const length = reader.readVarint();
						const offset = reader.offset;
						message.read(item, reader, offset + length);
						draft[key] = item;
					});
				}
			} else {
				const scalarType = type;
				const scalarSpec = spec;
				this.fieldSizeCalculators.set(key, compileScalarSizeCalculator(scalarType, scalarSpec));
				this.fieldSerializers.set(key, compileScalarSerializer(scalarType, scalarSpec));
				if (spec.repeated) this.fieldDefaultValues.push([key, () => []]);
				else if (spec.optional) this.fieldDefaultValues.push([key, void 0]);
				else this.fieldDefaultValues.push([key, ScalarTypeDefaultValue[scalarType]]);
				this.fieldDeserializers.set(spec.fieldNumber, compileScalarDeserializer(scalarType, key, scalarSpec));
			}
		}
	}
	calculateSerializedSize(message, cache) {
		let size = 0;
		for (const key in message) {
			const value = message[key];
			if (value === void 0) continue;
			const addSize = this.fieldSizeCalculators.get(key)(value, cache);
			size += addSize;
		}
		cache.set(message, size);
		return size;
	}
	write(message, writer, cache) {
		for (const key in message) {
			const value = message[key];
			if (value === void 0) continue;
			this.fieldSerializers.get(key)(value, writer, cache);
		}
	}
	createDraft() {
		const draft = {};
		for (const [key, valueOrSupplier] of this.fieldDefaultValues) draft[key] = typeof valueOrSupplier === "function" ? valueOrSupplier() : valueOrSupplier;
		return draft;
	}
	read(draft, reader, limit = reader.length) {
		while (reader.offset < limit) {
			const { fieldNumber, wireType } = reader.readTag();
			if (!this.fieldDeserializers.has(fieldNumber)) {
				reader.skip(wireType);
				continue;
			}
			this.fieldDeserializers.get(fieldNumber)(draft, reader, wireType);
		}
	}
	encode(message) {
		const cache = /* @__PURE__ */ new WeakMap();
		const writer = new CodedWriter(this.calculateSerializedSize(message, cache));
		this.write(message, writer, cache);
		return writer.build();
	}
	decode(buffer) {
		const reader = new CodedReader(buffer);
		const draft = this.createDraft();
		this.read(draft, reader);
		return draft;
	}
	static of(model) {
		let message = ProtoMessage.compiledMessages.get(model);
		if (message === void 0) {
			message = new ProtoMessage(model);
			ProtoMessage.compiledMessages.set(model, message);
		}
		return message;
	}
};
var ScalarTypeToWireType = {
	double: WireType.Fixed64,
	float: WireType.Fixed32,
	int64: WireType.Varint,
	uint64: WireType.Varint,
	int32: WireType.Varint,
	fixed64: WireType.Fixed64,
	fixed32: WireType.Fixed32,
	bool: WireType.Varint,
	string: WireType.LengthDelimited,
	bytes: WireType.LengthDelimited,
	uint32: WireType.Varint,
	sfixed32: WireType.Fixed32,
	sfixed64: WireType.Fixed64,
	sint32: WireType.Varint,
	sint64: WireType.Varint
};
function ProtoField(fieldNumber, type, modifier, options) {
	if (isMapFieldType(type)) {
		const [keyType, valueType] = type;
		if (!MapKeyWireTypes.has(keyType)) throw new Error(`Unsupported map key type: ${String(keyType)}`);
		if (isMapFieldType(valueType)) throw new Error("Map values cannot be map types.");
		if (modifier === "repeated") throw new Error("Map fields cannot be repeated.");
		if (options?.packed !== void 0) throw new Error("Map fields cannot be packed.");
	}
	if (modifier === "repeated" && options?.packed === void 0) options = {
		...options,
		packed: true
	};
	const tag = Converter.tag(fieldNumber, isMapFieldType(type) || isMessageFieldType(type) ? WireType.LengthDelimited : options?.packed ? WireType.LengthDelimited : ScalarTypeToWireType[type]);
	return {
		fieldNumber,
		type,
		optional: modifier === "optional",
		repeated: modifier === "repeated",
		packed: options?.packed,
		[kTag]: tag,
		[kTagLength]: SizeOf.varint32(tag)
	};
}
var MapKeyWireTypes = /* @__PURE__ */ new Set([
	"int32",
	"int64",
	"uint32",
	"uint64",
	"fixed32",
	"fixed64",
	"sfixed32",
	"sfixed64",
	"sint32",
	"sint64",
	"bool",
	"string"
]);
function hasBuffer() {
	return typeof globalThis !== "undefined" && typeof globalThis.Buffer !== "undefined" && typeof globalThis.Buffer.from === "function";
}
if (!hasBuffer()) throw new Error("Buffer is not available in this environment. TypeProto requires Buffer API support.");
//#endregion
//#region src/ntqqapi/proto/action.ts
var Action;
(function(_Action) {
	const LongMsgPeer = ProtoMessage.of({ uid: ProtoField(2, "string") });
	const LongMsgSettings = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		field2: ProtoField(2, "uint32"),
		field3: ProtoField(3, "uint32"),
		field4: ProtoField(4, "uint32")
	});
	_Action.SendLongMsgReq = ProtoMessage.of({
		info: ProtoField(2, {
			type: ProtoField(1, "uint32"),
			peer: ProtoField(2, LongMsgPeer),
			groupCode: ProtoField(3, "uint32"),
			payload: ProtoField(4, "bytes")
		}),
		settings: ProtoField(15, LongMsgSettings)
	});
	_Action.SendLongMsgResp = ProtoMessage.of({
		result: ProtoField(2, { resId: ProtoField(3, "string") }),
		settings: ProtoField(15, LongMsgSettings)
	});
	_Action.PullPicsReq = ProtoMessage.of({
		uin: ProtoField(2, "uint32"),
		field3: ProtoField(3, "uint32"),
		word: ProtoField(6, "string"),
		word2: ProtoField(7, "string"),
		field8: ProtoField(8, "uint32"),
		field9: ProtoField(9, "uint32"),
		field14: ProtoField(14, "uint32")
	});
	_Action.PullPicsResp = ProtoMessage.of({ info: ProtoField(3, { url: ProtoField(5, "string") }, "repeated") });
	_Action.RecvLongMsgReq = ProtoMessage.of({
		info: ProtoField(1, {
			peer: ProtoField(1, LongMsgPeer),
			resId: ProtoField(2, "string"),
			acquire: ProtoField(3, "bool")
		}),
		settings: ProtoField(15, LongMsgSettings)
	});
	_Action.RecvLongMsgResp = ProtoMessage.of({
		result: ProtoField(1, {
			resId: ProtoField(3, "string"),
			payload: ProtoField(4, "bytes")
		}),
		settings: ProtoField(15, LongMsgSettings)
	});
	_Action.FetchUserLoginDaysReq = ProtoMessage.of({
		field2: ProtoField(2, "uint32"),
		json: ProtoField(3, "string")
	});
	_Action.FetchUserLoginDaysResp = ProtoMessage.of({ json: ProtoField(4, "string") });
	_Action.SsoGetGroupMsgReq = ProtoMessage.of({
		groupInfo: ProtoField(1, {
			groupCode: ProtoField(1, "uint32"),
			startSequence: ProtoField(2, "uint32"),
			endSequence: ProtoField(3, "uint32")
		}),
		filter: ProtoField(2, "uint32")
	});
	_Action.SsoGetGroupMsgResp = ProtoMessage.of({
		retcode: ProtoField(1, "uint32"),
		errorMsg: ProtoField(2, "string", "optional"),
		body: ProtoField(3, {
			groupCode: ProtoField(3, "uint32"),
			startSequence: ProtoField(4, "uint32"),
			endSequence: ProtoField(5, "uint32"),
			messages: ProtoField(6, "bytes", "repeated")
		})
	});
	_Action.SsoGetC2CMsgReq = ProtoMessage.of({
		peerUid: ProtoField(2, "string"),
		startSequence: ProtoField(3, "uint32"),
		endSequence: ProtoField(4, "uint32")
	});
	_Action.SsoGetC2CMsgResp = ProtoMessage.of({
		retcode: ProtoField(1, "uint32"),
		errorMsg: ProtoField(2, "string", "optional"),
		messages: ProtoField(7, "bytes", "repeated")
	});
	_Action.SsoGetRoamMsgReq = ProtoMessage.of({
		peerUid: ProtoField(1, "string"),
		time: ProtoField(2, "uint32"),
		random: ProtoField(3, "uint32"),
		count: ProtoField(4, "uint32"),
		direction: ProtoField(5, "uint32")
	});
	_Action.SsoGetRoamMsgResp = ProtoMessage.of({
		peerUid: ProtoField(3, "string", "optional"),
		isComplete: ProtoField(4, "bool", "optional"),
		timestamp: ProtoField(5, "uint32", "optional"),
		random: ProtoField(6, "uint32", "optional"),
		messages: ProtoField(7, "bytes", "repeated")
	});
	_Action.SsoGroupRecallMsgReq = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		groupCode: ProtoField(2, "uint32"),
		info: ProtoField(3, { sequence: ProtoField(1, "uint32") })
	});
	_Action.SsoC2CRecallMsgReq = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		targetUid: ProtoField(3, "string"),
		info: ProtoField(4, {
			/** client 发送时自造的 10000-99999 临时号（PbSendMsg 时塞的那个 clientSequence） */
			clientSequence: ProtoField(1, "uint32"),
			/** client 发送时自造的 32-bit random（双端一致） */
			random: ProtoField(2, "uint32"),
			/** (0x01000000<<32) | random */
			messageUid: ProtoField(3, "uint64"),
			/** PbSendMsgResp.sendTime */
			timestamp: ProtoField(4, "uint32"),
			field5: ProtoField(5, "uint32"),
			/** = PbSendMsgResp.c2cMsgSeq (server 给这条 c2c 消息分配的 c2cMsgSeq，双端一致) */
			c2cMsgSeq: ProtoField(6, "uint32")
		}),
		field5: ProtoField(5, {
			field1: ProtoField(1, "uint32"),
			field2: ProtoField(2, "uint32")
		}),
		field6: ProtoField(6, "uint32")
	});
	_Action.SetStatusReq = ProtoMessage.of({
		status: ProtoField(1, "uint32"),
		extStatus: ProtoField(2, "uint32"),
		batteryStatus: ProtoField(3, "uint32"),
		customExt: ProtoField(4, {
			faceId: ProtoField(1, "uint32"),
			text: ProtoField(2, "string"),
			field3: ProtoField(3, "uint32")
		}, "optional")
	});
	_Action.SetStatusResp = ProtoMessage.of({
		retCode: ProtoField(1, "uint32"),
		message: ProtoField(2, "string")
	});
	const QunAlbumPhotoUrl = ProtoMessage.of({
		url: ProtoField(1, "string"),
		width: ProtoField(2, "uint32"),
		height: ProtoField(3, "uint32")
	});
	const QunAlbumThumbnail = ProtoMessage.of({
		spec: ProtoField(1, "uint32"),
		url: ProtoField(2, QunAlbumPhotoUrl)
	});
	const QunAlbumImage = ProtoMessage.of({
		lloc: ProtoField(3, "string"),
		photoUrl: ProtoField(4, QunAlbumThumbnail, "repeated"),
		defaultUrl: ProtoField(5, QunAlbumPhotoUrl, "optional")
	});
	const QunAlbumCover = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		image: ProtoField(2, QunAlbumImage, "optional")
	});
	const QunAlbumCreator = ProtoMessage.of({
		nick: ProtoField(2, "string"),
		uin: ProtoField(13, "string")
	});
	const QunAlbumRecord = ProtoMessage.of({
		albumId: ProtoField(1, "string"),
		owner: ProtoField(2, "string"),
		name: ProtoField(3, "string"),
		desc: ProtoField(4, "string"),
		createTime: ProtoField(5, "uint32"),
		modifyTime: ProtoField(6, "uint32"),
		lastUploadTime: ProtoField(7, "uint32"),
		uploadNumber: ProtoField(8, "uint32"),
		cover: ProtoField(9, QunAlbumCover, "optional"),
		creator: ProtoField(10, QunAlbumCreator, "optional")
	});
	const QunAlbumMetaHeader = ProtoMessage.of({
		name: ProtoField(1, "string"),
		value: ProtoField(2, "string")
	});
	const QunAlbumReqBody = ProtoMessage.of({
		groupCode: ProtoField(1, "string"),
		albumId: ProtoField(2, "bytes")
	});
	_Action.GetAlbumListReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		field2: ProtoField(2, "bytes"),
		field3: ProtoField(3, "bytes"),
		body: ProtoField(4, QunAlbumReqBody),
		sessionId: ProtoField(5, "string"),
		headers: ProtoField(10, QunAlbumMetaHeader, "repeated")
	});
	_Action.GetAlbumListResp = ProtoMessage.of({
		retCode: ProtoField(2, "uint32"),
		retMsg: ProtoField(3, "string"),
		body: ProtoField(4, { albums: ProtoField(1, QunAlbumRecord, "repeated") }, "optional")
	});
	_Action.AddAlbumReq = ProtoMessage.of({
		requestId: ProtoField(1, "uint32"),
		field2: ProtoField(2, "bytes"),
		field3: ProtoField(3, "bytes"),
		body: ProtoField(4, { info: ProtoField(1, {
			groupCode: ProtoField(2, "string"),
			name: ProtoField(3, "string"),
			desc: ProtoField(4, "string"),
			field5: ProtoField(5, "uint32")
		}) }),
		sessionId: ProtoField(5, "string"),
		headers: ProtoField(10, QunAlbumMetaHeader, "repeated")
	});
	_Action.AddAlbumResp = ProtoMessage.of({
		requestId: ProtoField(1, "uint32"),
		retCode: ProtoField(2, "uint32"),
		retMsg: ProtoField(3, "string"),
		body: ProtoField(4, { info: ProtoField(1, {
			albumId: ProtoField(1, "string"),
			groupCode: ProtoField(2, "string"),
			name: ProtoField(3, "string"),
			desc: ProtoField(4, "string")
		}) }, "optional")
	});
	_Action.DeleteAlbumReq = ProtoMessage.of({
		requestId: ProtoField(1, "uint32"),
		field2: ProtoField(2, "bytes"),
		field3: ProtoField(3, "bytes"),
		body: ProtoField(4, {
			groupCode: ProtoField(1, "string"),
			albumId: ProtoField(2, "string")
		}),
		sessionId: ProtoField(5, "string"),
		headers: ProtoField(10, QunAlbumMetaHeader, "repeated")
	});
	_Action.DeleteAlbumResp = ProtoMessage.of({
		retCode: ProtoField(2, "uint32"),
		retMsg: ProtoField(3, "string")
	});
	const QunMediaImage = ProtoMessage.of({
		lloc: ProtoField(3, "string"),
		photoUrl: ProtoField(4, QunAlbumThumbnail, "repeated"),
		defaultUrl: ProtoField(5, QunAlbumPhotoUrl, "optional")
	});
	const QunMediaVideo = ProtoMessage.of({
		id: ProtoField(1, "string"),
		url: ProtoField(2, "string"),
		cover: ProtoField(3, {
			lloc: ProtoField(3, "string"),
			photoUrl: ProtoField(4, QunAlbumThumbnail, "repeated"),
			defaultUrl: ProtoField(5, QunAlbumPhotoUrl, "optional")
		}),
		width: ProtoField(4, "uint32"),
		height: ProtoField(5, "uint32"),
		videoTime: ProtoField(6, "uint32"),
		videoUrl: ProtoField(7, {
			spec: ProtoField(1, "uint32"),
			url: ProtoField(2, {
				url: ProtoField(1, "string"),
				width: ProtoField(2, "uint32"),
				height: ProtoField(3, "uint32")
			})
		}, "repeated")
	});
	const QunMediaItem = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		image: ProtoField(2, QunMediaImage, "optional"),
		video: ProtoField(3, QunMediaVideo, "optional"),
		desc: ProtoField(4, "string"),
		uploader: ProtoField(6, "string"),
		batchId: ProtoField(7, "uint32"),
		uploadTime: ProtoField(8, "uint32"),
		like: ProtoField(10, { key: ProtoField(1, "string") }, "optional")
	});
	_Action.GetMediaListReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		field2: ProtoField(2, "bytes"),
		field3: ProtoField(3, "bytes"),
		body: ProtoField(4, {
			groupCode: ProtoField(1, "string"),
			albumId: ProtoField(2, "string"),
			field3: ProtoField(3, "uint32"),
			field4: ProtoField(4, "bytes"),
			attachInfo: ProtoField(5, "string")
		}),
		sessionId: ProtoField(5, "string"),
		headers: ProtoField(10, QunAlbumMetaHeader, "repeated")
	});
	_Action.GetMediaListResp = ProtoMessage.of({
		retCode: ProtoField(2, "uint32"),
		retMsg: ProtoField(3, "string"),
		body: ProtoField(4, {
			album: ProtoField(1, QunAlbumRecord, "optional"),
			mediaList: ProtoField(3, QunMediaItem, "repeated"),
			nextAttachInfo: ProtoField(5, "string"),
			nextHasMore: ProtoField(7, "bool")
		}, "optional")
	});
	_Action.SsoGetPeerSeqReq = ProtoMessage.of({ peerUid: ProtoField(1, "string") });
	_Action.SsoGetPeerSeqResp = ProtoMessage.of({
		retCode: ProtoField(1, "uint32"),
		retMsg: ProtoField(2, "string"),
		/** 实测 = c2cMsgSeq（双端一致那个）；通常 = seq2 */
		seq1: ProtoField(3, "uint32"),
		/** 实测 = c2cMsgSeq；偶尔比 seq1 大 1（可能发/收两个方向的最后一条 c2cMsgSeq） */
		seq2: ProtoField(4, "uint32"),
		/** 跟该 peer 最后一条消息的时间戳 */
		latestMsgTime: ProtoField(5, "uint32")
	});
	_Action.SsoReadedReportReq = ProtoMessage.of({
		group: ProtoField(1, {
			groupCode: ProtoField(1, "uint32"),
			startSequence: ProtoField(2, "uint32")
		}, "optional"),
		c2c: ProtoField(2, {
			targetUid: ProtoField(2, "string"),
			time: ProtoField(3, "uint32"),
			startSequence: ProtoField(4, "uint32")
		}, "optional")
	});
	_Action.SsoReadedReportResp = ProtoMessage.of({
		retCode: ProtoField(1, "uint32"),
		retMsg: ProtoField(2, "string")
	});
})(Action || (Action = {}));
//#endregion
//#region src/ntqqapi/proto/notify.ts
var Notify;
(function(_Notify) {
	_Notify.GroupMemberChange = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		memberUid: ProtoField(3, "string"),
		type: ProtoField(4, "uint32"),
		adminUid: ProtoField(5, "string")
	});
	const GroupAdminExtra = ProtoMessage.of({
		adminUid: ProtoField(1, "string"),
		isPromote: ProtoField(2, "bool")
	});
	_Notify.GroupAdminChange = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		flag: ProtoField(2, "uint32"),
		isPromote: ProtoField(3, "bool"),
		body: ProtoField(4, {
			extraDisable: ProtoField(1, GroupAdminExtra, "optional"),
			extraEnable: ProtoField(2, GroupAdminExtra, "optional")
		})
	});
	_Notify.FriendRelatedOrPinChange = ProtoMessage.of({ body: ProtoField(1, {
		type: ProtoField(2, "uint32"),
		friendDeleted: ProtoField(14, { uid: ProtoField(1, "string") }, "optional"),
		pinChanged: ProtoField(20, { body: ProtoField(1, {
			uid: ProtoField(1, "string"),
			groupCode: ProtoField(2, "uint32", "optional"),
			info: ProtoField(400, { timestamp: ProtoField(2, "bytes") })
		}) }, "optional"),
		profileLike: ProtoField(203, { msg: ProtoField(14, {
			count: ProtoField(1, "uint32"),
			time: ProtoField(2, "uint32"),
			detail: ProtoField(3, {
				txt: ProtoField(1, "string"),
				uin: ProtoField(3, "uint32"),
				nickname: ProtoField(5, "string")
			})
		}) }, "optional")
	}) });
	const GroupRecall = _Notify.GroupRecall = ProtoMessage.of({
		operatorUid: ProtoField(1, "string", "optional"),
		recallMessages: ProtoField(3, {
			sequence: ProtoField(1, "uint32"),
			time: ProtoField(2, "uint32"),
			random: ProtoField(3, "uint32"),
			type: ProtoField(4, "uint32"),
			flag: ProtoField(5, "uint32"),
			authorUid: ProtoField(6, "string")
		}, "repeated"),
		userDef: ProtoField(5, "bytes", "optional"),
		groupType: ProtoField(6, "uint32", "optional"),
		opType: ProtoField(7, "uint32", "optional"),
		tipInfo: ProtoField(9, { tip: ProtoField(2, "string", "optional") }, "optional")
	});
	_Notify.FriendRecall = ProtoMessage.of({ body: ProtoField(1, {
		fromUid: ProtoField(1, "string"),
		toUid: ProtoField(2, "string"),
		clientSequence: ProtoField(3, "uint32"),
		/** 被撤回消息的 msgUid（C2C 公式 (0x01000000<<32)|random） */
		msgUid: ProtoField(4, "uint64"),
		/** 被撤回消息的 32-bit random，server 跨双端一致 */
		random: ProtoField(6, "uint32"),
		tipInfo: ProtoField(13, { tip: ProtoField(2, "string") }, "optional"),
		sequence: ProtoField(20, "uint32")
	}) });
	_Notify.FriendRequest = ProtoMessage.of({ body: ProtoField(1, {
		fromUid: ProtoField(2, "string"),
		message: ProtoField(10, "string"),
		via: ProtoField(11, "string")
	}, "optional") });
	const GroupReaction = _Notify.GroupReaction = ProtoMessage.of({ data: ProtoField(1, { data: ProtoField(1, {
		target: ProtoField(2, { sequence: ProtoField(1, "uint32") }),
		data: ProtoField(3, {
			code: ProtoField(1, "string"),
			reactionType: ProtoField(2, "uint32"),
			count: ProtoField(3, "uint32"),
			operatorUid: ProtoField(4, "string"),
			actionType: ProtoField(5, "uint32")
		})
	}) }) });
	const GeneralGrayTip = _Notify.GeneralGrayTip = ProtoMessage.of({
		bizType: ProtoField(1, "uint32"),
		busiId: ProtoField(2, "uint32"),
		ctrlFlag: ProtoField(3, "uint32"),
		c2cType: ProtoField(4, "uint32", "optional"),
		serviceType: ProtoField(5, "uint32", "optional"),
		templId: ProtoField(6, "uint32"),
		templParam: ProtoField(7, ["string", "string"]),
		content: ProtoField(8, "string"),
		tipsSeqId: ProtoField(10, "uint32")
	});
	_Notify.GroupMute = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		operatorUid: ProtoField(4, "string"),
		info: ProtoField(5, { state: ProtoField(3, {
			targetUid: ProtoField(1, "string", "optional"),
			duration: ProtoField(2, "uint32")
		}) })
	});
	_Notify.GroupInvitation = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		invitorUid: ProtoField(5, "string")
	});
	_Notify.GroupJoinRequest = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		memberUid: ProtoField(3, "string")
	});
	_Notify.GroupInvitedJoinRequest = ProtoMessage.of({ info: ProtoField(2, { inner: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		targetUid: ProtoField(5, "string"),
		invitorUid: ProtoField(6, "string")
	}) }) });
	const GroupEssenceChange = _Notify.GroupEssenceChange = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		msgSequence: ProtoField(2, "uint32"),
		random: ProtoField(3, "uint32"),
		setFlag: ProtoField(4, "uint32"),
		memberUin: ProtoField(5, "uint32"),
		operatorUin: ProtoField(6, "uint32"),
		timeStamp: ProtoField(7, "uint32"),
		msgSequence2: ProtoField(8, "uint32"),
		operatorNickName: ProtoField(9, "string"),
		memberNickName: ProtoField(10, "string"),
		setFlag2: ProtoField(11, "uint32")
	});
	_Notify.NotifyMessageBody = ProtoMessage.of({
		notifyType: ProtoField(1, "uint32", "optional"),
		groupCode: ProtoField(4, "uint32", "optional"),
		eventParam: ProtoField(5, "bytes", "optional"),
		recall: ProtoField(11, GroupRecall, "optional"),
		subType: ProtoField(13, "uint32", "optional"),
		operatorUid: ProtoField(21, "string", "optional"),
		generalGrayTip: ProtoField(26, GeneralGrayTip, "optional"),
		essenceMessage: ProtoField(33, GroupEssenceChange, "optional"),
		msgSequence: ProtoField(37, "uint64", "optional"),
		reaction: ProtoField(44, GroupReaction, "optional")
	});
	_Notify.GroupNameChangeBody = ProtoMessage.of({
		field1: ProtoField(1, "uint32", "optional"),
		newName: ProtoField(2, "string")
	});
	_Notify.GroupRemoved = ProtoMessage.of({ groupCode: ProtoField(1, "uint32") });
	_Notify.GroupJoined = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		adminUid: ProtoField(3, "string")
	});
	_Notify.FriendAdded = ProtoMessage.of({ body: ProtoField(2, { friendUid: ProtoField(1, "string") }) });
	_Notify.GroupMemberSpecialTitleChange = ProtoMessage.of({
		tipText: ProtoField(2, "string"),
		memberUin: ProtoField(5, "uint32")
	});
})(Notify || (Notify = {}));
//#endregion
//#region src/ntqqapi/proto/media.ts
var Media;
(function(_Media) {
	const FileInfo = _Media.FileInfo = ProtoMessage.of({
		fileSize: ProtoField(1, "uint32"),
		md5HexStr: ProtoField(2, "string"),
		sha1HexStr: ProtoField(3, "string"),
		fileName: ProtoField(4, "string"),
		fileType: ProtoField(5, {
			type: ProtoField(1, "uint32"),
			picFormat: ProtoField(2, "uint32"),
			videoFormat: ProtoField(3, "uint32"),
			pttFormat: ProtoField(4, "uint32")
		}),
		width: ProtoField(6, "uint32"),
		height: ProtoField(7, "uint32"),
		time: ProtoField(8, "uint32"),
		original: ProtoField(9, "uint32")
	});
	const IndexNode = _Media.IndexNode = ProtoMessage.of({
		info: ProtoField(1, FileInfo),
		fileUuid: ProtoField(2, "string"),
		storeID: ProtoField(3, "uint32"),
		uploadTime: ProtoField(4, "uint32"),
		expire: ProtoField(5, "uint32"),
		type: ProtoField(6, "uint32")
	});
	const ExtBizInfo = _Media.ExtBizInfo = ProtoMessage.of({
		pic: ProtoField(1, {
			bizType: ProtoField(1, "uint32"),
			summary: ProtoField(2, "string"),
			bytesPbReserveC2c: ProtoField(11, "bytes", "optional"),
			bytesPbReserveTroop: ProtoField(12, "bytes", "optional"),
			fromScene: ProtoField(1001, "uint32"),
			toScene: ProtoField(1002, "uint32"),
			oldFileId: ProtoField(1003, "uint32")
		}),
		video: ProtoField(2, {
			fromScene: ProtoField(1, "uint32", "optional"),
			toScene: ProtoField(2, "uint32", "optional"),
			pbReserve: ProtoField(3, "bytes")
		}),
		ptt: ProtoField(3, {
			srcUin: ProtoField(1, "uint64", "optional"),
			pttScene: ProtoField(2, "uint32", "optional"),
			pttType: ProtoField(3, "uint32", "optional"),
			changeVoice: ProtoField(4, "uint32", "optional"),
			waveform: ProtoField(5, "bytes", "optional"),
			autoConvertText: ProtoField(6, "uint32", "optional"),
			bytesReserve: ProtoField(11, "bytes", "optional"),
			bytesPbReserve: ProtoField(12, "bytes", "optional"),
			bytesGeneralFlags: ProtoField(13, "bytes", "optional")
		}, "optional"),
		busiType: ProtoField(10, "uint32")
	});
	_Media.NTV2RichMediaReq = ProtoMessage.of({
		reqHead: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			scene: ProtoField(2, {
				requestType: ProtoField(101, "uint32"),
				businessType: ProtoField(102, "uint32"),
				field103: ProtoField(103, "uint32"),
				sceneType: ProtoField(200, "uint32"),
				c2c: ProtoField(201, {
					accountType: ProtoField(1, "uint32"),
					targetUid: ProtoField(2, "string"),
					tmpInfo: ProtoField(3, { body: ProtoField(3, {
						groupCode: ProtoField(3, "uint32"),
						targetUid: ProtoField(2, "string")
					}) }, "optional")
				}),
				group: ProtoField(202, { groupId: ProtoField(1, "uint32") })
			}),
			client: ProtoField(3, { agentType: ProtoField(1, "uint32") })
		}),
		upload: ProtoField(2, {
			uploadInfo: ProtoField(1, {
				fileInfo: ProtoField(1, FileInfo),
				subFileType: ProtoField(2, "uint32")
			}, "repeated"),
			tryFastUploadCompleted: ProtoField(2, "bool"),
			srvSendMsg: ProtoField(3, "bool"),
			clientRandomId: ProtoField(4, "uint32"),
			compatQMsgSceneType: ProtoField(5, "uint32"),
			extBizInfo: ProtoField(6, ExtBizInfo),
			clientSeq: ProtoField(7, "uint32"),
			noNeedCompatMsg: ProtoField(8, "bool")
		}, "optional"),
		download: ProtoField(3, { node: ProtoField(1, IndexNode) }, "optional"),
		uploadCompleted: ProtoField(6, {
			srvSendMsg: ProtoField(1, "bool"),
			clientRandomId: ProtoField(2, "uint64"),
			msgInfo: ProtoField(3, "bytes"),
			clientSeq: ProtoField(4, "uint32")
		}, "optional")
	});
	const MsgInfoBody = ProtoMessage.of({
		index: ProtoField(1, IndexNode),
		pic: ProtoField(2, {
			urlPath: ProtoField(1, "string"),
			ext: ProtoField(2, {
				originalParam: ProtoField(1, "string"),
				bigParam: ProtoField(2, "string"),
				thumbParam: ProtoField(3, "string")
			}),
			domain: ProtoField(3, "string")
		}, "optional"),
		video: ProtoField(3, "bytes", "optional"),
		audio: ProtoField(4, "bytes", "optional"),
		fileExist: ProtoField(5, "bool"),
		hashSum: ProtoField(6, {
			bytesPbReserveC2c: ProtoField(201, { friendUid: ProtoField(2, "string") }, "optional"),
			troopSource: ProtoField(202, { groupCode: ProtoField(1, "uint32") }, "optional")
		})
	});
	_Media.MsgInfo = ProtoMessage.of({
		msgInfoBody: ProtoField(1, MsgInfoBody, "repeated"),
		extBizInfo: ProtoField(2, ExtBizInfo)
	});
	_Media.FileIdInfo = ProtoMessage.of({
		sha1: ProtoField(2, "bytes"),
		size: ProtoField(3, "uint32"),
		appid: ProtoField(4, "uint32"),
		time: ProtoField(5, "uint32"),
		expire: ProtoField(10, "uint32")
	});
	const IPv4 = ProtoMessage.of({
		outIP: ProtoField(1, "uint32"),
		outPort: ProtoField(2, "uint32"),
		inIP: ProtoField(3, "uint32"),
		inPort: ProtoField(4, "uint32"),
		ipType: ProtoField(5, "uint32")
	});
	const IPv6 = ProtoMessage.of({
		outIP: ProtoField(1, "bytes"),
		outPort: ProtoField(2, "uint32"),
		inIP: ProtoField(3, "bytes"),
		inPort: ProtoField(4, "uint32"),
		ipType: ProtoField(5, "uint32")
	});
	_Media.NTV2RichMediaResp = ProtoMessage.of({
		upload: ProtoField(2, {
			uKey: ProtoField(1, "string", "optional"),
			uKeyTtlSecond: ProtoField(2, "uint32"),
			ipv4s: ProtoField(3, IPv4, "repeated"),
			ipv6s: ProtoField(4, IPv6, "repeated"),
			msgSeq: ProtoField(5, "uint32", "optional"),
			msgInfo: ProtoField(6, "bytes"),
			ext: ProtoField(7, {
				subType: ProtoField(1, "uint32"),
				extType: ProtoField(2, "uint32"),
				extValue: ProtoField(3, "bytes")
			}, "repeated"),
			compatQMsg: ProtoField(8, "bytes"),
			subFileInfos: ProtoField(10, {
				subType: ProtoField(1, "uint32"),
				uKey: ProtoField(2, "string", "optional"),
				uKeyTtlSecond: ProtoField(3, "uint32"),
				ipv4s: ProtoField(4, IPv4, "repeated"),
				ipv6s: ProtoField(5, IPv6, "repeated")
			}, "repeated")
		}, "optional"),
		download: ProtoField(3, {
			rKeyParam: ProtoField(1, "string"),
			rKeyTtlSecond: ProtoField(2, "uint32"),
			info: ProtoField(3, {
				domain: ProtoField(1, "string"),
				urlPath: ProtoField(2, "string"),
				httpsPort: ProtoField(3, "uint32")
			}),
			rKeyCreateTime: ProtoField(4, "uint32")
		}, "optional")
	});
	_Media.HighwaySessionReq = ProtoMessage.of({ reqBody: ProtoField(1281, {
		uin: ProtoField(1, "uint32"),
		idcId: ProtoField(2, "uint32"),
		appid: ProtoField(3, "uint32"),
		loginSigType: ProtoField(4, "uint32"),
		loginSigTicket: ProtoField(5, "bytes", "optional"),
		requestFlag: ProtoField(6, "uint32"),
		serviceTypes: ProtoField(7, "uint32", "repeated"),
		bid: ProtoField(8, "uint32"),
		field9: ProtoField(9, "int32"),
		field10: ProtoField(10, "int32"),
		field11: ProtoField(11, "int32"),
		version: ProtoField(15, "string")
	}) });
	_Media.HighwaySessionResp = ProtoMessage.of({ rspBody: ProtoField(1281, {
		sigSession: ProtoField(1, "bytes"),
		sessionKey: ProtoField(2, "bytes"),
		addrs: ProtoField(3, {
			serviceType: ProtoField(1, "uint32"),
			addrs: ProtoField(2, {
				type: ProtoField(1, "uint32"),
				ip: ProtoField(2, "fixed32"),
				port: ProtoField(3, "uint32"),
				area: ProtoField(4, "uint32")
			}, "repeated")
		}, "repeated")
	}) });
	const DataHighwayHead = ProtoMessage.of({
		version: ProtoField(1, "uint32"),
		uin: ProtoField(2, "string", "optional"),
		command: ProtoField(3, "string", "optional"),
		seq: ProtoField(4, "uint32"),
		retryTimes: ProtoField(5, "uint32"),
		appId: ProtoField(6, "uint32"),
		dataFlag: ProtoField(7, "uint32"),
		commandId: ProtoField(8, "uint32"),
		buildVer: ProtoField(9, "bytes", "optional")
	});
	const SegHead = ProtoMessage.of({
		serviceId: ProtoField(1, "uint32"),
		filesize: ProtoField(2, "uint32"),
		dataOffset: ProtoField(3, "uint32"),
		dataLength: ProtoField(4, "uint32"),
		retCode: ProtoField(5, "uint32", "optional"),
		serviceTicket: ProtoField(6, "bytes"),
		md5: ProtoField(8, "bytes"),
		fileMd5: ProtoField(9, "bytes"),
		cacheAddr: ProtoField(10, "uint32"),
		cachePort: ProtoField(13, "uint32")
	});
	_Media.ReqDataHighwayHead = ProtoMessage.of({
		msgBaseHead: ProtoField(1, DataHighwayHead),
		msgSegHead: ProtoField(2, SegHead),
		bytesReqExtendInfo: ProtoField(3, "bytes"),
		timestamp: ProtoField(4, "uint32"),
		msgLoginSigHead: ProtoField(5, {
			uint32LoginSigType: ProtoField(1, "uint32"),
			bytesLoginSig: ProtoField(2, "bytes", "optional"),
			appId: ProtoField(3, "uint32")
		})
	});
	_Media.RespDataHighwayHead = ProtoMessage.of({
		msgBaseHead: ProtoField(1, DataHighwayHead),
		msgSegHead: ProtoField(2, SegHead, "optional"),
		errorCode: ProtoField(3, "uint32"),
		allowRetry: ProtoField(4, "uint32"),
		cacheCost: ProtoField(5, "uint32"),
		htCost: ProtoField(6, "uint32"),
		bytesRspExtendInfo: ProtoField(7, "bytes"),
		timestamp: ProtoField(8, "uint32"),
		range: ProtoField(9, "uint32"),
		isReset: ProtoField(10, "uint32")
	});
	const NTHighwayIPv4 = _Media.NTHighwayIPv4 = ProtoMessage.of({
		domain: ProtoField(1, {
			isEnable: ProtoField(1, "bool"),
			ip: ProtoField(2, "string")
		}),
		port: ProtoField(2, "uint32")
	});
	const NTHighwayNetwork = _Media.NTHighwayNetwork = ProtoMessage.of({ ipv4s: ProtoField(1, NTHighwayIPv4, "repeated") });
	_Media.NTV2RichMediaHighwayExt = ProtoMessage.of({
		fileUuid: ProtoField(1, "string"),
		uKey: ProtoField(2, "string"),
		network: ProtoField(5, NTHighwayNetwork),
		msgInfoBody: ProtoField(6, MsgInfoBody, "repeated"),
		blockSize: ProtoField(10, "uint32"),
		hash: ProtoField(11, { fileSha1: ProtoField(1, "bytes", "repeated") })
	});
	const FlashTransferSha1StateV = _Media.FlashTransferSha1StateV = ProtoMessage.of({ state: ProtoField(1, "bytes", "repeated") });
	_Media.FlashTransferUploadReq = ProtoMessage.of({
		fieId1: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		fileId3: ProtoField(3, "uint32"),
		body: ProtoField(107, {
			fieId1: ProtoField(1, "bytes"),
			uKey: ProtoField(2, "string"),
			start: ProtoField(3, "uint32"),
			end: ProtoField(4, "uint32"),
			sha1: ProtoField(5, "bytes"),
			sha1StateV: ProtoField(6, FlashTransferSha1StateV),
			body: ProtoField(7, "bytes")
		})
	});
	_Media.FlashTransferUploadResp = ProtoMessage.of({ status: ProtoField(5, "string") });
	_Media.FileUploadExt = ProtoMessage.of({
		unknown1: ProtoField(1, "int32"),
		unknown2: ProtoField(2, "int32"),
		unknown3: ProtoField(3, "int32"),
		entry: ProtoField(100, {
			busiBuff: ProtoField(100, {
				busId: ProtoField(1, "int32"),
				senderUin: ProtoField(100, "uint32"),
				receiverUin: ProtoField(200, "uint32"),
				groupCode: ProtoField(400, "uint32")
			}),
			fileEntry: ProtoField(200, {
				fileSize: ProtoField(100, "uint32"),
				md5: ProtoField(200, "bytes"),
				checkKey: ProtoField(300, "bytes"),
				md510M: ProtoField(400, "bytes", "optional"),
				sha3: ProtoField(500, "bytes", "optional"),
				fileId: ProtoField(600, "string"),
				uploadKey: ProtoField(700, "bytes")
			}),
			clientInfo: ProtoField(300, {
				clientType: ProtoField(100, "int32"),
				appId: ProtoField(200, "string"),
				terminalType: ProtoField(300, "int32"),
				clientVer: ProtoField(400, "string"),
				unknown: ProtoField(600, "int32")
			}),
			fileNameInfo: ProtoField(400, { fileName: ProtoField(100, "string") }),
			host: ProtoField(500, { hosts: ProtoField(200, {
				url: ProtoField(1, {
					unknown: ProtoField(1, "int32"),
					host: ProtoField(2, "string")
				}),
				port: ProtoField(2, "uint32")
			}, "repeated") })
		}),
		unknown200: ProtoField(200, "int32", "optional")
	});
	_Media.GroupAvatarExtra = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		groupUin: ProtoField(2, "uint32"),
		field3: ProtoField(3, { field1: ProtoField(1, "uint32") }),
		field5: ProtoField(5, "uint32"),
		field6: ProtoField(6, "uint32")
	});
})(Media || (Media = {}));
//#endregion
//#region src/ntqqapi/proto/oidb.ts
var Oidb;
(function(_Oidb) {
	_Oidb.Base = ProtoMessage.of({
		command: ProtoField(1, "uint32"),
		subCommand: ProtoField(2, "uint32"),
		errorCode: ProtoField(3, "uint32"),
		body: ProtoField(4, "bytes"),
		errorMsg: ProtoField(5, "string"),
		isReserved: ProtoField(12, "uint32")
	});
	_Oidb.SendPokeReq = ProtoMessage.of({
		toUin: ProtoField(1, "uint32"),
		groupCode: ProtoField(2, "uint32"),
		friendUin: ProtoField(5, "uint32")
	});
	_Oidb.SetSpecialTitleReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		body: ProtoField(3, {
			targetUid: ProtoField(1, "string"),
			specialTitle: ProtoField(5, "string"),
			expireTime: ProtoField(6, "int32"),
			uidName: ProtoField(7, "string")
		})
	});
	_Oidb.GetRKeyResp = ProtoMessage.of({ result: ProtoField(4, { rkeyItems: ProtoField(1, {
		rkey: ProtoField(1, "string"),
		ttlSec: ProtoField(2, "uint32"),
		storeId: ProtoField(3, "uint32"),
		createTime: ProtoField(4, "uint32"),
		type: ProtoField(5, "uint32")
	}, "repeated") }) });
	_Oidb.FetchUserInfoByUinReq = ProtoMessage.of({
		uin: ProtoField(1, "uint32"),
		field2: ProtoField(2, "uint32"),
		keys: ProtoField(3, { key: ProtoField(1, "uint32") }, "repeated")
	});
	_Oidb.FetchUserInfoByUidReq = ProtoMessage.of({
		uid: ProtoField(1, "string"),
		keys: ProtoField(3, { key: ProtoField(1, "uint32") }, "repeated")
	});
	_Oidb.FetchUserInfoResp = ProtoMessage.of({ body: ProtoField(1, {
		properties: ProtoField(2, {
			numberProperties: ProtoField(1, ["uint32", "uint32"]),
			bytesProperties: ProtoField(2, ["uint32", "bytes"])
		}),
		uin: ProtoField(3, "uint32")
	}) });
	_Oidb.FetchGroupMembersReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		field2: ProtoField(2, "uint32"),
		field3: ProtoField(3, "uint32"),
		body: ProtoField(4, {
			memberName: ProtoField(10, "bool"),
			memberCard: ProtoField(11, "bool"),
			level: ProtoField(12, "bool"),
			specialTitle: ProtoField(17, "bool"),
			joinTimestamp: ProtoField(100, "bool"),
			lastMsgTimestamp: ProtoField(101, "bool"),
			shutUpTimestamp: ProtoField(102, "bool"),
			permission: ProtoField(107, "bool")
		}),
		cookie: ProtoField(15, "bytes", "optional")
	});
	_Oidb.FetchGroupMembersResp = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		members: ProtoField(2, {
			id: ProtoField(1, {
				uid: ProtoField(2, "string"),
				uin: ProtoField(4, "uint32")
			}),
			memberName: ProtoField(10, "string"),
			memberCard: ProtoField(11, { memberCard: ProtoField(2, "string", "optional") }),
			level: ProtoField(12, { level: ProtoField(2, "uint32", "optional") }, "optional"),
			specialTitle: ProtoField(17, "string", "optional"),
			joinTimestamp: ProtoField(100, "uint32"),
			lastMsgTimestamp: ProtoField(101, "uint32"),
			shutUpTimestamp: ProtoField(102, "uint32", "optional"),
			permission: ProtoField(107, "uint32", "optional")
		}, "repeated"),
		memberCount: ProtoField(3, "uint32"),
		cookie: ProtoField(15, "bytes", "optional")
	});
	_Oidb.FetchAiCharacterListReq = ProtoMessage.of({
		groupId: ProtoField(1, "uint32"),
		chatType: ProtoField(2, "uint32")
	});
	_Oidb.FetchAiCharacterListResp = ProtoMessage.of({ property: ProtoField(1, {
		type: ProtoField(1, "string"),
		characters: ProtoField(2, {
			characterId: ProtoField(1, "string"),
			characterName: ProtoField(2, "string"),
			previewUrl: ProtoField(3, "string")
		}, "repeated")
	}, "repeated") });
	_Oidb.GetGroupGenerateAiRecordReq = ProtoMessage.of({
		groupId: ProtoField(1, "uint32"),
		voiceId: ProtoField(2, "string"),
		text: ProtoField(3, "string"),
		chatType: ProtoField(4, "uint32"),
		clientMsgInfo: ProtoField(5, { msgRandom: ProtoField(1, "uint32") })
	});
	_Oidb.GetGroupFileReq = ProtoMessage.of({ download: ProtoField(3, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		busId: ProtoField(3, "uint32"),
		fileId: ProtoField(4, "string")
	}) });
	_Oidb.GetGroupFileResp = ProtoMessage.of({ download: ProtoField(3, {
		retCode: ProtoField(1, "int64"),
		clientWording: ProtoField(3, "string"),
		downloadDns: ProtoField(5, "string"),
		downloadUrl: ProtoField(6, "bytes")
	}) });
	_Oidb.GetPrivateFileReq = ProtoMessage.of({
		subCommand: ProtoField(1, "uint32"),
		field2: ProtoField(2, "uint32"),
		body: ProtoField(14, {
			receiverUid: ProtoField(10, "string"),
			fileUuid: ProtoField(20, "string"),
			type: ProtoField(30, "uint32"),
			fileHash: ProtoField(60, "string"),
			t2: ProtoField(601, "uint32")
		}),
		field101: ProtoField(101, "uint32"),
		field102: ProtoField(102, "uint32"),
		field200: ProtoField(200, "uint32"),
		field99999: ProtoField(99999, "bytes")
	});
	_Oidb.GetPrivateFileResp = ProtoMessage.of({
		command: ProtoField(1, "uint32"),
		subCommand: ProtoField(2, "uint32"),
		body: ProtoField(14, {
			retCode: ProtoField(10, "int64"),
			state: ProtoField(20, "string"),
			result: ProtoField(30, { extra: ProtoField(120, {
				field100: ProtoField(100, "uint32"),
				download: ProtoField(102, {
					downloadUrl: ProtoField(8, "bytes"),
					downloadDns: ProtoField(11, "string")
				})
			}) }),
			metadata: ProtoField(40, { fileName: ProtoField(7, "string") })
		}),
		field50: ProtoField(50, "uint32")
	});
	_Oidb.GroupClockInReq = ProtoMessage.of({ body: ProtoField(2, {
		uin: ProtoField(1, "string"),
		groupCode: ProtoField(2, "string"),
		appVersion: ProtoField(3, "string")
	}) });
	_Oidb.GroupFileReq = ProtoMessage.of({ uploadFileReq: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		busId: ProtoField(3, "uint32"),
		entrance: ProtoField(4, "uint32"),
		parentFolderId: ProtoField(5, "string"),
		fileName: ProtoField(6, "string"),
		localPath: ProtoField(7, "string"),
		fileSize: ProtoField(8, "uint32"),
		sha: ProtoField(9, "bytes"),
		sha3: ProtoField(10, "bytes", "optional"),
		md5: ProtoField(11, "bytes"),
		supportMultiUpload: ProtoField(12, "bool")
	}) });
	_Oidb.GroupFileResp = ProtoMessage.of({ uploadFileRsp: ProtoField(1, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string"),
		uploadIp: ProtoField(4, "string"),
		serverDns: ProtoField(5, "string"),
		busId: ProtoField(6, "uint32"),
		fileId: ProtoField(7, "string"),
		checkKey: ProtoField(8, "bytes"),
		fileKey: ProtoField(9, "bytes"),
		fileExist: ProtoField(10, "bool"),
		uploadIpLanV4: ProtoField(12, "string", "repeated"),
		uploadIpLanV6: ProtoField(13, "string", "repeated"),
		uploadPort: ProtoField(14, "uint32")
	}) });
	_Oidb.GroupFileFeedReq = ProtoMessage.of({ feedsInfoReq: ProtoField(5, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		feedsInfoList: ProtoField(3, {
			busId: ProtoField(1, "uint32"),
			fileId: ProtoField(2, "string"),
			msgRandom: ProtoField(3, "uint32"),
			feedFlag: ProtoField(5, "uint32")
		}, "repeated")
	}) });
	_Oidb.GroupFileFeedResp = ProtoMessage.of({ feedsInfoRsp: ProtoField(5, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string"),
		feedsResultList: ProtoField(4, {
			retCode: ProtoField(1, "int64"),
			detail: ProtoField(2, "string"),
			fileId: ProtoField(3, "string"),
			busId: ProtoField(4, "uint32"),
			deadTime: ProtoField(5, "uint32"),
			msgSeq: ProtoField(6, "uint32")
		}, "repeated"),
		svrBusyWaitTime: ProtoField(5, "uint32")
	}) });
	_Oidb.OfflineFileUploadReq = ProtoMessage.of({
		command: ProtoField(1, "uint32"),
		seq: ProtoField(2, "int32"),
		upload: ProtoField(19, {
			senderUid: ProtoField(10, "string"),
			receiverUid: ProtoField(20, "string"),
			fileSize: ProtoField(30, "uint32"),
			fileName: ProtoField(40, "string"),
			md510MCheckSum: ProtoField(50, "bytes"),
			sha1CheckSum: ProtoField(60, "bytes"),
			localPath: ProtoField(70, "string"),
			md5CheckSum: ProtoField(110, "bytes"),
			sha3CheckSum: ProtoField(120, "bytes")
		}),
		businessId: ProtoField(101, "int32"),
		clientType: ProtoField(102, "int32"),
		flagSupportMediaPlatform: ProtoField(200, "int32")
	});
	_Oidb.OfflineFileUploadResp = ProtoMessage.of({
		command: ProtoField(1, "uint32"),
		seq: ProtoField(2, "int32"),
		upload: ProtoField(19, {
			retCode: ProtoField(10, "int32"),
			retMsg: ProtoField(20, "string"),
			totalSpace: ProtoField(30, "uint32"),
			usedSpace: ProtoField(40, "uint32"),
			uploadedSize: ProtoField(50, "uint32"),
			uploadIp: ProtoField(60, "string"),
			uploadDomain: ProtoField(70, "string"),
			uploadPort: ProtoField(80, "uint32"),
			uuid: ProtoField(90, "string"),
			uploadKey: ProtoField(100, "bytes"),
			fileExist: ProtoField(110, "bool"),
			packSize: ProtoField(120, "int32"),
			uploadIpList: ProtoField(130, "string", "repeated"),
			uploadHttpsPort: ProtoField(140, "int32"),
			uploadHttpsDomain: ProtoField(150, "string"),
			uploadDns: ProtoField(160, "string"),
			uploadLanip: ProtoField(170, "string"),
			fileIdCrc: ProtoField(200, "string"),
			rtpMediaPlatformUploadAddress: ProtoField(210, {
				outIp: ProtoField(1, "uint32"),
				outPort: ProtoField(2, "uint32"),
				innerIp: ProtoField(3, "uint32"),
				innerPort: ProtoField(4, "uint32"),
				ipType: ProtoField(5, "uint32")
			}, "repeated"),
			mediaPlatformUploadKey: ProtoField(220, "bytes")
		}),
		businessId: ProtoField(101, "int32"),
		clientType: ProtoField(102, "int32"),
		flagSupportMediaPlatform: ProtoField(200, "int32")
	});
	_Oidb.FetchGroupsReq = ProtoMessage.of({ config: ProtoField(1, {
		config1: ProtoField(1, {
			groupOwner: ProtoField(1, "bool"),
			createdTime: ProtoField(2, "bool"),
			memberMax: ProtoField(3, "bool"),
			memberCount: ProtoField(4, "bool"),
			groupName: ProtoField(5, "bool"),
			topTime: ProtoField(9, "bool"),
			groupShutupExpireTime: ProtoField(10, "bool"),
			description: ProtoField(18, "bool"),
			question: ProtoField(19, "bool"),
			richDescription: ProtoField(21, "bool"),
			announcement: ProtoField(30, "bool")
		}),
		config2: ProtoField(2, {
			memberRole: ProtoField(2, "bool"),
			remark: ProtoField(3, "bool"),
			personShutupExpireTime: ProtoField(4, "bool"),
			msgMask: ProtoField(7, "bool")
		})
	}) });
	_Oidb.FetchGroupsResp = ProtoMessage.of({ groups: ProtoField(2, {
		groupCode: ProtoField(3, "uint32"),
		info: ProtoField(4, {
			groupOwner: ProtoField(1, { uid: ProtoField(2, "string") }),
			createdTime: ProtoField(2, "uint32"),
			memberMax: ProtoField(3, "uint32"),
			memberCount: ProtoField(4, "uint32"),
			groupName: ProtoField(5, "string"),
			topTime: ProtoField(9, "uint32", "optional"),
			groupShutupExpireTime: ProtoField(10, "uint32", "optional"),
			description: ProtoField(18, "string", "optional"),
			question: ProtoField(19, "string", "optional"),
			richDescription: ProtoField(21, "string", "optional"),
			announcement: ProtoField(30, "string", "optional")
		}),
		personInfo: ProtoField(5, {
			memberRole: ProtoField(2, "uint32"),
			remark: ProtoField(3, "string", "optional"),
			personShutupExpireTime: ProtoField(4, "uint32", "optional"),
			msgMask: ProtoField(7, "uint32")
		})
	}, "repeated") });
	_Oidb.GetGroupFileListReq = ProtoMessage.of({ listReq: ProtoField(2, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		targetDirectory: ProtoField(3, "string"),
		fileCount: ProtoField(5, "uint32"),
		sortBy: ProtoField(9, "uint32"),
		startIndex: ProtoField(13, "uint32"),
		field17: ProtoField(17, "uint32"),
		field18: ProtoField(18, "uint32")
	}) });
	const GetGroupFileListRespItem = _Oidb.GetGroupFileListRespItem = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		folderInfo: ProtoField(2, {
			folderId: ProtoField(1, "string"),
			parentFolderId: ProtoField(2, "string"),
			folderName: ProtoField(3, "string"),
			createTime: ProtoField(4, "uint32"),
			modifyTime: ProtoField(5, "uint32"),
			createUin: ProtoField(6, "uint32"),
			creatorName: ProtoField(7, "string"),
			totalFileCount: ProtoField(8, "uint32"),
			modifyUin: ProtoField(9, "uint32"),
			modifyName: ProtoField(10, "string"),
			usedSpace: ProtoField(11, "uint32")
		}, "optional"),
		fileInfo: ProtoField(3, {
			fileId: ProtoField(1, "string"),
			fileName: ProtoField(2, "string"),
			fileSize: ProtoField(3, "uint32"),
			busId: ProtoField(4, "uint32"),
			uploadedSize: ProtoField(5, "uint32"),
			uploadedTime: ProtoField(6, "uint32"),
			expireTime: ProtoField(7, "uint32"),
			modifiedTime: ProtoField(8, "uint32"),
			downloadedTimes: ProtoField(9, "uint32"),
			fileSha1: ProtoField(10, "bytes"),
			fileMd5: ProtoField(12, "bytes"),
			uploaderName: ProtoField(14, "string"),
			uploaderUin: ProtoField(15, "uint32"),
			parentDirectory: ProtoField(16, "string"),
			field17: ProtoField(17, "uint32"),
			field22: ProtoField(22, "string")
		}, "optional")
	});
	_Oidb.GetGroupFileListResp = ProtoMessage.of({ listResp: ProtoField(2, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string"),
		isEnd: ProtoField(4, "bool"),
		items: ProtoField(5, GetGroupFileListRespItem, "repeated"),
		allFileCount: ProtoField(7, "uint32"),
		nextIndex: ProtoField(13, "uint32")
	}) });
	_Oidb.GetGroupFileCountReq = ProtoMessage.of({ countReq: ProtoField(3, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		busId: ProtoField(3, "uint32")
	}) });
	_Oidb.GetGroupFileCountResp = ProtoMessage.of({ countResp: ProtoField(3, {
		fileCount: ProtoField(4, "uint32"),
		limitCount: ProtoField(6, "uint32"),
		isFull: ProtoField(7, "bool")
	}) });
	_Oidb.GetGroupFileSpaceReq = ProtoMessage.of({ spaceReq: ProtoField(4, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32")
	}) });
	_Oidb.GetGroupFileSpaceResp = ProtoMessage.of({ spaceResp: ProtoField(4, {
		totalSpace: ProtoField(4, "uint64"),
		usedSpace: ProtoField(5, "uint64")
	}) });
	_Oidb.ImageOcrReq = ProtoMessage.of({
		version: ProtoField(1, "uint32"),
		client: ProtoField(2, "uint32"),
		entrance: ProtoField(3, "uint32"),
		ocrReqBody: ProtoField(10, {
			imageUrl: ProtoField(1, "string"),
			languageType: ProtoField(2, "uint32"),
			scene: ProtoField(3, "uint32"),
			originMd5: ProtoField(10, "string"),
			afterCompressMd5: ProtoField(11, "string"),
			afterCompressFileSize: ProtoField(12, "string"),
			afterCompressWeight: ProtoField(13, "string"),
			afterCompressHeight: ProtoField(14, "string"),
			isCut: ProtoField(15, "bool")
		})
	});
	_Oidb.ImageOcrResp = ProtoMessage.of({
		retCode: ProtoField(1, "int32", "optional"),
		errMsg: ProtoField(2, "string"),
		wording: ProtoField(3, "string", "optional"),
		ocrRspBody: ProtoField(10, {
			textDetections: ProtoField(1, {
				detectedText: ProtoField(1, "string"),
				confidence: ProtoField(2, "uint32"),
				polygon: ProtoField(3, { coordinates: ProtoField(1, {
					x: ProtoField(1, "int32"),
					y: ProtoField(2, "int32")
				}, "repeated") }),
				advancedInfo: ProtoField(4, "string")
			}, "repeated"),
			language: ProtoField(2, "string"),
			requestId: ProtoField(3, "string"),
			ocrLanguageList: ProtoField(101, "string", "repeated"),
			dstTranslateLanguageList: ProtoField(102, "string", "repeated"),
			languageList: ProtoField(103, {
				languageCode: ProtoField(1, "string"),
				languageDesc: ProtoField(2, "string")
			}, "repeated"),
			afterCompressWeight: ProtoField(111, "uint32"),
			afterCompressHeight: ProtoField(112, "uint32")
		})
	});
	_Oidb.SetFriendRequestReq = ProtoMessage.of({
		accept: ProtoField(1, "uint32"),
		targetUid: ProtoField(2, "string")
	});
	_Oidb.SetFilteredFriendRequestReq = ProtoMessage.of({
		selfUid: ProtoField(1, "string"),
		requestUid: ProtoField(2, "string")
	});
	_Oidb.IncPullReq = ProtoMessage.of({
		reqCount: ProtoField(2, "uint32"),
		time: ProtoField(3, "uint32"),
		localSeq: ProtoField(4, "uint32"),
		cookie: ProtoField(5, "bytes", "optional"),
		flag: ProtoField(6, "int32"),
		proxySeq: ProtoField(7, "uint32"),
		requestBiz: ProtoField(10001, {
			bizType: ProtoField(1, "int32"),
			bizData: ProtoField(2, { extBusi: ProtoField(1, "int32", "repeated") })
		}, "repeated"),
		extSnsFlagKey: ProtoField(10002, "uint32", "repeated"),
		extPrivateIdListKey: ProtoField(10003, "uint32", "repeated")
	});
	_Oidb.IncPullResp = ProtoMessage.of({
		seq: ProtoField(1, "uint32"),
		cookie: ProtoField(2, "bytes", "optional"),
		isEnd: ProtoField(3, "bool"),
		time: ProtoField(6, "uint32"),
		selfUin: ProtoField(7, "uint32"),
		smallSeq: ProtoField(8, "uint32"),
		friendList: ProtoField(101, {
			uid: ProtoField(1, "string"),
			categoryId: ProtoField(2, "int32"),
			uin: ProtoField(3, "uint32"),
			subBiz: ProtoField(10001, ["int32", {
				numData: ProtoField(1, ["int32", "int32"]),
				data: ProtoField(2, ["int32", "bytes"])
			}])
		}, "repeated"),
		category: ProtoField(102, {
			categoryId: ProtoField(1, "int32"),
			categoryName: ProtoField(2, "string"),
			categoryMemberCount: ProtoField(3, "int32"),
			categorySortId: ProtoField(4, "int32")
		}, "repeated")
	});
	_Oidb.FetchPinsResp = ProtoMessage.of({
		friends: ProtoField(1, { uid: ProtoField(1, "string") }, "repeated"),
		groups: ProtoField(3, { groupCode: ProtoField(1, "uint32") }, "repeated")
	});
	_Oidb.GetFriendRecommendContactArkReq = ProtoMessage.of({
		uin: ProtoField(1, "uint32"),
		phoneNumber: ProtoField(2, "string"),
		jumpUrl: ProtoField(3, "string")
	});
	_Oidb.GetFriendRecommendContactArkResp = ProtoMessage.of({ ark: ProtoField(1, "string") });
	_Oidb.SetFriendRemarkReq = ProtoMessage.of({
		uid: ProtoField(1, "string"),
		remark: ProtoField(2, "string")
	});
	_Oidb.DeleteFriendReq = ProtoMessage.of({ field1: ProtoField(1, {
		targetUid: ProtoField(1, "string"),
		field2: ProtoField(2, {
			field1: ProtoField(1, "uint32"),
			field2: ProtoField(2, "uint32"),
			field3: ProtoField(3, {
				field1: ProtoField(1, "uint32"),
				field2: ProtoField(2, "uint32"),
				field3: ProtoField(3, "uint32")
			})
		}),
		block: ProtoField(3, "bool"),
		bothDelete: ProtoField(4, "bool")
	}) });
	_Oidb.SetFriendCategoryReq = ProtoMessage.of({
		uid: ProtoField(1, "string"),
		categoryId: ProtoField(2, "uint32")
	});
	_Oidb.FetchFriendRequestsReq = ProtoMessage.of({
		version: ProtoField(1, "int32"),
		type: ProtoField(3, "int32"),
		selfUid: ProtoField(4, "string"),
		startIndex: ProtoField(5, "int32"),
		reqNum: ProtoField(6, "int32"),
		getFlag: ProtoField(8, "int32"),
		startTime: ProtoField(9, "int32"),
		needCommFriend: ProtoField(12, "int32"),
		field22: ProtoField(22, "int32")
	});
	_Oidb.FetchFriendRequestsResp = ProtoMessage.of({
		field1: ProtoField(1, "int32"),
		field2: ProtoField(2, "int32"),
		info: ProtoField(3, {
			field2: ProtoField(2, "int32"),
			count: ProtoField(3, "int32"),
			requests: ProtoField(7, {
				selfUid: ProtoField(1, "string"),
				friendUid: ProtoField(2, "string"),
				state: ProtoField(3, "int32"),
				timestamp: ProtoField(4, "uint32"),
				comment: ProtoField(5, "string"),
				source: ProtoField(6, "string"),
				sourceId: ProtoField(7, "int32"),
				subSourceId: ProtoField(8, "int32"),
				isInitiator: ProtoField(20, "bool")
			}, "repeated")
		})
	});
	_Oidb.FetchFilteredFriendRequestsReq = ProtoMessage.of({
		field1: ProtoField(1, "int32"),
		field2: ProtoField(2, { count: ProtoField(1, "int32") })
	});
	_Oidb.FetchFilteredFriendRequestsResp = ProtoMessage.of({ info: ProtoField(2, { requests: ProtoField(1, {
		sourceUid: ProtoField(1, "string"),
		sourceNickname: ProtoField(2, "string"),
		comment: ProtoField(5, "string"),
		source: ProtoField(6, "string"),
		warningInfo: ProtoField(7, "string"),
		timestamp: ProtoField(8, "uint32"),
		groupCode: ProtoField(9, "uint32")
	}, "repeated") }) });
	_Oidb.SetFriendPinReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		info: ProtoField(2, {
			friendUid: ProtoField(1, "string"),
			field400: ProtoField(400, {
				field1: ProtoField(1, "uint32"),
				timestamp: ProtoField(2, "bytes")
			})
		}),
		field3: ProtoField(3, "uint32")
	});
	_Oidb.SetGroupPinReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		info: ProtoField(2, {
			groupCode: ProtoField(2, "uint32"),
			field400: ProtoField(400, {
				field1: ProtoField(1, "uint32"),
				timestamp: ProtoField(2, "bytes")
			})
		}),
		field3: ProtoField(3, "uint32")
	});
	_Oidb.FetchGroupReq = ProtoMessage.of({
		random: ProtoField(1, "uint32"),
		config: ProtoField(2, {
			groupCode: ProtoField(1, "uint32"),
			flags: ProtoField(2, {
				ownerUid: ProtoField(1, "bool"),
				groupCreateTime: ProtoField(2, "bool"),
				maxMemberNum: ProtoField(5, "bool"),
				memberNum: ProtoField(6, "bool"),
				groupName: ProtoField(15, "string"),
				question: ProtoField(24, "string"),
				description: ProtoField(40, "string"),
				shutUpMeTimestamp: ProtoField(46, "bool"),
				richGroupName: ProtoField(89, "string")
			})
		})
	});
	_Oidb.FetchGroupResp = ProtoMessage.of({ info: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		results: ProtoField(3, {
			ownerUid: ProtoField(1, "string"),
			groupCreateTime: ProtoField(2, "uint32"),
			maxMemberNum: ProtoField(5, "uint32"),
			memberNum: ProtoField(6, "uint32"),
			groupName: ProtoField(15, "string"),
			question: ProtoField(24, "string"),
			description: ProtoField(40, "string", "optional"),
			shutUpMeTimestamp: ProtoField(46, "uint32"),
			richGroupName: ProtoField(89, "string", "optional")
		})
	}) });
	_Oidb.KickMemberReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		kickUids: ProtoField(3, "string", "repeated"),
		rejectSubsequentRequests: ProtoField(4, "bool"),
		reason: ProtoField(5, "string", "optional")
	});
	_Oidb.MuteMemberReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		memCount: ProtoField(2, "uint32"),
		memList: ProtoField(3, {
			uid: ProtoField(1, "string"),
			duration: ProtoField(2, "uint32")
		}, "repeated")
	});
	_Oidb.MuteAllMembersReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		body: ProtoField(2, { duration: ProtoField(17, "uint32") })
	});
	_Oidb.SetGroupNameReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		body: ProtoField(2, { name: ProtoField(3, "string") })
	});
	_Oidb.SetMemberCardReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		body: ProtoField(3, {
			targetUid: ProtoField(1, "string"),
			card: ProtoField(8, "string")
		}, "repeated")
	});
	_Oidb.LeaveGroupReq = ProtoMessage.of({ groupCode: ProtoField(1, "uint32") });
	_Oidb.HandleGroupRequestReq = ProtoMessage.of({
		operation: ProtoField(1, "uint32"),
		body: ProtoField(2, {
			sequence: ProtoField(1, "uint64"),
			eventType: ProtoField(2, "uint32"),
			groupCode: ProtoField(3, "uint32"),
			message: ProtoField(4, "string")
		})
	});
	_Oidb.SetMemberAdminReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		memberUid: ProtoField(2, "string"),
		isSet: ProtoField(3, "bool")
	});
	_Oidb.GroupEssenceReq = ProtoMessage.of({
		groupCode: ProtoField(1, "uint32"),
		msgSequence: ProtoField(2, "uint32"),
		msgRandom: ProtoField(3, "uint32")
	});
	_Oidb.GroupEssenceResp = ProtoMessage.of({
		retMsg: ProtoField(1, "string"),
		retCode: ProtoField(10, "uint32")
	});
	_Oidb.GroupReactionReq = ProtoMessage.of({
		groupCode: ProtoField(2, "uint32"),
		sequence: ProtoField(3, "uint32"),
		code: ProtoField(4, "string"),
		type: ProtoField(5, "uint32")
	});
	_Oidb.FetchCookiesReq = ProtoMessage.of({ domain: ProtoField(1, "string", "repeated") });
	_Oidb.FetchCookiesResp = ProtoMessage.of({
		psKeys: ProtoField(1, ["string", "string"]),
		keyType: ProtoField(2, "int32"),
		clientKey: ProtoField(3, "string"),
		expiration: ProtoField(4, "uint32")
	});
	_Oidb.FetchGroupNotifiesReq = ProtoMessage.of({
		count: ProtoField(1, "uint32"),
		startSequence: ProtoField(2, "uint64", "optional")
	});
	_Oidb.FetchGroupNotifiesResp = ProtoMessage.of({
		requests: ProtoField(1, {
			sequence: ProtoField(1, "uint64"),
			type: ProtoField(2, "uint32"),
			requestState: ProtoField(3, "uint32"),
			group: ProtoField(4, {
				groupCode: ProtoField(1, "uint32"),
				groupName: ProtoField(2, "string")
			}),
			user1: ProtoField(5, {
				uid: ProtoField(1, "string"),
				nickName: ProtoField(2, "string")
			}),
			user2: ProtoField(6, {
				uid: ProtoField(1, "string"),
				nickName: ProtoField(2, "string")
			}, "optional"),
			user3: ProtoField(7, {
				uid: ProtoField(1, "string"),
				nickName: ProtoField(2, "string")
			}, "optional"),
			time: ProtoField(8, "uint32", "optional"),
			comment: ProtoField(10, "string", "optional")
		}, "repeated"),
		newLatestSequence: ProtoField(3, "uint64", "optional")
	});
	_Oidb.FriendLikeReq = ProtoMessage.of({
		targetUid: ProtoField(11, "string"),
		field2: ProtoField(12, "uint32"),
		count: ProtoField(13, "uint32")
	});
	_Oidb.GroupFileDeleteReq = ProtoMessage.of({ delete: ProtoField(4, {
		groupCode: ProtoField(1, "uint32"),
		busId: ProtoField(3, "uint32"),
		fileId: ProtoField(5, "string")
	}) });
	_Oidb.GroupFileDeleteResp = ProtoMessage.of({ delete: ProtoField(4, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	}) });
	_Oidb.GroupFileMoveReq = ProtoMessage.of({ move: ProtoField(6, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		busId: ProtoField(3, "uint32"),
		fileId: ProtoField(4, "string"),
		parentDirectory: ProtoField(5, "string"),
		targetDirectory: ProtoField(6, "string")
	}) });
	_Oidb.GroupFileMoveResp = ProtoMessage.of({ move: ProtoField(6, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	}) });
	_Oidb.GroupRemarkReq = ProtoMessage.of({ body: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		targetRemark: ProtoField(3, "string")
	}) });
	_Oidb.GroupFolderCreateReq = ProtoMessage.of({ create: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		rootDirectory: ProtoField(3, "string"),
		folderName: ProtoField(4, "string")
	}) });
	_Oidb.GroupFolderCreateResp = ProtoMessage.of({ create: ProtoField(1, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string"),
		folderInfo: ProtoField(4, {
			folderId: ProtoField(1, "string"),
			folderPath: ProtoField(2, "string"),
			folderName: ProtoField(3, "string")
		})
	}) });
	_Oidb.GroupFolderDeleteReq = ProtoMessage.of({ delete: ProtoField(2, {
		groupCode: ProtoField(1, "uint32"),
		folderId: ProtoField(3, "string")
	}) });
	_Oidb.GroupFolderDeleteResp = ProtoMessage.of({ delete: ProtoField(2, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	}) });
	_Oidb.GroupFolderRenameReq = ProtoMessage.of({ rename: ProtoField(3, {
		groupCode: ProtoField(1, "uint32"),
		folderId: ProtoField(3, "string"),
		newFolderName: ProtoField(4, "string")
	}) });
	_Oidb.GroupFolderRenameResp = ProtoMessage.of({ rename: ProtoField(3, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	}) });
	_Oidb.GetGroupRecommendContactArkReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		groupCode: ProtoField(2, "uint32"),
		field5: ProtoField(5, "uint32")
	});
	_Oidb.GetGroupRecommendContactArkResp = ProtoMessage.of({ ark: ProtoField(5, "string") });
	_Oidb.SetGroupMsgMaskReq = ProtoMessage.of({ body: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		setting: ProtoField(2, {
			selfUid: ProtoField(1, "string"),
			msgMask: ProtoField(4, "uint32")
		}),
		field3: ProtoField(3, "uint32"),
		field4: ProtoField(4, "uint32")
	}) });
	_Oidb.SetGroupMsgMaskResp = ProtoMessage.of({ body: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		errCode: ProtoField(2, "uint32")
	}) });
	_Oidb.TransGroupFileReq = ProtoMessage.of({ body: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		busId: ProtoField(3, "uint32"),
		fileId: ProtoField(4, "string")
	}) });
	_Oidb.TransGroupFileResp = ProtoMessage.of({
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	});
	_Oidb.FetchProfileLikeReq = ProtoMessage.of({
		selfUid: ProtoField(1, "string"),
		field2: ProtoField(2, "uint32"),
		field3: ProtoField(3, "uint32"),
		field4: ProtoField(4, "uint32"),
		field101: ProtoField(101, "uint32"),
		start: ProtoField(102, "int64"),
		count: ProtoField(103, "uint32")
	});
	_Oidb.FetchProfileLikeResp = ProtoMessage.of({
		userLikeInfo: ProtoField(1, {
			targetUid: ProtoField(1, "string"),
			field2: ProtoField(2, "uint32"),
			favoriteInfo: ProtoField(3, { users: ProtoField(4, {
				uid: ProtoField(1, "string"),
				src: ProtoField(2, "uint32"),
				latestTime: ProtoField(3, "uint32"),
				count: ProtoField(4, "uint32"),
				giftCount: ProtoField(5, "uint32"),
				customId: ProtoField(6, "uint32"),
				lastCharged: ProtoField(8, "uint32"),
				bTodayVotedCnt: ProtoField(22, "uint32"),
				nick: ProtoField(101, "string"),
				gender: ProtoField(102, "uint32"),
				age: ProtoField(103, "uint32"),
				isvip: ProtoField(105, "bool"),
				isSvip: ProtoField(106, "bool")
			}, "repeated") }),
			voteInfo: ProtoField(4, {
				totalCount: ProtoField(1, "uint32"),
				users: ProtoField(5, {
					uid: ProtoField(1, "string"),
					src: ProtoField(2, "uint32"),
					latestTime: ProtoField(3, "uint32"),
					count: ProtoField(4, "uint32"),
					giftCount: ProtoField(5, "uint32"),
					customId: ProtoField(6, "uint32"),
					lastCharged: ProtoField(8, "uint32"),
					bTodayVotedCnt: ProtoField(22, "uint32"),
					nick: ProtoField(101, "string"),
					gender: ProtoField(102, "uint32"),
					age: ProtoField(103, "uint32"),
					isvip: ProtoField(105, "bool"),
					isSvip: ProtoField(106, "bool")
				}, "repeated")
			})
		}),
		start: ProtoField(101, "uint32")
	});
	_Oidb.FetchProfileLikeCountReq = ProtoMessage.of({ uid: ProtoField(1, "string") });
	_Oidb.FetchProfileLikeCountResp = ProtoMessage.of({ body: ProtoField(1, { voteInfo: ProtoField(4, { totalCount: ProtoField(1, "uint32") }) }) });
	_Oidb.RenameGroupFileReq = ProtoMessage.of({ rename: ProtoField(5, {
		groupCode: ProtoField(1, "uint32"),
		busId: ProtoField(3, "uint32"),
		fileId: ProtoField(4, "string"),
		parentDirectory: ProtoField(5, "string"),
		newFileName: ProtoField(6, "string")
	}) });
	_Oidb.RenameGroupFileResp = ProtoMessage.of({ rename: ProtoField(5, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string")
	}) });
	_Oidb.ModifySelfProfileReq = ProtoMessage.of({
		selfUin: ProtoField(1, "uint32"),
		bytesProperties: ProtoField(2, {
			key: ProtoField(1, "uint32"),
			value: ProtoField(2, "bytes")
		}, "repeated"),
		numberProperties: ProtoField(3, {
			key: ProtoField(1, "uint32"),
			value: ProtoField(2, "uint32")
		}, "repeated")
	});
	_Oidb.FetchEmojiLikesReq = ProtoMessage.of({
		groupCode: ProtoField(2, "uint32"),
		msgSeq: ProtoField(3, "uint32"),
		chatType: ProtoField(4, "uint32"),
		emojiCode: ProtoField(5, "string"),
		cookie: ProtoField(6, "string"),
		field7: ProtoField(7, "uint32"),
		count: ProtoField(8, "uint32")
	});
	_Oidb.FetchEmojiLikesResp = ProtoMessage.of({
		users: ProtoField(1, { uin: ProtoField(1, "uint32") }, "repeated"),
		cookie: ProtoField(2, "string"),
		isLastPage: ProtoField(3, "bool"),
		isFirstPage: ProtoField(4, "bool")
	});
	_Oidb.FlashFileSetIdByCodeReq = ProtoMessage.of({ code: ProtoField(1, "string") });
	_Oidb.FlashFileSetIdByCodeResp = ProtoMessage.of({ fileSetId: ProtoField(1, "string") });
	_Oidb.FlashFileInfoReq = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		field2: ProtoField(2, "uint32")
	});
	const FlashFileShareLink = ProtoMessage.of({ url: ProtoField(1, "string") });
	_Oidb.FlashFileInfoResp = ProtoMessage.of({ info: ProtoField(1, {
		fileSetId: ProtoField(1, "string"),
		title: ProtoField(2, "string"),
		subtitle: ProtoField(3, "string"),
		field4: ProtoField(4, "uint32"),
		totalSize: ProtoField(5, "uint32"),
		shareInfo: ProtoField(8, FlashFileShareLink, "optional"),
		field11: ProtoField(11, "uint32"),
		createTime: ProtoField(13, "uint32"),
		expireTime: ProtoField(14, "uint32")
	}, "optional") });
	_Oidb.FlashFileListReq = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		paging: ProtoField(2, {
			cookie: ProtoField(1, "bytes"),
			field2: ProtoField(2, "uint32"),
			count: ProtoField(3, "uint32"),
			field4: ProtoField(4, "bytes"),
			flags1: ProtoField(5, { field1: ProtoField(1, "uint32") }),
			flags2: ProtoField(6, {
				field1: ProtoField(1, "uint32"),
				field2: ProtoField(2, "uint32")
			})
		}),
		field3: ProtoField(3, "uint32"),
		field4: ProtoField(4, "uint32")
	});
	const FlashFileEntry = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		fileUuid: ProtoField(2, "string"),
		field5: ProtoField(5, "uint32"),
		field6: ProtoField(6, "uint32"),
		fileTypeFlag: ProtoField(7, "uint32"),
		name: ProtoField(8, "string"),
		name2: ProtoField(9, "string"),
		fileSize: ProtoField(11, "uint32"),
		downloadToken: ProtoField(13, {
			token: ProtoField(1, "string"),
			tokenWithKind: ProtoField(2, {
				kind: ProtoField(1, "uint32"),
				token: ProtoField(2, "string")
			}),
			sha1Hex: ProtoField(3, "string"),
			field4: ProtoField(4, "uint32"),
			md5Hex: ProtoField(5, "string"),
			field6: ProtoField(6, "uint32"),
			field7: ProtoField(7, "uint32")
		}, "optional"),
		historyToken: ProtoField(14, {
			token: ProtoField(1, "string"),
			field3: ProtoField(3, "uint32")
		}, "optional"),
		fileUuid2: ProtoField(15, "string"),
		field18: ProtoField(18, "uint32"),
		sha1Hex: ProtoField(20, "string"),
		fileSize2: ProtoField(21, "uint32"),
		md5Hex: ProtoField(25, "string")
	});
	_Oidb.FlashFileListResp = ProtoMessage.of({ result: ProtoField(1, {
		field2: ProtoField(2, "uint32"),
		files: ProtoField(3, FlashFileEntry, "repeated")
	}, "optional") });
	_Oidb.FlashFileGetFileInfoReq = ProtoMessage.of({
		fileUuid: ProtoField(1, "string"),
		fileSetId: ProtoField(2, "string"),
		field3: ProtoField(3, "uint32")
	});
	_Oidb.FlashFileGetFileInfoResp = ProtoMessage.of({ wrap: ProtoField(1, {
		fileUuid: ProtoField(1, "string"),
		file: ProtoField(2, FlashFileEntry, "optional")
	}, "optional") });
	_Oidb.FlashFileDownloadReq = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		sceneType: ProtoField(2, "uint32")
	});
	_Oidb.CreateFlashFileSetReq = ProtoMessage.of({
		totalFileCount: ProtoField(1, "uint32"),
		meta: ProtoField(2, {
			title: ProtoField(2, "string"),
			subtitle: ProtoField(3, "string"),
			field4: ProtoField(4, "uint32"),
			totalFileSize: ProtoField(5, "uint32"),
			uploader: ProtoField(10, {
				uin: ProtoField(1, "string"),
				nickname: ProtoField(2, "string"),
				uid: ProtoField(3, "string"),
				field4: ProtoField(4, "bytes")
			}),
			field16: ProtoField(16, "uint32"),
			field20: ProtoField(20, "uint32"),
			field21: ProtoField(21, "uint32"),
			field23: ProtoField(23, "uint32"),
			field24: ProtoField(24, {
				field2: ProtoField(2, "uint32"),
				field3: ProtoField(3, "bytes")
			}, "optional")
		}),
		field3: ProtoField(3, "uint32"),
		field12: ProtoField(12, "uint32")
	});
	_Oidb.CreateFlashFileSetResp = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		fileSetIdEcho: ProtoField(2, "string"),
		shareLink: ProtoField(3, "string"),
		expireTime: ProtoField(4, "uint32"),
		expireLeftTime: ProtoField(5, "uint32")
	});
	_Oidb.RegisterFlashFileReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		fileSetId: ProtoField(2, "string"),
		fileSetIdEcho: ProtoField(3, "string"),
		file: ProtoField(4, {
			fileSetId: ProtoField(1, "string"),
			fileUuid: ProtoField(2, "string"),
			field3: ProtoField(3, "uint32"),
			field4: ProtoField(4, "bytes"),
			field5: ProtoField(5, "uint32"),
			field6: ProtoField(6, "uint32"),
			field7: ProtoField(7, "uint32"),
			name: ProtoField(8, "string"),
			name2: ProtoField(9, "string"),
			field10: ProtoField(10, "uint32"),
			fileSize: ProtoField(11, "uint32"),
			field12: ProtoField(12, "uint32"),
			sha1Hex: ProtoField(20, "string", "optional"),
			field24: ProtoField(24, "bytes", "optional"),
			md5Hex: ProtoField(25, "string", "optional")
		}),
		field5: ProtoField(5, "uint32"),
		field6: ProtoField(6, "uint32")
	});
	_Oidb.PrepFlashFileSetReq = ProtoMessage.of({
		fileSetId: ProtoField(1, "string"),
		field2: ProtoField(2, "bytes")
	});
	_Oidb.FlashFileUploadPreReq = ProtoMessage.of({
		head: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			scene: ProtoField(2, {
				requestType: ProtoField(101, "uint32"),
				businessType: ProtoField(102, "uint32"),
				field103: ProtoField(103, "uint32"),
				sceneType: ProtoField(200, "uint32")
			}),
			client: ProtoField(3, { agentType: ProtoField(1, "uint32") })
		}),
		upload: ProtoField(2, {
			uploadInfo: ProtoField(1, {
				fileInfo: ProtoField(1, {
					fileSize: ProtoField(1, "uint32"),
					md5: ProtoField(2, "bytes"),
					sha1: ProtoField(3, "string"),
					name: ProtoField(4, "string"),
					fileType: ProtoField(5, {
						field1: ProtoField(1, "uint32"),
						field2: ProtoField(2, "uint32"),
						field3: ProtoField(3, "uint32"),
						field4: ProtoField(4, "uint32")
					}),
					width: ProtoField(6, "uint32"),
					height: ProtoField(7, "uint32"),
					field8: ProtoField(8, "uint32"),
					field9: ProtoField(9, "uint32")
				}),
				subFileType: ProtoField(2, "uint32")
			}),
			tryFastUploadCompleted: ProtoField(2, "bool"),
			srvSendMsg: ProtoField(3, "bool"),
			clientRandomId: ProtoField(4, "uint32"),
			compatQMsgSceneType: ProtoField(5, "uint32"),
			extBizInfo: ProtoField(6, {
				field1: ProtoField(1, {
					field1: ProtoField(1, "uint32"),
					field2: ProtoField(2, "bytes")
				}),
				field2: ProtoField(2, { field1: ProtoField(1, "uint32") }, "optional")
			})
		})
	});
	_Oidb.FlashFileUploadCommitReq = ProtoMessage.of({
		head: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			scene: ProtoField(2, {
				requestType: ProtoField(101, "uint32"),
				businessType: ProtoField(102, "uint32"),
				field103: ProtoField(103, "uint32"),
				sceneType: ProtoField(200, "uint32")
			}),
			client: ProtoField(3, { agentType: ProtoField(1, "uint32") })
		}),
		commit: ProtoField(12, {
			fileSummary: ProtoField(1, {
				fileInfo: ProtoField(1, {
					fileSize: ProtoField(1, "uint32"),
					md5: ProtoField(2, "bytes"),
					sha1: ProtoField(3, "string"),
					name: ProtoField(4, "string"),
					fileType: ProtoField(5, {
						field1: ProtoField(1, "uint32"),
						field2: ProtoField(2, "uint32"),
						field3: ProtoField(3, "uint32"),
						field4: ProtoField(4, "uint32")
					}),
					width: ProtoField(6, "uint32"),
					height: ProtoField(7, "uint32"),
					field8: ProtoField(8, "uint32"),
					field9: ProtoField(9, "uint32")
				}),
				token: ProtoField(2, "string"),
				field3: ProtoField(3, "uint32"),
				time: ProtoField(4, "uint32"),
				ttl: ProtoField(5, "uint32"),
				field6: ProtoField(6, "uint32")
			}),
			field2: ProtoField(2, { field1: ProtoField(1, "uint32") }),
			field3: ProtoField(3, {
				field1: ProtoField(1, "uint32"),
				field2: ProtoField(2, "uint32")
			}),
			target: ProtoField(10, {
				fileSetId: ProtoField(1, "string"),
				fileSetId2: ProtoField(2, "string"),
				fileUuid: ProtoField(3, "string"),
				field4: ProtoField(4, "uint32"),
				field5: ProtoField(5, "uint32"),
				field6: ProtoField(6, "uint32"),
				fileTypeFlag: ProtoField(7, "uint32"),
				field8: ProtoField(8, "bytes"),
				field9: ProtoField(9, "uint32"),
				field10: ProtoField(10, "uint32"),
				field11: ProtoField(11, "uint32"),
				field12: ProtoField(12, "uint32"),
				field13: ProtoField(13, "uint32"),
				field14: ProtoField(14, "uint32")
			})
		})
	});
	_Oidb.FlashFileUploadResp = ProtoMessage.of({
		head: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			retCode: ProtoField(3, "string", "optional")
		}),
		body: ProtoField(2, {
			uKey: ProtoField(1, "string", "optional"),
			uKeyTtlSecond: ProtoField(2, "uint32"),
			fastUploadInfo: ProtoField(6, { summary: ProtoField(1, {
				fileSummary: ProtoField(1, {
					fileInfo: ProtoField(1, {
						fileSize: ProtoField(1, "uint32"),
						sha1: ProtoField(3, "string"),
						name: ProtoField(4, "string"),
						md5: ProtoField(5, "bytes"),
						width: ProtoField(6, "uint32"),
						height: ProtoField(7, "uint32"),
						field9: ProtoField(9, "uint32")
					}),
					token: ProtoField(2, "string"),
					field3: ProtoField(3, "uint32"),
					time: ProtoField(4, "uint32"),
					ttl: ProtoField(5, "uint32"),
					field7: ProtoField(7, "uint32")
				}),
				field5: ProtoField(5, "uint32")
			}) }, "optional")
		}, "optional"),
		commitInfo: ProtoField(12, { summary: ProtoField(1, {
			token: ProtoField(2, "string"),
			field3: ProtoField(3, "uint32"),
			time: ProtoField(4, "uint32"),
			ttl: ProtoField(5, "uint32")
		}, "optional") }, "optional")
	});
	_Oidb.FlashFileDownloadPreReq = ProtoMessage.of({
		head: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			scene: ProtoField(2, {
				requestType: ProtoField(101, "uint32"),
				businessType: ProtoField(102, "uint32"),
				field103: ProtoField(103, "uint32"),
				sceneType: ProtoField(200, "uint32")
			}),
			client: ProtoField(3, { agentType: ProtoField(1, "uint32") })
		}),
		download: ProtoField(3, {
			info: ProtoField(1, {
				fileInfo: ProtoField(1, {
					fileSize: ProtoField(1, "uint32"),
					md5: ProtoField(2, "bytes"),
					sha1: ProtoField(3, "bytes"),
					name: ProtoField(4, "string"),
					fileType: ProtoField(5, {
						field1: ProtoField(1, "uint32"),
						field2: ProtoField(2, "uint32"),
						field3: ProtoField(3, "uint32"),
						field4: ProtoField(4, "uint32")
					}),
					width: ProtoField(6, "uint32"),
					height: ProtoField(7, "uint32"),
					field8: ProtoField(8, "uint32"),
					field9: ProtoField(9, "uint32")
				}),
				fileId: ProtoField(2, "string"),
				field3: ProtoField(3, "uint32"),
				field4: ProtoField(4, "uint32"),
				field5: ProtoField(5, "uint32"),
				field6: ProtoField(6, "uint32")
			}),
			clientCaps: ProtoField(2, {
				capsBody: ProtoField(2, {
					field1: ProtoField(1, "uint32"),
					field3: ProtoField(3, "uint32"),
					field5: ProtoField(5, "uint32"),
					field6: ProtoField(6, {
						field1: ProtoField(1, "uint32"),
						field2: ProtoField(2, "bytes"),
						field3: ProtoField(3, "bytes"),
						field4: ProtoField(4, "uint32")
					})
				}),
				smallFlag: ProtoField(4, { field1: ProtoField(1, "uint32") }),
				target: ProtoField(10, {
					fileSetId: ProtoField(1, "string"),
					fileUuid: ProtoField(2, "string"),
					field3: ProtoField(3, "uint32"),
					fileUuid2: ProtoField(4, "string")
				})
			}),
			field3: ProtoField(3, "uint32")
		})
	});
	_Oidb.FlashFileDownloadPreResp = ProtoMessage.of({
		head: ProtoField(1, {
			common: ProtoField(1, {
				requestId: ProtoField(1, "uint32"),
				command: ProtoField(2, "uint32")
			}),
			retCode: ProtoField(3, "string", "optional")
		}),
		body: ProtoField(3, {
			rkey: ProtoField(1, "string"),
			ttl: ProtoField(2, "uint32"),
			url: ProtoField(3, {
				host: ProtoField(1, "string"),
				path: ProtoField(2, "string"),
				port: ProtoField(3, "uint32")
			})
		}, "optional")
	});
	_Oidb.FetchGroupAtAllRemainReq = ProtoMessage.of({
		subCmd: ProtoField(1, "uint32"),
		limitIntervalTypeForUin: ProtoField(2, "uint32"),
		limitIntervalTypeForGroup: ProtoField(3, "uint32"),
		uin: ProtoField(4, "uint32"),
		groupCode: ProtoField(5, "uint32")
	});
	_Oidb.FetchGroupAtAllRemainResp = ProtoMessage.of({
		canAtAll: ProtoField(1, "bool"),
		remainAtAllCountForUin: ProtoField(2, "uint32"),
		remainAtAllCountForGroup: ProtoField(3, "uint32"),
		atTimesMsg: ProtoField(4, "string"),
		canNotAtAllMsg: ProtoField(5, "string", "optional")
	});
	_Oidb.FetchGroupExtraReq = ProtoMessage.of({
		random: ProtoField(1, "uint32"),
		config: ProtoField(2, {
			groupCode: ProtoField(1, "uint32"),
			flags: ProtoField(2, { latestMessageSeq: ProtoField(22, "bool") })
		})
	});
	_Oidb.FetchGroupExtraResp = ProtoMessage.of({ info: ProtoField(1, {
		groupCode: ProtoField(1, "uint32"),
		results: ProtoField(3, { latestMessageSeq: ProtoField(22, "uint32") })
	}) });
	_Oidb.SetInputStatusReq = ProtoMessage.of({ body: ProtoField(1, {
		toUid: ProtoField(1, "string"),
		field2: ProtoField(2, "uint32"),
		eventType: ProtoField(3, "uint32")
	}) });
	_Oidb.SetInputStatusResp = ProtoMessage.of({ body: ProtoField(1, { retCode: ProtoField(1, "uint32") }) });
	_Oidb.GetFriendsStatusReq = ProtoMessage.of({
		selfUid: ProtoField(1, "string"),
		field5: ProtoField(5, "uint32"),
		field7: ProtoField(7, "uint32"),
		field100: ProtoField(100, "uint32"),
		field101: ProtoField(101, "uint32")
	});
	_Oidb.GetFriendsStatusResp = ProtoMessage.of({ list: ProtoField(5, {
		uid: ProtoField(1, "string"),
		status: ProtoField(2, "uint32")
	}, "repeated") });
	_Oidb.ForwardGroupFileReq = ProtoMessage.of({ copyToReq: ProtoField(3, {
		groupCode: ProtoField(1, "uint32"),
		appId: ProtoField(2, "uint32"),
		srcBusId: ProtoField(3, "uint32"),
		srcFileId: ProtoField(4, "string"),
		dstBusId: ProtoField(5, "uint32"),
		dstUin: ProtoField(6, "uint32"),
		newFileName: ProtoField(40, "string"),
		timCloudPdirKey: ProtoField(100, "bytes"),
		timCloudPpdirKey: ProtoField(101, "bytes"),
		timCloudExtensionInfo: ProtoField(102, "bytes"),
		timFileExistOption: ProtoField(103, "uint32")
	}) });
	_Oidb.ForwardGroupFileResp = ProtoMessage.of({ copyToRsp: ProtoField(3, {
		retCode: ProtoField(1, "int64"),
		retMsg: ProtoField(2, "string"),
		clientWording: ProtoField(3, "string"),
		saveFilePath: ProtoField(4, "string"),
		busId: ProtoField(5, "uint32"),
		fileName: ProtoField(40, "string")
	}) });
})(Oidb || (Oidb = {}));
//#endregion
//#region src/ntqqapi/proto/msg.ts
var Msg;
(function(_Msg) {
	_Msg.VideoFileMsg = ProtoMessage.of({
		fileUuid: ProtoField(1, "string", "optional"),
		fileMd5: ProtoField(2, "bytes", "optional"),
		fileName: ProtoField(3, "string", "optional"),
		fileFormat: ProtoField(4, "uint32", "optional"),
		fileTime: ProtoField(5, "uint32", "optional"),
		fileSize: ProtoField(6, "uint32", "optional"),
		thumbWidth: ProtoField(7, "uint32", "optional"),
		thumbHeight: ProtoField(8, "uint32", "optional"),
		thumbFileMd5: ProtoField(9, "bytes", "optional"),
		source: ProtoField(10, "bytes", "optional"),
		thumbFileSize: ProtoField(11, "uint32", "optional"),
		busiType: ProtoField(12, "uint32", "optional"),
		fromChatType: ProtoField(13, "uint32", "optional"),
		toChatType: ProtoField(14, "uint32", "optional"),
		boolSupportProgressive: ProtoField(15, "bool", "optional"),
		fileWidth: ProtoField(16, "uint32", "optional"),
		fileHeight: ProtoField(17, "uint32", "optional"),
		subBusiType: ProtoField(18, "uint32", "optional"),
		videoAttr: ProtoField(19, "uint32", "optional"),
		bytesThumbFileUrls: ProtoField(20, "bytes", "repeated"),
		bytesVideoFileUrls: ProtoField(21, "bytes", "repeated"),
		thumbDownloadFlag: ProtoField(22, "uint32", "optional"),
		fileDownloadFlag: ProtoField(23, "uint32", "optional")
	});
	const Elem = _Msg.Elem = ProtoMessage.of({
		text: ProtoField(1, {
			str: ProtoField(1, "string"),
			link: ProtoField(2, "string", "optional"),
			attr6Buf: ProtoField(3, "bytes", "optional"),
			attr7Buf: ProtoField(4, "bytes", "optional"),
			buf: ProtoField(11, "bytes", "optional"),
			pbReserve: ProtoField(12, "bytes", "optional")
		}, "optional"),
		face: ProtoField(2, {
			index: ProtoField(1, "uint32"),
			old: ProtoField(2, "bytes"),
			buf: ProtoField(11, "bytes", "optional")
		}, "optional"),
		notOnlineImage: ProtoField(4, {
			filePath: ProtoField(1, "string"),
			fileLen: ProtoField(2, "uint32"),
			downloadPath: ProtoField(3, "bytes"),
			oldVerSendFile: ProtoField(4, "bytes"),
			imgType: ProtoField(5, "uint32"),
			previewsImage: ProtoField(6, "bytes"),
			picMd5: ProtoField(7, "bytes"),
			picHeight: ProtoField(8, "uint32"),
			picWidth: ProtoField(9, "uint32"),
			resId: ProtoField(10, "string"),
			flag: ProtoField(11, "bytes"),
			thumbUrl: ProtoField(12, "string"),
			original: ProtoField(13, "uint32"),
			bigUrl: ProtoField(14, "string"),
			origUrl: ProtoField(15, "string"),
			bizType: ProtoField(16, "uint32"),
			result: ProtoField(17, "uint32"),
			index: ProtoField(18, "uint32"),
			opFaceBuf: ProtoField(19, "bytes"),
			oldPicMd5: ProtoField(20, "bool"),
			thumbWidth: ProtoField(21, "uint32"),
			thumbHeight: ProtoField(22, "uint32"),
			fileId: ProtoField(23, "uint32"),
			showLen: ProtoField(24, "uint32"),
			downloadLen: ProtoField(25, "uint32"),
			url400: ProtoField(26, "string"),
			width400: ProtoField(27, "uint32"),
			height400: ProtoField(28, "uint32"),
			pbReserve: ProtoField(29, "bytes")
		}, "optional"),
		transElemInfo: ProtoField(5, {
			elemType: ProtoField(1, "uint32"),
			elemValue: ProtoField(2, "bytes")
		}, "optional"),
		marketFace: ProtoField(6, {
			summary: ProtoField(1, "string", "optional"),
			itemType: ProtoField(2, "uint32", "optional"),
			info: ProtoField(3, "uint32", "optional"),
			faceId: ProtoField(4, "bytes", "optional"),
			tabId: ProtoField(5, "uint32", "optional"),
			subType: ProtoField(6, "uint32", "optional"),
			key: ProtoField(7, "string", "optional"),
			width: ProtoField(10, "uint32", "optional"),
			height: ProtoField(11, "uint32", "optional")
		}, "optional"),
		customFace: ProtoField(8, {
			guid: ProtoField(1, "bytes"),
			filePath: ProtoField(2, "string"),
			shortcut: ProtoField(3, "string"),
			buffer: ProtoField(4, "bytes"),
			flag: ProtoField(5, "bytes"),
			oldData: ProtoField(6, "bytes", "optional"),
			fileId: ProtoField(7, "uint32"),
			serverIp: ProtoField(8, "int32", "optional"),
			serverPort: ProtoField(9, "int32", "optional"),
			fileType: ProtoField(10, "int32"),
			signature: ProtoField(11, "bytes"),
			useful: ProtoField(12, "int32"),
			md5: ProtoField(13, "bytes"),
			thumbUrl: ProtoField(14, "string"),
			bigUrl: ProtoField(15, "string"),
			origUrl: ProtoField(16, "string"),
			bizType: ProtoField(17, "int32"),
			repeatIndex: ProtoField(18, "int32"),
			repeatImage: ProtoField(19, "int32"),
			imageType: ProtoField(20, "int32"),
			index: ProtoField(21, "int32"),
			width: ProtoField(22, "int32"),
			height: ProtoField(23, "int32"),
			source: ProtoField(24, "int32"),
			size: ProtoField(25, "uint32"),
			origin: ProtoField(26, "int32"),
			thumbWidth: ProtoField(27, "int32", "optional"),
			thumbHeight: ProtoField(28, "int32", "optional"),
			showLen: ProtoField(29, "int32"),
			downloadLen: ProtoField(30, "int32"),
			x400Url: ProtoField(31, "string", "optional"),
			x400Width: ProtoField(32, "int32"),
			x400Height: ProtoField(33, "int32"),
			pbReserve: ProtoField(34, {
				subType: ProtoField(1, "int32"),
				field3: ProtoField(3, "int32"),
				field4: ProtoField(4, "int32"),
				summary: ProtoField(9, "string"),
				field10: ProtoField(10, "int32"),
				field21: ProtoField(21, {
					field1: ProtoField(1, "int32"),
					field2: ProtoField(2, "string"),
					field3: ProtoField(3, "int32"),
					field4: ProtoField(4, "int32"),
					field5: ProtoField(5, "int32"),
					md5Str: ProtoField(7, "string")
				}),
				field31: ProtoField(31, "string")
			}, "optional")
		}, "optional"),
		elemFlags2: ProtoField(9, {
			colorTextId: ProtoField(1, "uint64"),
			msgId: ProtoField(2, "uint64"),
			whisperSessionId: ProtoField(3, "uint32"),
			pttChangeBit: ProtoField(4, "uint32"),
			vipStatus: ProtoField(5, "uint32"),
			compatibleId: ProtoField(6, "uint32"),
			insts: ProtoField(7, {
				appId: ProtoField(1, "uint32"),
				instId: ProtoField(2, "uint32")
			}, "repeated"),
			msgRptCnt: ProtoField(8, "uint32"),
			srcInst: ProtoField(9, {
				appId: ProtoField(1, "uint32"),
				instId: ProtoField(2, "uint32")
			}),
			longtitude: ProtoField(10, "uint32"),
			latitude: ProtoField(11, "uint32"),
			customFont: ProtoField(12, "uint32"),
			pcSupportDef: ProtoField(13, {
				pcPtlBegin: ProtoField(1, "uint32"),
				pcPtlEnd: ProtoField(2, "uint32"),
				macPtlBegin: ProtoField(3, "uint32"),
				macPtlEnd: ProtoField(4, "uint32"),
				ptlsSupport: ProtoField(5, "uint32", "repeated"),
				ptlsNotSupport: ProtoField(6, "uint32", "repeated")
			}),
			crmFlags: ProtoField(14, "uint32", "optional")
		}, "optional"),
		richMsg: ProtoField(12, {
			template: ProtoField(1, "bytes"),
			serviceId: ProtoField(2, "int32")
		}, "optional"),
		groupFile: ProtoField(13, {
			filename: ProtoField(1, "string", "optional"),
			fileSize: ProtoField(2, "uint64", "optional"),
			fileId: ProtoField(3, "bytes", "optional"),
			batchId: ProtoField(4, "bytes", "optional"),
			fileKey: ProtoField(5, "bytes", "optional"),
			sequence: ProtoField(7, "uint64", "optional")
		}, "optional"),
		extraInfo: ProtoField(16, {
			nick: ProtoField(1, "string", "optional"),
			groupCard: ProtoField(2, "string", "optional"),
			level: ProtoField(3, "int32"),
			flags: ProtoField(4, "int32"),
			groupMask: ProtoField(5, "int32"),
			msgTailId: ProtoField(6, "int32", "optional"),
			senderTitle: ProtoField(7, "string"),
			apnsTips: ProtoField(8, "string", "optional"),
			uin: ProtoField(9, "uint32", "optional"),
			msgStateFlag: ProtoField(10, "int32", "optional"),
			apnsSoundType: ProtoField(11, "int32", "optional"),
			newGroupFlag: ProtoField(12, "int32", "optional")
		}, "optional"),
		videoFile: ProtoField(19, "bytes", "optional"),
		generalFlags: ProtoField(37, {
			bubbleDiyTextId: ProtoField(1, "uint32"),
			groupFlagNew: ProtoField(2, "int32"),
			uin: ProtoField(3, "uint64"),
			rpId: ProtoField(4, "bytes"),
			prpFold: ProtoField(5, "int32"),
			longTextFlag: ProtoField(6, "int32"),
			longTextResId: ProtoField(7, "string", "optional"),
			groupType: ProtoField(8, "int32"),
			toUinFlag: ProtoField(9, "int32"),
			glamourLevel: ProtoField(10, "int32"),
			memberLevel: ProtoField(11, "int32"),
			groupRankSeq: ProtoField(12, "int64"),
			olympicTorch: ProtoField(13, "int32"),
			babyqGuideMsgCookie: ProtoField(14, "bytes"),
			uin32ExpertFlag: ProtoField(15, "int32"),
			bubbleSubId: ProtoField(16, "int32"),
			pendantId: ProtoField(17, "uint64"),
			rpIndex: ProtoField(18, "bytes"),
			pbReserve: ProtoField(19, "bytes")
		}, "optional"),
		srcMsg: ProtoField(45, {
			origSeqs: ProtoField(1, "uint32", "repeated"),
			senderUin: ProtoField(2, "uint32"),
			time: ProtoField(3, "int32"),
			elems: ProtoField(5, "bytes", "repeated"),
			attr: ProtoField(8, {
				oriMsgType: ProtoField(2, "uint32", "optional"),
				sourceMsgId: ProtoField(3, "uint64"),
				senderUid: ProtoField(6, "string"),
				receiverUid: ProtoField(7, "string", "optional"),
				ntMsgSeq: ProtoField(8, "uint32", "optional")
			}),
			srcMsg: ProtoField(9, "bytes", "optional"),
			toUin: ProtoField(10, "uint32")
		}, "optional"),
		lightApp: ProtoField(51, {
			data: ProtoField(1, "bytes"),
			msgResid: ProtoField(2, "bytes", "optional")
		}, "optional"),
		commonElem: ProtoField(53, {
			serviceType: ProtoField(1, "uint32"),
			pbElem: ProtoField(2, "bytes"),
			businessType: ProtoField(3, "uint32")
		}, "optional")
	});
	const Message = _Msg.Message = ProtoMessage.of({
		routingHead: ProtoField(1, {
			fromUin: ProtoField(1, "uint32"),
			fromUid: ProtoField(2, "string"),
			fromAppid: ProtoField(3, "uint32"),
			fromInstid: ProtoField(4, "uint32"),
			toUin: ProtoField(5, "uint32"),
			toUid: ProtoField(6, "string"),
			c2c: ProtoField(7, {
				c2cType: ProtoField(1, "int32"),
				serviceType: ProtoField(2, "int32"),
				sig: ProtoField(3, "bytes", "optional"),
				fromTinyId: ProtoField(4, "uint32"),
				toTinyId: ProtoField(5, "uint32"),
				name: ProtoField(6, "string")
			}),
			group: ProtoField(8, {
				groupCode: ProtoField(1, "uint32"),
				groupType: ProtoField(2, "uint32"),
				groupInfoSeq: ProtoField(3, "uint64"),
				groupCard: ProtoField(4, "string"),
				groupCardType: ProtoField(5, "uint32"),
				groupLevel: ProtoField(6, "uint32"),
				groupName: ProtoField(7, "string"),
				extGroupKeyInfo: ProtoField(8, "string"),
				msgFlag: ProtoField(9, "uint32")
			}, "optional")
		}),
		/**
		* OlPush.MsgPush 推下来的消息头。**注意：跟 send 时的 SendContentHead 字段布局不同。**
		*
		* 关于 "msgSeq" —— field 5 和 field 11 的语义因 chatType 不同：
		*
		*   群聊 (msgType=82)：
		*     - field 5  (groupMsgSeqOrC2cClientSeq) = server 给整群分配的 msgSeq，**双端 / 群里所有人一致**，
		*                                跟发送方 PbSendMsgResp.groupMsgSeq (field 11) 相等。
		*     - field 11 (c2cMsgSeq)   = 0 / 空（群聊不用）。
		*
		*   私聊 (msgType=166)：
		*     - field 5  (groupMsgSeqOrC2cClientSeq) = **不是 msgSeq**——server 把发送方 PbSendMsg 时填的
		*                                client `clientSequence` (10000-99999 临时号) 原样转发给
		*                                接收方。实测 bot1 固定 clientSequence=55555 时 bot2 收
		*                                到的此字段恒为 55555。撤回 / reply 引用 c2c 消息都用它。
		*     - field 11 (c2cMsgSeq)   = server 给这条消息分配的 **c2cMsgSeq**（全局，
		*                                跨 c2c 会话单调递增），**双端一致**，跟发送方
		*                                PbSendMsgResp.c2cMsgSeq (field 14) 相等。
		*
		* 转 RawMessage 时按 chatType 选取：群用 field 5，私聊用 field 11。
		*/
		contentHead: ProtoField(2, {
			msgType: ProtoField(1, "uint32"),
			subType: ProtoField(2, "uint32"),
			c2cCmd: ProtoField(3, "uint32"),
			/** client 在 PbSendMsg 提交的 32-bit random，server 在两端原样广播。 */
			random: ProtoField(4, "uint32"),
			/** 群聊：双端一致的群 msgSeq（= PbSendMsgResp.groupMsgSeq）。
			*  私聊：发送方 PbSendMsg 时填的 client `clientSequence` (10000-99999)，
			*        server 原样转发给接收方；撤回 / reply 时回传给 server。 */
			groupMsgSeqOrC2cClientSeq: ProtoField(5, "uint32"),
			msgTime: ProtoField(6, "uint32"),
			pkgNum: ProtoField(7, "uint32"),
			pkgIndex: ProtoField(8, "uint32"),
			divSeq: ProtoField(9, "uint32"),
			autoReply: ProtoField(10, "uint32"),
			/** 群聊：通常 0/空。
			*  私聊：双端一致的 c2cMsgSeq（= PbSendMsgResp.c2cMsgSeq）。 */
			c2cMsgSeq: ProtoField(11, "uint32"),
			/** 消息全局 64-bit msgUid。client 端可由 (0x01000000<<32)|random 推出来。 */
			msgUid: ProtoField(12, "uint64"),
			/**
			* SsoGetGroupMsg 拉历史时，server 不填 field 12 的 msgUid，
			* 而是把同样语义的 64-bit id 放在 field 32（PC NT 客户端协议特有的）。
			* convertToRawMessage 里 fallback 到这个字段，msgId 才能拿到稳定的全局唯一值。
			*/
			msgUidAlt: ProtoField(32, "uint64", "optional"),
			forward: ProtoField(15, {
				field1: ProtoField(1, "uint32"),
				field2: ProtoField(2, "uint32"),
				field3: ProtoField(3, "uint32"),
				field4: ProtoField(4, "string"),
				avatar: ProtoField(5, "string")
			}, "optional")
		}),
		body: ProtoField(3, {
			richText: ProtoField(1, {
				attr: ProtoField(1, {
					codePage: ProtoField(1, "int32"),
					time: ProtoField(2, "int32"),
					random: ProtoField(3, "int32"),
					color: ProtoField(4, "int32"),
					size: ProtoField(5, "int32"),
					effect: ProtoField(6, "int32"),
					charSet: ProtoField(7, "int32"),
					pitchAndFamily: ProtoField(8, "int32"),
					fontName: ProtoField(9, "string"),
					reserveData: ProtoField(10, "bytes")
				}),
				elems: ProtoField(2, Elem, "repeated")
			}),
			msgContent: ProtoField(2, "bytes"),
			msgEncryptContent: ProtoField(3, "bytes")
		}, "optional")
	});
	const PbMultiMsgItem = _Msg.PbMultiMsgItem = ProtoMessage.of({
		fileName: ProtoField(1, "string"),
		buffer: ProtoField(2, { msg: ProtoField(1, "bytes", "repeated") })
	});
	_Msg.PbMultiMsgTransmit = ProtoMessage.of({
		msg: ProtoField(1, Message, "repeated"),
		pbItemList: ProtoField(2, PbMultiMsgItem, "repeated")
	});
	_Msg.PushMsg = ProtoMessage.of({ message: ProtoField(1, Message) });
	_Msg.KickNTPush = ProtoMessage.of({
		uin: ProtoField(1, "uint32"),
		tipsDesc: ProtoField(3, "string"),
		tipsTitle: ProtoField(4, "string"),
		/** 1001 = 异地登录顶号？；2001 = 服务端主动踢出 */
		code: ProtoField(5, "uint32"),
		/** 时间戳或某种 token */
		field6: ProtoField(6, "uint32")
	});
	_Msg.QSmallFaceExtra = ProtoMessage.of({
		faceId: ProtoField(1, "uint32"),
		text: ProtoField(2, "string"),
		compatText: ProtoField(3, "string")
	});
	_Msg.LargeFaceExtra = ProtoMessage.of({
		aniStickerPackId: ProtoField(1, "string", "optional"),
		aniStickerId: ProtoField(2, "string", "optional"),
		faceId: ProtoField(3, "int32", "optional"),
		field4: ProtoField(4, "int32", "optional"),
		aniStickerType: ProtoField(5, "int32", "optional"),
		field6: ProtoField(6, "string", "optional"),
		preview: ProtoField(7, "string", "optional"),
		field9: ProtoField(9, "int32", "optional"),
		/** dice/rps 才有：1-6 / 1-3 表示骰子点数或猜拳手势 */
		resultId: ProtoField(11, "int32", "optional")
	});
	_Msg.GroupFileExtra = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		fileName: ProtoField(2, "string"),
		display: ProtoField(3, "string"),
		inner: ProtoField(7, { info: ProtoField(2, {
			busId: ProtoField(1, "uint32"),
			fileId: ProtoField(2, "string"),
			fileSize: ProtoField(3, "uint32"),
			fileName: ProtoField(4, "string"),
			field5: ProtoField(5, "uint32", "optional"),
			field7: ProtoField(7, "string", "optional"),
			fileMd5: ProtoField(8, "string")
		}) })
	});
	_Msg.FileExtra = ProtoMessage.of({ file: ProtoField(1, {
		fileType: ProtoField(1, "uint32"),
		sig: ProtoField(2, "bytes", "optional"),
		fileUuid: ProtoField(3, "string"),
		fileMd5: ProtoField(4, "bytes", "optional"),
		fileName: ProtoField(5, "string"),
		fileSize: ProtoField(6, "uint32"),
		note: ProtoField(7, "bytes", "optional"),
		reserved: ProtoField(8, "uint32"),
		subCmd: ProtoField(9, "uint32"),
		microCloud: ProtoField(10, "uint32"),
		fileUrls: ProtoField(11, "bytes", "repeated"),
		downloadFlag: ProtoField(12, "uint32"),
		dangerLevel: ProtoField(50, "uint32"),
		lifeTime: ProtoField(51, "uint32"),
		uploadTime: ProtoField(52, "uint32"),
		absFileType: ProtoField(53, "uint32"),
		clientType: ProtoField(54, "uint32"),
		expireTime: ProtoField(55, "uint32"),
		pbReserve: ProtoField(56, "bytes", "optional"),
		fileIdCrcMedia: ProtoField(57, "string")
	}) });
	_Msg.PbSendMsg = ProtoMessage.of({
		routingHead: ProtoField(1, {
			c2c: ProtoField(1, {
				toUin: ProtoField(1, "uint32", "optional"),
				toUid: ProtoField(2, "string", "optional")
			}, "optional"),
			group: ProtoField(2, { groupCode: ProtoField(1, "uint32") }, "optional"),
			groupTemp: ProtoField(3, {
				groupCode: ProtoField(3, "uint32"),
				toUid: ProtoField(4, "string")
			}, "optional"),
			trans0X211: ProtoField(15, {
				toUin: ProtoField(1, "uint32", "optional"),
				ccCmd: ProtoField(2, "uint32", "optional"),
				uid: ProtoField(8, "string", "optional")
			}, "optional")
		}),
		contentHead: ProtoField(2, {
			pkgNum: ProtoField(1, "uint32", "optional"),
			pkgIndex: ProtoField(2, "uint32", "optional"),
			divSeq: ProtoField(3, "uint32", "optional"),
			autoReply: ProtoField(4, "uint32", "optional")
		}, "optional"),
		body: ProtoField(3, {
			richText: ProtoField(1, { elems: ProtoField(2, Elem, "repeated") }, "optional"),
			msgContent: ProtoField(2, "bytes", "optional")
		}),
		clientSequence: ProtoField(4, "uint32", "optional"),
		random: ProtoField(5, "uint32"),
		syncCookie: ProtoField(6, "bytes", "optional"),
		via: ProtoField(8, "uint32", "optional"),
		control: ProtoField(12, { msgFlag: ProtoField(1, "uint32") }, "optional"),
		multiSendSeq: ProtoField(14, "uint32", "optional")
	});
	_Msg.PbSendMsgResp = ProtoMessage.of({
		resultCode: ProtoField(1, "int32"),
		errMsg: ProtoField(2, "string", "optional"),
		sendTime: ProtoField(3, "uint32", "optional"),
		msgInfoFlag: ProtoField(10, "uint32", "optional"),
		/** 群聊用：双端一致的群 msgSeq；私聊为空。 */
		groupMsgSeq: ProtoField(11, "uint32", "optional"),
		/** 私聊用：双端一致的 c2c ntMsgSeq；群聊为空。 */
		c2cMsgSeq: ProtoField(14, "uint32", "optional")
	});
	_Msg.PttTransGroupReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		body: ProtoField(2, {
			msgUid: ProtoField(1, "uint64"),
			senderUin: ProtoField(2, "uint32"),
			groupUin: ProtoField(3, "uint32"),
			field4: ProtoField(4, "uint32"),
			voiceMd5Hex: ProtoField(5, "string"),
			field6: ProtoField(6, "uint32"),
			field7: ProtoField(7, "uint32"),
			field8: ProtoField(8, "uint32"),
			voiceFileId: ProtoField(9, "string"),
			field10: ProtoField(10, "uint32")
		}),
		field5: ProtoField(5, "uint32"),
		field6: ProtoField(6, "uint32"),
		field10: ProtoField(10, "uint32")
	});
	_Msg.PttTransC2CReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		body: ProtoField(3, {
			msgUid: ProtoField(1, "uint64"),
			senderUin: ProtoField(2, "uint32"),
			receiverUin: ProtoField(3, "uint32"),
			voiceFileId: ProtoField(4, "string"),
			field5: ProtoField(5, "uint32"),
			field6: ProtoField(6, "uint32"),
			field7: ProtoField(7, "uint32"),
			field8: ProtoField(8, "uint32"),
			voiceMd5Hex: ProtoField(9, "string")
		}),
		field5: ProtoField(5, "uint32"),
		field6: ProtoField(6, "uint32"),
		field10: ProtoField(10, "uint32")
	});
	_Msg.PttTransResultPush = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		body: ProtoField(2, {
			msgUid: ProtoField(1, "uint64"),
			/** 1 = group, 2 = c2c */
			chatType: ProtoField(2, "uint32"),
			field3: ProtoField(3, "uint32"),
			field4: ProtoField(4, "uint32"),
			field5: ProtoField(5, "uint32"),
			field6: ProtoField(6, "uint32"),
			field7: ProtoField(7, "uint32"),
			/** 转写文字 */
			text: ProtoField(8, "string"),
			senderUin: ProtoField(9, "uint32"),
			/** group: groupCode；c2c: 收件人 uin */
			groupOrReceiverUin: ProtoField(10, "uint32")
		})
	});
	_Msg.FaceroamOpReq = ProtoMessage.of({
		comm: ProtoField(1, {
			imPlat: ProtoField(1, "uint32"),
			osVersion: ProtoField(2, "string"),
			qVersion: ProtoField(3, "string", "optional")
		}),
		selfUin: ProtoField(2, "uint64"),
		/** 1 = 列表, 2 = 删除 */
		subCmd: ProtoField(3, "uint32"),
		/** 删除时填要删的 emoji_id 列表 */
		deleteList: ProtoField(5, { emojiId: ProtoField(1, "string") }, "repeated"),
		field6: ProtoField(6, "uint32", "optional")
	});
	_Msg.FaceroamListResp = ProtoMessage.of({
		retCode: ProtoField(1, "uint32"),
		errMsg: ProtoField(2, "string"),
		subCmd: ProtoField(3, "uint32"),
		userInfo: ProtoField(4, {
			fileName: ProtoField(1, "string", "repeated"),
			deleteFile: ProtoField(2, "string", "repeated"),
			bid: ProtoField(3, "string"),
			maxRoamSize: ProtoField(4, "uint32")
		}),
		/** 每个 emoji 对应的 type（与 fileName 等长） */
		emojiType: ProtoField(5, "uint32", "repeated")
	});
	_Msg.FaceroamDeleteResp = ProtoMessage.of({
		retCode: ProtoField(1, "uint32"),
		errMsg: ProtoField(2, "string"),
		subCmd: ProtoField(3, "uint32"),
		results: ProtoField(5, {
			emojiId: ProtoField(1, "string"),
			status: ProtoField(2, "uint32")
		}, "repeated")
	});
	_Msg.BDHExpressionRoamReq = ProtoMessage.of({
		field1: ProtoField(1, "uint32"),
		field2: ProtoField(2, "uint32"),
		body: ProtoField(3, {
			field1: ProtoField(1, "uint32"),
			uin: ProtoField(2, "uint64"),
			field3: ProtoField(3, "uint32"),
			/** 表情图 md5（16 字节二进制，不是 hex 字符串） */
			md5: ProtoField(4, "bytes"),
			fileSize: ProtoField(5, "uint32"),
			field7: ProtoField(7, "uint32"),
			field8: ProtoField(8, "uint32"),
			field9: ProtoField(9, "uint32"),
			version: ProtoField(13, "string"),
			field16: ProtoField(16, "uint32")
		}),
		/** 对应 highway commandId（add 走 cmd=9） */
		commandId: ProtoField(7, "uint32"),
		extension: ProtoField(1001, "bytes", "optional")
	});
	_Msg.BDHExpressionRoamResp = ProtoMessage.of({
		field1: ProtoField(1, "uint64"),
		field2: ProtoField(2, "uint32"),
		body: ProtoField(3, {
			retCode: ProtoField(1, "uint32"),
			field2: ProtoField(2, "uint32"),
			field4: ProtoField(4, "uint32"),
			uploadIps: ProtoField(6, "uint32", "repeated"),
			uploadPorts: ProtoField(7, "uint32", "repeated"),
			/** highway upload 用的 ticket */
			uKey: ProtoField(8, "bytes", "optional"),
			field9: ProtoField(9, "uint32", "optional"),
			field10: ProtoField(10, "uint32", "optional"),
			field11: ProtoField(11, "uint32", "optional"),
			field12: ProtoField(12, "uint32", "optional"),
			ext: ProtoField(1018, {
				domain: ProtoField(1, "string"),
				path1: ProtoField(2, "string", "optional"),
				path2: ProtoField(3, "string", "optional"),
				emojiId: ProtoField(5, "string")
			}, "optional")
		})
	});
	const InfoSyncPushGroupNode = _Msg.InfoSyncPushGroupNode = ProtoMessage.of({
		groupCode: ProtoField(1, "uint64"),
		groupSeq: ProtoField(2, "uint64"),
		readMsgSeq: ProtoField(3, "uint64", "optional"),
		latestMsgTime: ProtoField(8, "uint64", "optional")
	});
	_Msg.InfoSyncPush = ProtoMessage.of({ groupNodes: ProtoField(6, InfoSyncPushGroupNode, "repeated") });
	_Msg.MarkdownExtra = ProtoMessage.of({ content: ProtoField(1, "string") });
	_Msg.TextResvAttr = ProtoMessage.of({
		atType: ProtoField(3, "uint32"),
		atMemberUin: ProtoField(4, "uint32", "optional"),
		atMemberTinyid: ProtoField(5, "uint32", "optional"),
		atMemberUid: ProtoField(9, "string")
	});
	_Msg.PokeExtra = ProtoMessage.of({
		type: ProtoField(1, "uint32"),
		strength: ProtoField(7, "uint32")
	});
	_Msg.MessageStyleExtra = ProtoMessage.of({
		field4: ProtoField(4, "int32"),
		font: ProtoField(15, "uint64"),
		fontEffectId: ProtoField(34, "uint32"),
		vipType: ProtoField(51, "uint64"),
		vipLevel: ProtoField(52, "uint64"),
		vipNameplate: ProtoField(56, "uint64"),
		groupMemberLevel: ProtoField(65, { level: ProtoField(2, "int32") }, "optional"),
		groupHonorStyle: ProtoField(81, "uint64"),
		messageSequence: ProtoField(107, "uint32")
	});
})(Msg || (Msg = {}));
//#endregion
//#region src/ntqqapi/proto/misc.ts
var Misc;
(function(_Misc) {
	_Misc.UserInfoLabel = ProtoMessage.of({ labels: ProtoField(1, { content: ProtoField(4, "string") }, "repeated") });
	_Misc.UserInfoBusiness = ProtoMessage.of({ body: ProtoField(3, {
		msg: ProtoField(1, "string"),
		lists: ProtoField(3, {
			type: ProtoField(1, "uint32"),
			field2: ProtoField(2, "uint32"),
			isYear: ProtoField(3, "uint32"),
			level: ProtoField(4, "uint32"),
			isPro: ProtoField(5, "uint32"),
			icon1: ProtoField(6, "string"),
			icon2: ProtoField(7, "string")
		}, "repeated")
	}) });
})(Misc || (Misc = {}));
var face_config_default = {
	sysface: [
		{
			"QSid": "419",
			"QDes": "/火车",
			"IQLid": "419",
			"AQLid": "419",
			"EMCode": "10419",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "47"
		},
		{
			"QSid": "424",
			"QDes": "/续标识",
			"IQLid": "424",
			"AQLid": "424",
			"EMCode": "10424",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "52"
		},
		{
			"QSid": "425",
			"QDes": "/求放过",
			"IQLid": "425",
			"AQLid": "425",
			"EMCode": "10425",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "53"
		},
		{
			"QSid": "426",
			"QDes": "/玩火",
			"IQLid": "426",
			"AQLid": "426",
			"EMCode": "10426",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "54"
		},
		{
			"QSid": "427",
			"QDes": "/偷感",
			"IQLid": "427",
			"AQLid": "427",
			"EMCode": "10427",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "55"
		},
		{
			"QSid": "428",
			"QDes": "/收到",
			"IQLid": "428",
			"AQLid": "428",
			"EMCode": "10428"
		},
		{
			"QSid": "429",
			"QDes": "/蛇年快乐",
			"IQLid": "429",
			"AQLid": "429",
			"EMCode": "10429",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "56"
		},
		{
			"QSid": "364",
			"QDes": "/超级赞",
			"IQLid": "364",
			"AQLid": "364",
			"EMCode": "10364",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "1",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "366",
			"QDes": "/芒狗",
			"IQLid": "366",
			"AQLid": "366",
			"EMCode": "10366",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "2",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "362",
			"QDes": "/好兄弟",
			"IQLid": "362",
			"AQLid": "362",
			"EMCode": "10362",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "3",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "397",
			"QDes": "/抛媚眼",
			"IQLid": "397",
			"AQLid": "397",
			"EMCode": "10397",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "4",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "396",
			"QDes": "/狼狗",
			"IQLid": "396",
			"AQLid": "396",
			"EMCode": "10396",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "5",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "360",
			"QDes": "/亲亲",
			"IQLid": "360",
			"AQLid": "360",
			"EMCode": "10360",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "6",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "361",
			"QDes": "/狗狗笑哭",
			"IQLid": "361",
			"AQLid": "361",
			"EMCode": "10361",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "7",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "363",
			"QDes": "/狗狗可怜",
			"IQLid": "363",
			"AQLid": "363",
			"EMCode": "10363",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "8",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "365",
			"QDes": "/狗狗生气",
			"IQLid": "365",
			"AQLid": "365",
			"EMCode": "10365",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "9",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "367",
			"QDes": "/狗狗疑问",
			"IQLid": "367",
			"AQLid": "367",
			"EMCode": "10367",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "10",
			"AniStickerPackId": "2",
			"AniStickerPackName": "汪汪"
		},
		{
			"QSid": "399",
			"QDes": "/tui",
			"IQLid": "399",
			"AQLid": "399",
			"EMCode": "10399",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "1",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "398",
			"QDes": "/超级ok",
			"IQLid": "398",
			"AQLid": "398",
			"EMCode": "10398",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "2",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "373",
			"QDes": "/忙",
			"IQLid": "373",
			"AQLid": "373",
			"EMCode": "10373",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "3",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "370",
			"QDes": "/祝贺",
			"IQLid": "370",
			"AQLid": "370",
			"EMCode": "10370",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "4",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "375",
			"QDes": "/超级鼓掌",
			"IQLid": "375",
			"AQLid": "375",
			"EMCode": "10375",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "5",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "368",
			"QDes": "/奥特笑哭",
			"IQLid": "368",
			"AQLid": "368",
			"EMCode": "10368",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "6",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "369",
			"QDes": "/彩虹",
			"IQLid": "369",
			"AQLid": "369",
			"EMCode": "10369",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "7",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "371",
			"QDes": "/冒泡",
			"IQLid": "371",
			"AQLid": "371",
			"EMCode": "10371",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "8",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "372",
			"QDes": "/气呼呼",
			"IQLid": "372",
			"AQLid": "372",
			"EMCode": "10372",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "9",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "374",
			"QDes": "/波波流泪",
			"IQLid": "374",
			"AQLid": "374",
			"EMCode": "10374",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "10",
			"AniStickerPackId": "6",
			"AniStickerPackName": "噗噗星人"
		},
		{
			"QSid": "382",
			"QDes": "/emo",
			"IQLid": "382",
			"AQLid": "382",
			"EMCode": "10382",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "1",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "383",
			"QDes": "/企鹅爱心",
			"IQLid": "383",
			"AQLid": "383",
			"EMCode": "10383",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "2",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "401",
			"QDes": "/超级转圈",
			"IQLid": "401",
			"AQLid": "401",
			"EMCode": "10401",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "3",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "400",
			"QDes": "/快乐",
			"IQLid": "400",
			"AQLid": "400",
			"EMCode": "10400",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "4",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "380",
			"QDes": "/真棒",
			"IQLid": "380",
			"AQLid": "380",
			"EMCode": "10380",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "5",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "381",
			"QDes": "/路过",
			"IQLid": "381",
			"AQLid": "381",
			"EMCode": "10381",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "6",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "379",
			"QDes": "/企鹅流泪",
			"IQLid": "379",
			"AQLid": "379",
			"EMCode": "10379",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "7",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "376",
			"QDes": "/跺脚",
			"IQLid": "376",
			"AQLid": "376",
			"EMCode": "10376",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "8",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "378",
			"QDes": "/企鹅笑哭",
			"IQLid": "378",
			"AQLid": "378",
			"EMCode": "10378",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "9",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "377",
			"QDes": "/嗨",
			"IQLid": "377",
			"AQLid": "377",
			"EMCode": "10377",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "10",
			"AniStickerPackId": "5",
			"AniStickerPackName": "企鹅"
		},
		{
			"QSid": "403",
			"QDes": "/出去玩",
			"IQLid": "403",
			"AQLid": "403",
			"EMCode": "10403",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "1",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "402",
			"QDes": "/别说话",
			"IQLid": "402",
			"AQLid": "402",
			"EMCode": "10402",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "2",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "390",
			"QDes": "/太头秃",
			"IQLid": "390",
			"AQLid": "390",
			"EMCode": "10390",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "3",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "391",
			"QDes": "/太沧桑",
			"IQLid": "391",
			"AQLid": "391",
			"EMCode": "10391",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "4",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "388",
			"QDes": "/太头疼",
			"IQLid": "388",
			"AQLid": "388",
			"EMCode": "10388",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "5",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "389",
			"QDes": "/太赞了",
			"IQLid": "389",
			"AQLid": "389",
			"EMCode": "10389",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "6",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "386",
			"QDes": "/呜呜呜",
			"IQLid": "386",
			"AQLid": "386",
			"EMCode": "10386",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "7",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "385",
			"QDes": "/太气了",
			"IQLid": "385",
			"AQLid": "385",
			"EMCode": "10385",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "8",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "384",
			"QDes": "/晚安",
			"IQLid": "384",
			"AQLid": "384",
			"EMCode": "10384",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "9",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "387",
			"QDes": "/太好笑",
			"IQLid": "387",
			"AQLid": "387",
			"EMCode": "10387",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "10",
			"AniStickerPackId": "4",
			"AniStickerPackName": "QQ黄脸"
		},
		{
			"QSid": "413",
			"QDes": "/摇起来",
			"IQLid": "413",
			"AQLid": "413",
			"EMCode": "10413",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "1",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "405",
			"QDes": "/好运来",
			"IQLid": "405",
			"AQLid": "405",
			"EMCode": "10405",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "2",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "404",
			"QDes": "/闪亮登场",
			"IQLid": "404",
			"AQLid": "404",
			"EMCode": "10404",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "3",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "406",
			"QDes": "/姐是女王",
			"IQLid": "406",
			"AQLid": "406",
			"EMCode": "10406",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "4",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "410",
			"QDes": "/么么哒",
			"IQLid": "410",
			"AQLid": "410",
			"EMCode": "10410",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "5",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "411",
			"QDes": "/一起嗨",
			"IQLid": "411",
			"AQLid": "411",
			"EMCode": "10411",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "6",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "407",
			"QDes": "/我听听",
			"IQLid": "407",
			"AQLid": "407",
			"EMCode": "10407",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "7",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "408",
			"QDes": "/臭美",
			"IQLid": "408",
			"AQLid": "408",
			"EMCode": "10408",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "8",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "412",
			"QDes": "/开心",
			"IQLid": "412",
			"AQLid": "412",
			"EMCode": "10412",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "9",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "409",
			"QDes": "/送你花花",
			"IQLid": "409",
			"AQLid": "409",
			"EMCode": "10409",
			"QHide": "1",
			"AniStickerType": 1,
			"AniStickerId": "10",
			"AniStickerPackId": "3",
			"AniStickerPackName": "喜花妮"
		},
		{
			"QSid": "14",
			"QDes": "/微笑",
			"IQLid": "23",
			"AQLid": "23",
			"EMCode": "100"
		},
		{
			"QSid": "1",
			"QDes": "/撇嘴",
			"IQLid": "40",
			"AQLid": "40",
			"EMCode": "101"
		},
		{
			"QSid": "2",
			"QDes": "/色",
			"IQLid": "19",
			"AQLid": "19",
			"EMCode": "102"
		},
		{
			"QSid": "3",
			"QDes": "/发呆",
			"IQLid": "43",
			"AQLid": "43",
			"EMCode": "103"
		},
		{
			"QSid": "4",
			"QDes": "/得意",
			"IQLid": "21",
			"AQLid": "21",
			"EMCode": "104"
		},
		{
			"QSid": "6",
			"QDes": "/害羞",
			"IQLid": "20",
			"AQLid": "20",
			"EMCode": "106"
		},
		{
			"QSid": "7",
			"QDes": "/闭嘴",
			"IQLid": "104",
			"AQLid": "106",
			"EMCode": "107"
		},
		{
			"QSid": "8",
			"QDes": "/睡",
			"IQLid": "35",
			"AQLid": "35",
			"EMCode": "108"
		},
		{
			"QSid": "9",
			"QDes": "/大哭",
			"IQLid": "10",
			"AQLid": "10",
			"EMCode": "109"
		},
		{
			"QSid": "5",
			"QDes": "/流泪",
			"IQLid": "9",
			"AQLid": "9",
			"EMCode": "105",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "16"
		},
		{
			"QSid": "10",
			"QDes": "/尴尬",
			"IQLid": "25",
			"AQLid": "25",
			"EMCode": "110"
		},
		{
			"QSid": "11",
			"QDes": "/发怒",
			"IQLid": "24",
			"AQLid": "24",
			"EMCode": "111"
		},
		{
			"QSid": "12",
			"QDes": "/调皮",
			"IQLid": "1",
			"AQLid": "1",
			"EMCode": "112"
		},
		{
			"QSid": "13",
			"QDes": "/呲牙",
			"IQLid": "0",
			"AQLid": "0",
			"EMCode": "113"
		},
		{
			"QSid": "0",
			"QDes": "/惊讶",
			"IQLid": "33",
			"AQLid": "33",
			"EMCode": "114"
		},
		{
			"QSid": "15",
			"QDes": "/难过",
			"IQLid": "32",
			"AQLid": "32",
			"EMCode": "115"
		},
		{
			"QSid": "16",
			"QDes": "/酷",
			"IQLid": "12",
			"AQLid": "12",
			"EMCode": "116"
		},
		{
			"QSid": "96",
			"QDes": "/冷汗",
			"IQLid": "27",
			"AQLid": "27",
			"EMCode": "117"
		},
		{
			"QSid": "18",
			"QDes": "/抓狂",
			"IQLid": "13",
			"AQLid": "13",
			"EMCode": "118"
		},
		{
			"QSid": "19",
			"QDes": "/吐",
			"IQLid": "22",
			"AQLid": "22",
			"EMCode": "119"
		},
		{
			"QSid": "20",
			"QDes": "/偷笑",
			"IQLid": "3",
			"AQLid": "3",
			"EMCode": "120"
		},
		{
			"QSid": "21",
			"QDes": "/可爱",
			"IQLid": "18",
			"AQLid": "18",
			"EMCode": "121"
		},
		{
			"QSid": "22",
			"QDes": "/白眼",
			"IQLid": "30",
			"AQLid": "30",
			"EMCode": "122"
		},
		{
			"QSid": "23",
			"QDes": "/傲慢",
			"IQLid": "31",
			"AQLid": "31",
			"EMCode": "123"
		},
		{
			"QSid": "24",
			"QDes": "/饥饿",
			"IQLid": "79",
			"AQLid": "81",
			"EMCode": "124"
		},
		{
			"QSid": "25",
			"QDes": "/困",
			"IQLid": "80",
			"AQLid": "82",
			"EMCode": "125"
		},
		{
			"QSid": "26",
			"QDes": "/惊恐",
			"IQLid": "26",
			"AQLid": "26",
			"EMCode": "126"
		},
		{
			"QSid": "27",
			"QDes": "/流汗",
			"IQLid": "2",
			"AQLid": "2",
			"EMCode": "127"
		},
		{
			"QSid": "28",
			"QDes": "/憨笑",
			"IQLid": "37",
			"AQLid": "37",
			"EMCode": "128"
		},
		{
			"QSid": "29",
			"QDes": "/悠闲",
			"IQLid": "50",
			"AQLid": "50",
			"EMCode": "129"
		},
		{
			"QSid": "30",
			"QDes": "/奋斗",
			"IQLid": "42",
			"AQLid": "42",
			"EMCode": "130"
		},
		{
			"QSid": "31",
			"QDes": "/咒骂",
			"IQLid": "81",
			"AQLid": "83",
			"EMCode": "131"
		},
		{
			"QSid": "32",
			"QDes": "/疑问",
			"IQLid": "34",
			"AQLid": "34",
			"EMCode": "132"
		},
		{
			"QSid": "33",
			"QDes": "/嘘",
			"IQLid": "11",
			"AQLid": "11",
			"EMCode": "133"
		},
		{
			"QSid": "34",
			"QDes": "/晕",
			"IQLid": "49",
			"AQLid": "49",
			"EMCode": "134"
		},
		{
			"QSid": "35",
			"QDes": "/折磨",
			"IQLid": "82",
			"AQLid": "84",
			"EMCode": "135"
		},
		{
			"QSid": "36",
			"QDes": "/衰",
			"IQLid": "39",
			"AQLid": "39",
			"EMCode": "136"
		},
		{
			"QSid": "37",
			"QDes": "/骷髅",
			"isStatic": "1",
			"IQLid": "76",
			"AQLid": "78",
			"EMCode": "137"
		},
		{
			"QSid": "38",
			"QDes": "/敲打",
			"IQLid": "5",
			"AQLid": "5",
			"EMCode": "138"
		},
		{
			"QSid": "39",
			"QDes": "/再见",
			"IQLid": "4",
			"AQLid": "4",
			"EMCode": "139"
		},
		{
			"QSid": "97",
			"QDes": "/擦汗",
			"IQLid": "6",
			"AQLid": "6",
			"EMCode": "140"
		},
		{
			"QSid": "98",
			"QDes": "/抠鼻",
			"IQLid": "83",
			"AQLid": "85",
			"EMCode": "141"
		},
		{
			"QSid": "99",
			"QDes": "/鼓掌",
			"IQLid": "84",
			"AQLid": "86",
			"EMCode": "142"
		},
		{
			"QSid": "100",
			"QDes": "/糗大了",
			"IQLid": "85",
			"AQLid": "87",
			"EMCode": "143"
		},
		{
			"QSid": "101",
			"QDes": "/坏笑",
			"IQLid": "46",
			"AQLid": "46",
			"EMCode": "144"
		},
		{
			"QSid": "102",
			"QDes": "/左哼哼",
			"IQLid": "86",
			"AQLid": "88",
			"EMCode": "145"
		},
		{
			"QSid": "103",
			"QDes": "/右哼哼",
			"IQLid": "44",
			"AQLid": "44",
			"EMCode": "146"
		},
		{
			"QSid": "104",
			"QDes": "/哈欠",
			"IQLid": "87",
			"AQLid": "89",
			"EMCode": "147"
		},
		{
			"QSid": "105",
			"QDes": "/鄙视",
			"IQLid": "48",
			"AQLid": "48",
			"EMCode": "148"
		},
		{
			"QSid": "106",
			"QDes": "/委屈",
			"IQLid": "14",
			"AQLid": "14",
			"EMCode": "149"
		},
		{
			"QSid": "107",
			"QDes": "/快哭了",
			"IQLid": "88",
			"AQLid": "90",
			"EMCode": "150"
		},
		{
			"QSid": "108",
			"QDes": "/阴险",
			"IQLid": "41",
			"AQLid": "41",
			"EMCode": "151"
		},
		{
			"QSid": "305",
			"QDes": "/右亲亲",
			"IQLid": "305",
			"AQLid": "305",
			"EMCode": "10305"
		},
		{
			"QSid": "109",
			"QDes": "/左亲亲",
			"IQLid": "36",
			"AQLid": "36",
			"EMCode": "152"
		},
		{
			"QSid": "110",
			"QDes": "/吓",
			"IQLid": "89",
			"AQLid": "91",
			"EMCode": "153"
		},
		{
			"QSid": "111",
			"QDes": "/可怜",
			"IQLid": "51",
			"AQLid": "51",
			"EMCode": "154"
		},
		{
			"QSid": "172",
			"QDes": "/眨眼睛",
			"IQLid": "142",
			"AQLid": "164",
			"EMCode": "242"
		},
		{
			"QSid": "182",
			"QDes": "/笑哭",
			"IQLid": "152",
			"AQLid": "174",
			"EMCode": "252"
		},
		{
			"QSid": "179",
			"QDes": "/doge",
			"IQLid": "149",
			"AQLid": "171",
			"EMCode": "249"
		},
		{
			"QSid": "173",
			"QDes": "/泪奔",
			"IQLid": "143",
			"AQLid": "165",
			"EMCode": "243"
		},
		{
			"QSid": "174",
			"QDes": "/无奈",
			"IQLid": "144",
			"AQLid": "166",
			"EMCode": "244"
		},
		{
			"QSid": "212",
			"QDes": "/托腮",
			"IQLid": "182",
			"AQLid": "161",
			"EMCode": "282"
		},
		{
			"QSid": "175",
			"QDes": "/卖萌",
			"IQLid": "145",
			"AQLid": "167",
			"EMCode": "245"
		},
		{
			"QSid": "178",
			"QDes": "/斜眼笑",
			"IQLid": "148",
			"AQLid": "170",
			"EMCode": "248"
		},
		{
			"QSid": "177",
			"QDes": "/喷血",
			"IQLid": "147",
			"AQLid": "169",
			"EMCode": "247"
		},
		{
			"QSid": "176",
			"QDes": "/小纠结",
			"IQLid": "146",
			"AQLid": "168",
			"EMCode": "246"
		},
		{
			"QSid": "183",
			"QDes": "/我最美",
			"IQLid": "153",
			"AQLid": "175",
			"EMCode": "253"
		},
		{
			"QSid": "262",
			"QDes": "/脑阔疼",
			"IQLid": "262",
			"AQLid": "262",
			"EMCode": "10262"
		},
		{
			"QSid": "263",
			"QDes": "/沧桑",
			"IQLid": "263",
			"AQLid": "263",
			"EMCode": "10263"
		},
		{
			"QSid": "264",
			"QDes": "/捂脸",
			"IQLid": "264",
			"AQLid": "264",
			"EMCode": "10264"
		},
		{
			"QSid": "265",
			"QDes": "/辣眼睛",
			"IQLid": "265",
			"AQLid": "265",
			"EMCode": "10265"
		},
		{
			"QSid": "266",
			"QDes": "/哦哟",
			"IQLid": "266",
			"AQLid": "266",
			"EMCode": "10266"
		},
		{
			"QSid": "267",
			"QDes": "/头秃",
			"IQLid": "267",
			"AQLid": "267",
			"EMCode": "10267"
		},
		{
			"QSid": "268",
			"QDes": "/问号脸",
			"IQLid": "268",
			"AQLid": "268",
			"EMCode": "10268"
		},
		{
			"QSid": "269",
			"QDes": "/暗中观察",
			"IQLid": "269",
			"AQLid": "269",
			"EMCode": "10269"
		},
		{
			"QSid": "270",
			"QDes": "/emm",
			"IQLid": "270",
			"AQLid": "270",
			"EMCode": "10270"
		},
		{
			"QSid": "271",
			"QDes": "/吃瓜",
			"IQLid": "271",
			"AQLid": "271",
			"EMCode": "10271"
		},
		{
			"QSid": "272",
			"QDes": "/呵呵哒",
			"IQLid": "272",
			"AQLid": "272",
			"EMCode": "10272"
		},
		{
			"QSid": "277",
			"QDes": "/汪汪",
			"IQLid": "277",
			"AQLid": "277",
			"EMCode": "10277"
		},
		{
			"QSid": "307",
			"QDes": "/喵喵",
			"IQLid": "307",
			"AQLid": "307",
			"EMCode": "10307"
		},
		{
			"QSid": "306",
			"QDes": "/牛气冲天",
			"isStatic": "1",
			"IQLid": "306",
			"AQLid": "306",
			"EMCode": "10306"
		},
		{
			"QSid": "281",
			"QDes": "/无眼笑",
			"IQLid": "281",
			"AQLid": "281",
			"EMCode": "10281"
		},
		{
			"QSid": "282",
			"QDes": "/敬礼",
			"IQLid": "282",
			"AQLid": "282",
			"EMCode": "10282"
		},
		{
			"QSid": "283",
			"QDes": "/狂笑",
			"IQLid": "283",
			"AQLid": "283",
			"EMCode": "10283"
		},
		{
			"QSid": "284",
			"QDes": "/面无表情",
			"IQLid": "284",
			"AQLid": "284",
			"EMCode": "10284"
		},
		{
			"QSid": "285",
			"QDes": "/摸鱼",
			"IQLid": "285",
			"AQLid": "285",
			"EMCode": "10285"
		},
		{
			"QSid": "293",
			"QDes": "/摸锦鲤",
			"IQLid": "293",
			"AQLid": "293",
			"EMCode": "10293"
		},
		{
			"QSid": "286",
			"QDes": "/魔鬼笑",
			"IQLid": "286",
			"AQLid": "286",
			"EMCode": "10286"
		},
		{
			"QSid": "287",
			"QDes": "/哦",
			"IQLid": "287",
			"AQLid": "287",
			"EMCode": "10287"
		},
		{
			"QSid": "289",
			"QDes": "/睁眼",
			"IQLid": "289",
			"AQLid": "289",
			"EMCode": "10289"
		},
		{
			"QSid": "294",
			"QDes": "/期待",
			"IQLid": "294",
			"AQLid": "294",
			"EMCode": "10294"
		},
		{
			"QSid": "297",
			"QDes": "/拜谢",
			"IQLid": "297",
			"AQLid": "297",
			"EMCode": "10297"
		},
		{
			"QSid": "298",
			"QDes": "/元宝",
			"IQLid": "298",
			"AQLid": "298",
			"EMCode": "10298"
		},
		{
			"QSid": "299",
			"QDes": "/牛啊",
			"IQLid": "299",
			"AQLid": "299",
			"EMCode": "10299"
		},
		{
			"QSid": "300",
			"QDes": "/胖三斤",
			"IQLid": "300",
			"AQLid": "300",
			"EMCode": "10300"
		},
		{
			"QSid": "323",
			"QDes": "/嫌弃",
			"IQLid": "323",
			"AQLid": "323",
			"EMCode": "10323"
		},
		{
			"QSid": "332",
			"QDes": "/举牌牌",
			"IQLid": "332",
			"AQLid": "332",
			"EMCode": "10332"
		},
		{
			"QSid": "336",
			"QDes": "/豹富",
			"IQLid": "336",
			"AQLid": "336",
			"EMCode": "10336"
		},
		{
			"QSid": "353",
			"QDes": "/拜托",
			"IQLid": "353",
			"AQLid": "353",
			"EMCode": "10353"
		},
		{
			"QSid": "355",
			"QDes": "/耶",
			"IQLid": "355",
			"AQLid": "355",
			"EMCode": "10355"
		},
		{
			"QSid": "356",
			"QDes": "/666",
			"IQLid": "356",
			"AQLid": "356",
			"EMCode": "10356"
		},
		{
			"QSid": "354",
			"QDes": "/尊嘟假嘟",
			"IQLid": "354",
			"AQLid": "354",
			"EMCode": "10354"
		},
		{
			"QSid": "352",
			"QDes": "/咦",
			"IQLid": "352",
			"AQLid": "352",
			"EMCode": "10352"
		},
		{
			"QSid": "357",
			"QDes": "/裂开",
			"IQLid": "357",
			"AQLid": "357",
			"EMCode": "10357"
		},
		{
			"QSid": "334",
			"QDes": "/虎虎生威",
			"IQLid": "334",
			"AQLid": "334",
			"EMCode": "10334"
		},
		{
			"QSid": "347",
			"QDes": "/大展宏兔",
			"IQLid": "347",
			"AQLid": "347",
			"EMCode": "10347"
		},
		{
			"QSid": "303",
			"QDes": "/右拜年",
			"IQLid": "303",
			"AQLid": "303",
			"EMCode": "10303"
		},
		{
			"QSid": "302",
			"QDes": "/左拜年",
			"IQLid": "302",
			"AQLid": "302",
			"EMCode": "10302"
		},
		{
			"QSid": "295",
			"QDes": "/拿到红包",
			"IQLid": "295",
			"AQLid": "295",
			"EMCode": "10295"
		},
		{
			"QSid": "311",
			"QDes": "/打call",
			"IQLid": "311",
			"AQLid": "311",
			"EMCode": "10311",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "1"
		},
		{
			"QSid": "312",
			"QDes": "/变形",
			"IQLid": "312",
			"AQLid": "312",
			"EMCode": "10312",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "2"
		},
		{
			"QSid": "314",
			"QDes": "/仔细分析",
			"IQLid": "314",
			"AQLid": "314",
			"EMCode": "10314",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "4"
		},
		{
			"QSid": "317",
			"QDes": "/菜汪",
			"IQLid": "317",
			"AQLid": "317",
			"EMCode": "10317",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "7"
		},
		{
			"QSid": "318",
			"QDes": "/崇拜",
			"IQLid": "318",
			"AQLid": "318",
			"EMCode": "10318",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "8"
		},
		{
			"QSid": "319",
			"QDes": "/比心",
			"IQLid": "319",
			"AQLid": "319",
			"EMCode": "10319",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "9"
		},
		{
			"QSid": "320",
			"QDes": "/庆祝",
			"IQLid": "320",
			"AQLid": "320",
			"EMCode": "10320",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "10"
		},
		{
			"QSid": "324",
			"QDes": "/吃糖",
			"IQLid": "324",
			"AQLid": "324",
			"EMCode": "10324",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "12"
		},
		{
			"QSid": "325",
			"QDes": "/惊吓",
			"IQLid": "325",
			"AQLid": "325",
			"EMCode": "10325",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "14"
		},
		{
			"QSid": "337",
			"QDes": "/花朵脸",
			"IQLid": "337",
			"AQLid": "337",
			"EMCode": "10337",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "22"
		},
		{
			"QSid": "338",
			"QDes": "/我想开了",
			"IQLid": "338",
			"AQLid": "338",
			"EMCode": "10338",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "20"
		},
		{
			"QSid": "339",
			"QDes": "/舔屏",
			"IQLid": "339",
			"AQLid": "339",
			"EMCode": "10339",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "21"
		},
		{
			"QSid": "341",
			"QDes": "/打招呼",
			"IQLid": "341",
			"AQLid": "341",
			"EMCode": "10341",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "24"
		},
		{
			"QSid": "342",
			"QDes": "/酸Q",
			"IQLid": "342",
			"AQLid": "342",
			"EMCode": "10342",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "26"
		},
		{
			"QSid": "343",
			"QDes": "/我方了",
			"IQLid": "343",
			"AQLid": "343",
			"EMCode": "10343",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "27"
		},
		{
			"QSid": "344",
			"QDes": "/大怨种",
			"IQLid": "344",
			"AQLid": "344",
			"EMCode": "10344",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "28"
		},
		{
			"QSid": "345",
			"QDes": "/红包多多",
			"IQLid": "345",
			"AQLid": "345",
			"EMCode": "10345",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "29"
		},
		{
			"QSid": "346",
			"QDes": "/你真棒棒",
			"IQLid": "346",
			"AQLid": "346",
			"EMCode": "10346",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "25"
		},
		{
			"QSid": "181",
			"QDes": "/戳一戳",
			"IQLid": "151",
			"AQLid": "173",
			"EMCode": "251",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "37"
		},
		{
			"QSid": "74",
			"QDes": "/太阳",
			"isStatic": "1",
			"IQLid": "73",
			"AQLid": "75",
			"EMCode": "176",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "35"
		},
		{
			"QSid": "75",
			"QDes": "/月亮",
			"isStatic": "1",
			"IQLid": "67",
			"AQLid": "68",
			"EMCode": "175",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "36"
		},
		{
			"QSid": "351",
			"QDes": "/敲敲",
			"IQLid": "351",
			"AQLid": "351",
			"EMCode": "10351",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "30"
		},
		{
			"QSid": "349",
			"QDes": "/坚强",
			"IQLid": "349",
			"AQLid": "349",
			"EMCode": "10349",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "32"
		},
		{
			"QSid": "350",
			"QDes": "/贴贴",
			"IQLid": "350",
			"AQLid": "350",
			"EMCode": "10350",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "31"
		},
		{
			"QSid": "395",
			"QDes": "/略略略",
			"IQLid": "395",
			"AQLid": "395",
			"EMCode": "10395",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "41"
		},
		{
			"QSid": "114",
			"QDes": "/篮球",
			"IQLid": "90",
			"AQLid": "92",
			"EMCode": "158",
			"AniStickerType": 2,
			"AniStickerPackId": "1",
			"AniStickerId": "13"
		},
		{
			"QSid": "358",
			"QDes": "/骰子",
			"IQLid": "358",
			"AQLid": "358",
			"QHide": "1",
			"EMCode": "10358",
			"AniStickerType": 2,
			"AniStickerPackId": "1",
			"AniStickerId": "33"
		},
		{
			"QSid": "359",
			"QDes": "/包剪锤",
			"IQLid": "359",
			"AQLid": "359",
			"QHide": "1",
			"EMCode": "10359",
			"AniStickerType": 2,
			"AniStickerPackId": "1",
			"AniStickerId": "34"
		},
		{
			"QSid": "326",
			"QDes": "/生气",
			"IQLid": "326",
			"AQLid": "326",
			"EMCode": "10326",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "15"
		},
		{
			"QSid": "53",
			"QDes": "/蛋糕",
			"IQLid": "59",
			"AQLid": "59",
			"EMCode": "168",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "17"
		},
		{
			"QSid": "49",
			"QDes": "/拥抱",
			"IQLid": "45",
			"AQLid": "45",
			"EMCode": "178"
		},
		{
			"QSid": "66",
			"QDes": "/爱心",
			"IQLid": "28",
			"AQLid": "28",
			"EMCode": "166"
		},
		{
			"QSid": "63",
			"QDes": "/玫瑰",
			"IQLid": "8",
			"AQLid": "8",
			"EMCode": "163"
		},
		{
			"QSid": "64",
			"QDes": "/凋谢",
			"IQLid": "57",
			"AQLid": "57",
			"EMCode": "164"
		},
		{
			"QSid": "187",
			"QDes": "/幽灵",
			"IQLid": "157",
			"AQLid": "179",
			"EMCode": "257"
		},
		{
			"QSid": "146",
			"QDes": "/爆筋",
			"IQLid": "116",
			"AQLid": "118",
			"EMCode": "121011"
		},
		{
			"QSid": "116",
			"QDes": "/示爱",
			"IQLid": "29",
			"AQLid": "29",
			"EMCode": "165"
		},
		{
			"QSid": "67",
			"QDes": "/心碎",
			"IQLid": "72",
			"AQLid": "74",
			"EMCode": "167"
		},
		{
			"QSid": "60",
			"QDes": "/咖啡",
			"IQLid": "66",
			"AQLid": "66",
			"EMCode": "160"
		},
		{
			"QSid": "185",
			"QDes": "/羊驼",
			"IQLid": "155",
			"AQLid": "177",
			"EMCode": "255"
		},
		{
			"QSid": "137",
			"QDes": "/鞭炮",
			"isStatic": "1",
			"IQLid": "107",
			"AQLid": "109",
			"EMCode": "121002",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "18"
		},
		{
			"QSid": "333",
			"QDes": "/烟花",
			"isStatic": "1",
			"IQLid": "333",
			"AQLid": "333",
			"EMCode": "10333",
			"AniStickerType": 1,
			"AniStickerPackId": "1",
			"AniStickerId": "19"
		},
		{
			"QSid": "415",
			"QDes": "/划龙舟",
			"IQLid": "415",
			"AQLid": "415",
			"EMCode": "10415",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "43",
			"AniStickerWidth": 192,
			"AniStickerHeight": 76
		},
		{
			"QSid": "416",
			"QDes": "/中龙舟",
			"IQLid": "416",
			"AQLid": "416",
			"EMCode": "10416",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "44",
			"AniStickerWidth": 192,
			"AniStickerHeight": 76,
			"QHide": "1"
		},
		{
			"QSid": "417",
			"QDes": "/大龙舟",
			"IQLid": "417",
			"AQLid": "417",
			"EMCode": "10417",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "45",
			"AniStickerWidth": 192,
			"AniStickerHeight": 96,
			"QHide": "1"
		},
		{
			"QSid": "392",
			"QDes": "/龙年快乐",
			"IQLid": "392",
			"AQLid": "392",
			"EMCode": "10392",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "38",
			"AniStickerWidth": 129,
			"AniStickerHeight": 57
		},
		{
			"QSid": "393",
			"QDes": "/新年中龙",
			"IQLid": "393",
			"AQLid": "393",
			"EMCode": "10393",
			"QHide": "1",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "39",
			"AniStickerWidth": 159,
			"AniStickerHeight": 72
		},
		{
			"QSid": "394",
			"QDes": "/新年大龙",
			"IQLid": "394",
			"AQLid": "394",
			"EMCode": "10394",
			"QHide": "1",
			"AniStickerType": 3,
			"AniStickerPackId": "1",
			"AniStickerId": "40",
			"AniStickerWidth": 220,
			"AniStickerHeight": 91
		},
		{
			"QSid": "76",
			"QDes": "/赞",
			"IQLid": "52",
			"AQLid": "52",
			"EMCode": "179"
		},
		{
			"QSid": "124",
			"QDes": "/OK",
			"IQLid": "64",
			"AQLid": "64",
			"EMCode": "189"
		},
		{
			"QSid": "118",
			"QDes": "/抱拳",
			"IQLid": "56",
			"AQLid": "56",
			"EMCode": "183"
		},
		{
			"QSid": "78",
			"QDes": "/握手",
			"IQLid": "54",
			"AQLid": "54",
			"EMCode": "181"
		},
		{
			"QSid": "119",
			"QDes": "/勾引",
			"IQLid": "63",
			"AQLid": "63",
			"EMCode": "184"
		},
		{
			"QSid": "79",
			"QDes": "/胜利",
			"IQLid": "55",
			"AQLid": "55",
			"EMCode": "182"
		},
		{
			"QSid": "120",
			"QDes": "/拳头",
			"IQLid": "71",
			"AQLid": "73",
			"EMCode": "185"
		},
		{
			"QSid": "121",
			"QDes": "/差劲",
			"IQLid": "70",
			"AQLid": "72",
			"EMCode": "186"
		},
		{
			"QSid": "77",
			"QDes": "/踩",
			"IQLid": "53",
			"AQLid": "53",
			"EMCode": "180"
		},
		{
			"QSid": "123",
			"QDes": "/NO",
			"IQLid": "92",
			"AQLid": "94",
			"EMCode": "188"
		},
		{
			"QSid": "201",
			"QDes": "/点赞",
			"IQLid": "171",
			"AQLid": "150",
			"EMCode": "271"
		},
		{
			"QSid": "273",
			"QDes": "/我酸了",
			"isStatic": "1",
			"IQLid": "273",
			"AQLid": "273",
			"EMCode": "10273"
		},
		{
			"QSid": "46",
			"QDes": "/猪头",
			"isStatic": "1",
			"IQLid": "7",
			"AQLid": "7",
			"EMCode": "162"
		},
		{
			"QSid": "112",
			"QDes": "/菜刀",
			"IQLid": "17",
			"AQLid": "17",
			"EMCode": "155"
		},
		{
			"QSid": "56",
			"QDes": "/刀",
			"IQLid": "68",
			"AQLid": "70",
			"EMCode": "171"
		},
		{
			"QSid": "169",
			"QDes": "/手枪",
			"isStatic": "1",
			"IQLid": "139",
			"AQLid": "141",
			"EMCode": "121034"
		},
		{
			"QSid": "171",
			"QDes": "/茶",
			"IQLid": "141",
			"AQLid": "163",
			"EMCode": "241"
		},
		{
			"QSid": "59",
			"QDes": "/便便",
			"IQLid": "15",
			"AQLid": "15",
			"EMCode": "174"
		},
		{
			"QSid": "144",
			"QDes": "/喝彩",
			"isStatic": "1",
			"IQLid": "114",
			"AQLid": "116",
			"EMCode": "121009"
		},
		{
			"QSid": "147",
			"QDes": "/棒棒糖",
			"isStatic": "1",
			"IQLid": "117",
			"AQLid": "119",
			"EMCode": "121012"
		},
		{
			"QSid": "89",
			"QDes": "/西瓜",
			"isStatic": "1",
			"IQLid": "60",
			"AQLid": "60",
			"EMCode": "156"
		},
		{
			"QSid": "148",
			"QDes": "/喝奶",
			"isStatic": "1",
			"IQLid": "118",
			"AQLid": "120",
			"QHide": "1",
			"EMCode": "121013"
		},
		{
			"QSid": "55",
			"QDes": "/炸弹",
			"isStatic": "1",
			"IQLid": "16",
			"AQLid": "16",
			"QHide": "1",
			"EMCode": "170"
		},
		{
			"QSid": "41",
			"QDes": "/发抖",
			"isStatic": "1",
			"IQLid": "69",
			"AQLid": "71",
			"EMCode": "193"
		},
		{
			"QSid": "125",
			"QDes": "/转圈",
			"IQLid": "95",
			"AQLid": "97",
			"EMCode": "195"
		},
		{
			"QSid": "42",
			"QDes": "/爱情",
			"IQLid": "38",
			"AQLid": "38",
			"EMCode": "190"
		},
		{
			"QSid": "43",
			"QDes": "/跳跳",
			"IQLid": "93",
			"AQLid": "95",
			"EMCode": "192"
		},
		{
			"QSid": "86",
			"QDes": "/怄火",
			"IQLid": "94",
			"AQLid": "96",
			"EMCode": "194"
		},
		{
			"QSid": "129",
			"QDes": "/挥手",
			"IQLid": "77",
			"AQLid": "79",
			"EMCode": "199"
		},
		{
			"QSid": "226",
			"QDes": "/拍桌",
			"IQLid": "196",
			"isCMEmoji": "1",
			"AQLid": "198",
			"QHide": "1",
			"EMCode": "297"
		},
		{
			"QSid": "85",
			"QDes": "/飞吻",
			"isStatic": "1",
			"IQLid": "47",
			"AQLid": "47",
			"EMCode": "191"
		},
		{
			"QSid": "215",
			"QDes": "/糊脸",
			"IQLid": "185",
			"isCMEmoji": "1",
			"AQLid": "187",
			"QHide": "1",
			"EMCode": "285"
		},
		{
			"QSid": "214",
			"QDes": "/啵啵",
			"IQLid": "184",
			"isCMEmoji": "1",
			"AQLid": "186",
			"QHide": "1",
			"EMCode": "284"
		},
		{
			"QSid": "222",
			"QDes": "/抱抱",
			"IQLid": "192",
			"isCMEmoji": "1",
			"AQLid": "194",
			"QHide": "1",
			"EMCode": "292"
		},
		{
			"QSid": "203",
			"QDes": "/托脸",
			"IQLid": "173",
			"AQLid": "152",
			"QHide": "1",
			"EMCode": "273"
		},
		{
			"QSid": "235",
			"QDes": "/颤抖",
			"IQLid": "205",
			"isCMEmoji": "1",
			"AQLid": "207",
			"QHide": "1",
			"EMCode": "305"
		},
		{
			"QSid": "241",
			"QDes": "/生日快乐",
			"IQLid": "211",
			"isCMEmoji": "1",
			"AQLid": "213",
			"QHide": "1",
			"EMCode": "311"
		},
		{
			"QSid": "237",
			"QDes": "/偷看",
			"IQLid": "207",
			"isCMEmoji": "1",
			"AQLid": "209",
			"QHide": "1",
			"EMCode": "307"
		},
		{
			"QSid": "218",
			"QDes": "/舔一舔",
			"IQLid": "188",
			"isCMEmoji": "1",
			"AQLid": "190",
			"QHide": "1",
			"EMCode": "288"
		},
		{
			"QSid": "233",
			"QDes": "/掐一掐",
			"IQLid": "203",
			"isCMEmoji": "1",
			"AQLid": "205",
			"QHide": "1",
			"EMCode": "303"
		},
		{
			"QSid": "232",
			"QDes": "/佛系",
			"IQLid": "202",
			"isCMEmoji": "1",
			"AQLid": "204",
			"QHide": "1",
			"EMCode": "302"
		},
		{
			"QSid": "238",
			"QDes": "/扇脸",
			"IQLid": "208",
			"isCMEmoji": "1",
			"AQLid": "210",
			"QHide": "1",
			"EMCode": "308"
		},
		{
			"QSid": "217",
			"QDes": "/扯一扯",
			"IQLid": "187",
			"isCMEmoji": "1",
			"AQLid": "189",
			"QHide": "1",
			"EMCode": "287"
		},
		{
			"QSid": "225",
			"QDes": "/撩一撩",
			"IQLid": "195",
			"isCMEmoji": "1",
			"AQLid": "197",
			"QHide": "1",
			"EMCode": "296"
		},
		{
			"QSid": "230",
			"QDes": "/嘲讽",
			"IQLid": "200",
			"isCMEmoji": "1",
			"AQLid": "202",
			"QHide": "1",
			"EMCode": "300"
		},
		{
			"QSid": "194",
			"QDes": "/不开心",
			"IQLid": "164",
			"AQLid": "143",
			"QHide": "1",
			"EMCode": "264"
		},
		{
			"QSid": "210",
			"QDes": "/飙泪",
			"IQLid": "180",
			"AQLid": "159",
			"QHide": "1",
			"EMCode": "280"
		},
		{
			"QSid": "193",
			"QDes": "/大笑",
			"IQLid": "163",
			"AQLid": "185",
			"QHide": "1",
			"EMCode": "263"
		},
		{
			"QSid": "204",
			"QDes": "/吃",
			"IQLid": "174",
			"AQLid": "153",
			"QHide": "1",
			"EMCode": "274"
		},
		{
			"QSid": "200",
			"QDes": "/求求",
			"IQLid": "170",
			"AQLid": "149",
			"QHide": "1",
			"EMCode": "270"
		},
		{
			"QSid": "290",
			"QDes": "/敲开心",
			"IQLid": "290",
			"isCMEmoji": "1",
			"AQLid": "290",
			"QHide": "1",
			"EMCode": "20240"
		},
		{
			"QSid": "224",
			"QDes": "/开枪",
			"IQLid": "194",
			"isCMEmoji": "1",
			"AQLid": "196",
			"QHide": "1",
			"EMCode": "295"
		},
		{
			"QSid": "229",
			"QDes": "/干杯",
			"IQLid": "199",
			"isCMEmoji": "1",
			"AQLid": "201",
			"QHide": "1",
			"EMCode": "299"
		},
		{
			"QSid": "221",
			"QDes": "/顶呱呱",
			"IQLid": "191",
			"isCMEmoji": "1",
			"AQLid": "193",
			"QHide": "1",
			"EMCode": "291"
		},
		{
			"QSid": "219",
			"QDes": "/蹭一蹭",
			"IQLid": "189",
			"isCMEmoji": "1",
			"AQLid": "191",
			"QHide": "1",
			"EMCode": "289"
		},
		{
			"QSid": "227",
			"QDes": "/拍手",
			"IQLid": "197",
			"isCMEmoji": "1",
			"AQLid": "199",
			"QHide": "1",
			"EMCode": "294"
		},
		{
			"QSid": "216",
			"QDes": "/拍头",
			"IQLid": "186",
			"isCMEmoji": "1",
			"AQLid": "188",
			"QHide": "1",
			"EMCode": "286"
		},
		{
			"QSid": "231",
			"QDes": "/哼",
			"IQLid": "201",
			"isCMEmoji": "1",
			"AQLid": "203",
			"QHide": "1",
			"EMCode": "301"
		},
		{
			"QSid": "244",
			"QDes": "/扔狗",
			"IQLid": "214",
			"isCMEmoji": "1",
			"AQLid": "216",
			"QHide": "1",
			"EMCode": "312"
		},
		{
			"QSid": "223",
			"QDes": "/暴击",
			"IQLid": "193",
			"isCMEmoji": "1",
			"AQLid": "195",
			"QHide": "1",
			"EMCode": "293"
		},
		{
			"QSid": "243",
			"QDes": "/甩头",
			"IQLid": "213",
			"isCMEmoji": "1",
			"AQLid": "215",
			"QHide": "1",
			"EMCode": "313"
		},
		{
			"QSid": "211",
			"QDes": "/我不看",
			"IQLid": "181",
			"AQLid": "160",
			"QHide": "1",
			"EMCode": "281"
		},
		{
			"QSid": "292",
			"QDes": "/让我康康",
			"IQLid": "292",
			"isCMEmoji": "1",
			"AQLid": "292",
			"QHide": "1",
			"EMCode": "20242"
		},
		{
			"QSid": "240",
			"QDes": "/喷脸",
			"IQLid": "210",
			"isCMEmoji": "1",
			"AQLid": "212",
			"QHide": "1",
			"EMCode": "310"
		},
		{
			"QSid": "180",
			"QDes": "/惊喜",
			"IQLid": "150",
			"AQLid": "172",
			"QHide": "1",
			"EMCode": "250"
		},
		{
			"QSid": "122",
			"QDes": "/爱你",
			"IQLid": "65",
			"AQLid": "65",
			"QHide": "1",
			"EMCode": "187"
		},
		{
			"QSid": "202",
			"QDes": "/无聊",
			"IQLid": "172",
			"AQLid": "151",
			"QHide": "1",
			"EMCode": "272"
		},
		{
			"QSid": "278",
			"QDes": "/汗",
			"IQLid": "278",
			"isCMEmoji": "1",
			"AQLid": "278",
			"QHide": "1",
			"EMCode": "20237"
		},
		{
			"QSid": "301",
			"QDes": "/好闪",
			"IQLid": "301",
			"AQLid": "301",
			"QHide": "1",
			"EMCode": "10301"
		},
		{
			"QSid": "288",
			"QDes": "/请",
			"IQLid": "288",
			"AQLid": "288",
			"QHide": "1",
			"EMCode": "10288"
		},
		{
			"QSid": "322",
			"QDes": "/拒绝",
			"IQLid": "322",
			"AQLid": "322",
			"QHide": "1",
			"EMCode": "10322"
		},
		{
			"QSid": "198",
			"QDes": "/呃",
			"IQLid": "168",
			"AQLid": "147",
			"QHide": "1",
			"EMCode": "268"
		},
		{
			"QSid": "348",
			"QDes": "/福萝卜",
			"IQLid": "348",
			"AQLid": "348",
			"QHide": "1",
			"EMCode": "10348"
		},
		{
			"QSid": "206",
			"QDes": "/害怕",
			"IQLid": "176",
			"AQLid": "155",
			"QHide": "1",
			"EMCode": "276"
		},
		{
			"QSid": "239",
			"QDes": "/原谅",
			"IQLid": "209",
			"isCMEmoji": "1",
			"AQLid": "211",
			"QHide": "1",
			"EMCode": "309"
		}
	],
	emoji: [
		{
			"QSid": "😊",
			"QCid": "128522",
			"AQLid": "0",
			"QDes": "/嘿嘿",
			"EMCode": "400832"
		},
		{
			"QSid": "😌",
			"QCid": "128524",
			"AQLid": "1",
			"QDes": "/羞涩",
			"EMCode": "400834"
		},
		{
			"QSid": "😚",
			"QCid": "128538",
			"AQLid": "2",
			"QDes": "/亲亲",
			"EMCode": "400848"
		},
		{
			"QSid": "😓",
			"QCid": "128531",
			"AQLid": "3",
			"QDes": "/汗",
			"EMCode": "400841"
		},
		{
			"QSid": "😰",
			"QCid": "128560",
			"AQLid": "4",
			"QDes": "/紧张",
			"EMCode": "400870"
		},
		{
			"QSid": "😝",
			"QCid": "128541",
			"AQLid": "5",
			"QDes": "/吐舌",
			"EMCode": "400851"
		},
		{
			"QSid": "😁",
			"QCid": "128513",
			"AQLid": "6",
			"QDes": "/呲牙",
			"EMCode": "400823"
		},
		{
			"QSid": "😜",
			"QCid": "128540",
			"AQLid": "7",
			"QDes": "/淘气",
			"EMCode": "400850"
		},
		{
			"QSid": "☺",
			"QCid": "9786",
			"AQLid": "8",
			"QDes": "/可爱",
			"EMCode": "401181"
		},
		{
			"QSid": "😉",
			"QCid": "128521",
			"AQLid": "9",
			"QDes": "/媚眼",
			"QHide": "1",
			"EMCode": "400831"
		},
		{
			"QSid": "😍",
			"QCid": "128525",
			"AQLid": "10",
			"QDes": "/花痴",
			"EMCode": "400835"
		},
		{
			"QSid": "😔",
			"QCid": "128532",
			"AQLid": "11",
			"QDes": "/失落",
			"EMCode": "400842"
		},
		{
			"QSid": "😄",
			"QCid": "128516",
			"AQLid": "12",
			"QDes": "/高兴",
			"EMCode": "400826"
		},
		{
			"QSid": "😏",
			"QCid": "128527",
			"AQLid": "13",
			"QDes": "/哼哼",
			"EMCode": "400837"
		},
		{
			"QSid": "😒",
			"QCid": "128530",
			"AQLid": "14",
			"QDes": "/不屑",
			"EMCode": "400840"
		},
		{
			"QSid": "😳",
			"QCid": "128563",
			"AQLid": "15",
			"QDes": "/瞪眼",
			"EMCode": "400873"
		},
		{
			"QSid": "😘",
			"QCid": "128536",
			"AQLid": "16",
			"QDes": "/飞吻",
			"EMCode": "400846"
		},
		{
			"QSid": "😭",
			"QCid": "128557",
			"AQLid": "17",
			"QDes": "/大哭",
			"EMCode": "400867"
		},
		{
			"QSid": "😱",
			"QCid": "128561",
			"AQLid": "18",
			"QDes": "/害怕",
			"EMCode": "400871"
		},
		{
			"QSid": "😂",
			"QCid": "128514",
			"AQLid": "19",
			"QDes": "/激动",
			"EMCode": "400824"
		},
		{
			"QSid": "💪",
			"QCid": "128170",
			"AQLid": "20",
			"QDes": "/肌肉",
			"EMCode": "400644"
		},
		{
			"QSid": "👊",
			"QCid": "128074",
			"AQLid": "21",
			"QDes": "/拳头",
			"EMCode": "400390"
		},
		{
			"QSid": "👍",
			"QCid": "128077",
			"AQLid": "22",
			"QDes": "/厉害",
			"EMCode": "400408"
		},
		{
			"QSid": "☝",
			"QCid": "9757",
			"AQLid": "23",
			"QDes": "/向上",
			"QHide": "1",
			"EMCode": "401203"
		},
		{
			"QSid": "👏",
			"QCid": "128079",
			"AQLid": "24",
			"QDes": "/鼓掌",
			"EMCode": "400420"
		},
		{
			"QSid": "✌",
			"QCid": "9996",
			"AQLid": "25",
			"QDes": "/胜利",
			"QHide": "1",
			"EMCode": "401210"
		},
		{
			"QSid": "👎",
			"QCid": "128078",
			"AQLid": "26",
			"QDes": "/鄙视",
			"EMCode": "400414"
		},
		{
			"QSid": "🙏",
			"QCid": "128591",
			"AQLid": "27",
			"QDes": "/合十",
			"EMCode": "400396"
		},
		{
			"QSid": "👌",
			"QCid": "128076",
			"AQLid": "28",
			"QDes": "/好的",
			"EMCode": "400402"
		},
		{
			"QSid": "👈",
			"QCid": "128072",
			"AQLid": "29",
			"QDes": "/向左",
			"QHide": "1",
			"EMCode": "400378"
		},
		{
			"QSid": "👉",
			"QCid": "128073",
			"AQLid": "30",
			"QDes": "/向右",
			"QHide": "1",
			"EMCode": "400384"
		},
		{
			"QSid": "👆",
			"QCid": "128070",
			"AQLid": "31",
			"QDes": "/向上",
			"EMCode": "400366"
		},
		{
			"QSid": "👇",
			"QCid": "128071",
			"AQLid": "32",
			"QDes": "/向下",
			"QHide": "1",
			"EMCode": "400372"
		},
		{
			"QSid": "👀",
			"QCid": "128064",
			"AQLid": "33",
			"QDes": "/眼睛",
			"EMCode": "400351"
		},
		{
			"QSid": "👃",
			"QCid": "128067",
			"AQLid": "34",
			"QDes": "/鼻子",
			"QHide": "1",
			"EMCode": "400358"
		},
		{
			"QSid": "👄",
			"QCid": "128068",
			"AQLid": "35",
			"QDes": "/嘴唇",
			"QHide": "1",
			"EMCode": "400364"
		},
		{
			"QSid": "👂",
			"QCid": "128066",
			"AQLid": "36",
			"QDes": "/耳朵",
			"QHide": "1",
			"EMCode": "400352"
		},
		{
			"QSid": "🍚",
			"QCid": "127834",
			"AQLid": "37",
			"QDes": "/米饭",
			"QHide": "1",
			"EMCode": "400149"
		},
		{
			"QSid": "🍝",
			"QCid": "127837",
			"AQLid": "38",
			"QDes": "/意面",
			"QHide": "1",
			"EMCode": "400152"
		},
		{
			"QSid": "🍜",
			"QCid": "127836",
			"AQLid": "39",
			"QDes": "/拉面",
			"EMCode": "400151"
		},
		{
			"QSid": "🍙",
			"QCid": "127833",
			"AQLid": "40",
			"QDes": "/饭团",
			"QHide": "1",
			"EMCode": "400148"
		},
		{
			"QSid": "🍧",
			"QCid": "127847",
			"AQLid": "41",
			"QDes": "/刨冰",
			"EMCode": "400162"
		},
		{
			"QSid": "🍣",
			"QCid": "127843",
			"AQLid": "42",
			"QDes": "/寿司",
			"QHide": "1",
			"EMCode": "400158"
		},
		{
			"QSid": "🎂",
			"QCid": "127874",
			"AQLid": "43",
			"QDes": "/蛋糕",
			"QHide": "1",
			"EMCode": "400186"
		},
		{
			"QSid": "🍞",
			"QCid": "127838",
			"AQLid": "44",
			"QDes": "/面包",
			"EMCode": "400153"
		},
		{
			"QSid": "🍔",
			"QCid": "127828",
			"AQLid": "45",
			"QDes": "/汉堡",
			"QHide": "1",
			"EMCode": "400143"
		},
		{
			"QSid": "🍳",
			"QCid": "127859",
			"AQLid": "46",
			"QDes": "/煎蛋",
			"QHide": "1",
			"EMCode": "400174"
		},
		{
			"QSid": "🍟",
			"QCid": "127839",
			"AQLid": "47",
			"QDes": "/薯条",
			"QHide": "1",
			"EMCode": "400154"
		},
		{
			"QSid": "🍺",
			"QCid": "127866",
			"AQLid": "48",
			"QDes": "/啤酒",
			"EMCode": "400181"
		},
		{
			"QSid": "🍻",
			"QCid": "127867",
			"AQLid": "49",
			"QDes": "/干杯",
			"EMCode": "400182"
		},
		{
			"QSid": "🍸",
			"QCid": "127864",
			"AQLid": "50",
			"QDes": "/高脚杯",
			"QHide": "1",
			"EMCode": "400179"
		},
		{
			"QSid": "☕",
			"QCid": "9749",
			"AQLid": "51",
			"QDes": "/咖啡",
			"EMCode": "401262"
		},
		{
			"QSid": "🍎",
			"QCid": "127822",
			"AQLid": "52",
			"QDes": "/苹果",
			"EMCode": "400137"
		},
		{
			"QSid": "🍊",
			"QCid": "127818",
			"AQLid": "53",
			"QDes": "/橙子",
			"QHide": "1",
			"EMCode": "400133"
		},
		{
			"QSid": "🍓",
			"QCid": "127827",
			"AQLid": "54",
			"QDes": "/草莓",
			"EMCode": "400142"
		},
		{
			"QSid": "🍉",
			"QCid": "127817",
			"AQLid": "55",
			"QDes": "/西瓜",
			"EMCode": "400132"
		},
		{
			"QSid": "💊",
			"QCid": "128138",
			"AQLid": "56",
			"QDes": "/药丸",
			"QHide": "1",
			"EMCode": "400612"
		},
		{
			"QSid": "🚬",
			"QCid": "128684",
			"AQLid": "57",
			"QDes": "/吸烟",
			"EMCode": "400987"
		},
		{
			"QSid": "🎄",
			"QCid": "127876",
			"AQLid": "58",
			"QDes": "/圣诞树",
			"QHide": "1",
			"EMCode": "400188"
		},
		{
			"QSid": "🌹",
			"QCid": "127801",
			"AQLid": "59",
			"QDes": "/玫瑰",
			"EMCode": "400116"
		},
		{
			"QSid": "🎉",
			"QCid": "127881",
			"AQLid": "60",
			"QDes": "/庆祝",
			"EMCode": "400198"
		},
		{
			"QSid": "🌴",
			"QCid": "127796",
			"AQLid": "61",
			"QDes": "/椰子树",
			"QHide": "1",
			"EMCode": "400112"
		},
		{
			"QSid": "💝",
			"QCid": "128157",
			"AQLid": "62",
			"QDes": "/礼物",
			"EMCode": "400631"
		},
		{
			"QSid": "🎀",
			"QCid": "127872",
			"AQLid": "63",
			"QDes": "/蝴蝶结",
			"QHide": "1",
			"EMCode": "400184"
		},
		{
			"QSid": "🎈",
			"QCid": "127880",
			"AQLid": "64",
			"QDes": "/气球",
			"QHide": "1",
			"EMCode": "400197"
		},
		{
			"QSid": "🐚",
			"QCid": "128026",
			"AQLid": "65",
			"QDes": "/海螺",
			"QHide": "1",
			"EMCode": "400314"
		},
		{
			"QSid": "💍",
			"QCid": "128141",
			"AQLid": "66",
			"QDes": "/戒指",
			"QHide": "1",
			"EMCode": "400615"
		},
		{
			"QSid": "💣",
			"QCid": "128163",
			"AQLid": "67",
			"QDes": "/炸弹",
			"EMCode": "400637"
		},
		{
			"QSid": "👑",
			"QCid": "128081",
			"AQLid": "68",
			"QDes": "/皇冠",
			"QHide": "1",
			"EMCode": "400432"
		},
		{
			"QSid": "🔔",
			"QCid": "128276",
			"AQLid": "69",
			"QDes": "/铃铛",
			"QHide": "1",
			"EMCode": "400751"
		},
		{
			"QSid": "⭐",
			"QCid": "11088",
			"AQLid": "70",
			"QDes": "/星星",
			"QHide": "1",
			"EMCode": "401686"
		},
		{
			"QSid": "✨",
			"QCid": "10024",
			"AQLid": "71",
			"QDes": "/闪光",
			"EMCode": "401137"
		},
		{
			"QSid": "💨",
			"QCid": "128168",
			"AQLid": "72",
			"QDes": "/吹气",
			"EMCode": "400642"
		},
		{
			"QSid": "💦",
			"QCid": "128166",
			"AQLid": "73",
			"QDes": "/水",
			"EMCode": "400640"
		},
		{
			"QSid": "🔥",
			"QCid": "128293",
			"AQLid": "74",
			"QDes": "/火",
			"EMCode": "400768"
		},
		{
			"QSid": "🏆",
			"QCid": "127942",
			"AQLid": "75",
			"QDes": "/奖杯",
			"QHide": "1",
			"EMCode": "400256"
		},
		{
			"QSid": "💰",
			"QCid": "128176",
			"AQLid": "76",
			"QDes": "/钱",
			"QHide": "1",
			"EMCode": "400655"
		},
		{
			"QSid": "💤",
			"QCid": "128164",
			"AQLid": "77",
			"QDes": "/睡觉",
			"EMCode": "400638"
		},
		{
			"QSid": "⚡",
			"QCid": "9889",
			"AQLid": "78",
			"QDes": "/闪电",
			"QHide": "1",
			"EMCode": "401685"
		},
		{
			"QSid": "👣",
			"QCid": "128099",
			"AQLid": "79",
			"QDes": "/脚印",
			"QHide": "1",
			"EMCode": "400450"
		},
		{
			"QSid": "💩",
			"QCid": "128169",
			"AQLid": "80",
			"QDes": "/便便",
			"EMCode": "400643"
		},
		{
			"QSid": "💉",
			"QCid": "128137",
			"AQLid": "81",
			"QDes": "/打针",
			"EMCode": "400611"
		},
		{
			"QSid": "♨",
			"QCid": "9832",
			"AQLid": "82",
			"QDes": "/热",
			"QHide": "1",
			"EMCode": "401287"
		},
		{
			"QSid": "📫",
			"QCid": "128235",
			"AQLid": "83",
			"QDes": "/邮箱",
			"EMCode": "400714"
		},
		{
			"QSid": "🔑",
			"QCid": "128273",
			"AQLid": "84",
			"QDes": "/钥匙",
			"QHide": "1",
			"EMCode": "400748"
		},
		{
			"QSid": "🔒",
			"QCid": "128274",
			"AQLid": "85",
			"QDes": "/锁",
			"QHide": "1",
			"EMCode": "400749"
		},
		{
			"QSid": "✈",
			"QCid": "9992",
			"AQLid": "86",
			"QDes": "/飞机",
			"QHide": "1",
			"EMCode": "401298"
		},
		{
			"QSid": "🚄",
			"QCid": "128644",
			"AQLid": "87",
			"QDes": "/列车",
			"QHide": "1",
			"EMCode": "400942"
		},
		{
			"QSid": "🚗",
			"QCid": "128663",
			"AQLid": "88",
			"QDes": "/汽车",
			"QHide": "1",
			"EMCode": "400961"
		},
		{
			"QSid": "🚤",
			"QCid": "128676",
			"AQLid": "89",
			"QDes": "/快艇",
			"QHide": "1",
			"EMCode": "400979"
		},
		{
			"QSid": "🚲",
			"QCid": "128690",
			"AQLid": "90",
			"QDes": "/自行车",
			"QHide": "1",
			"EMCode": "400993"
		},
		{
			"QSid": "🐎",
			"QCid": "128014",
			"AQLid": "91",
			"QDes": "/骑马",
			"EMCode": "400302"
		},
		{
			"QSid": "🚀",
			"QCid": "128640",
			"AQLid": "92",
			"QDes": "/火箭",
			"QHide": "1",
			"EMCode": "400938"
		},
		{
			"QSid": "🚌",
			"QCid": "128652",
			"AQLid": "93",
			"QDes": "/公交",
			"QHide": "1",
			"EMCode": "400950"
		},
		{
			"QSid": "⛵",
			"QCid": "9973",
			"AQLid": "94",
			"QDes": "/船",
			"QHide": "1",
			"EMCode": "401294"
		},
		{
			"QSid": "👩",
			"QCid": "128105",
			"AQLid": "95",
			"QDes": "/妈妈",
			"QHide": "1",
			"EMCode": "400482"
		},
		{
			"QSid": "👨",
			"QCid": "128104",
			"AQLid": "96",
			"QDes": "/爸爸",
			"QHide": "1",
			"EMCode": "400465"
		},
		{
			"QSid": "👧",
			"QCid": "128103",
			"AQLid": "97",
			"QDes": "/女孩",
			"EMCode": "400459"
		},
		{
			"QSid": "👦",
			"QCid": "128102",
			"AQLid": "98",
			"QDes": "/男孩",
			"EMCode": "400453"
		},
		{
			"QSid": "🐵",
			"QCid": "128053",
			"AQLid": "99",
			"QDes": "/猴",
			"EMCode": "400341"
		},
		{
			"QSid": "🐙",
			"QCid": "128025",
			"AQLid": "100",
			"QDes": "/章鱼",
			"QHide": "1",
			"EMCode": "400313"
		},
		{
			"QSid": "🐷",
			"QCid": "128055",
			"AQLid": "101",
			"QDes": "/猪",
			"EMCode": "400343"
		},
		{
			"QSid": "💀",
			"QCid": "128128",
			"AQLid": "102",
			"QDes": "/骷髅",
			"QHide": "1",
			"EMCode": "400572"
		},
		{
			"QSid": "🐤",
			"QCid": "128036",
			"AQLid": "103",
			"QDes": "/小鸡",
			"QHide": "1",
			"EMCode": "400324"
		},
		{
			"QSid": "🐨",
			"QCid": "128040",
			"AQLid": "104",
			"QDes": "/树懒",
			"QHide": "1",
			"EMCode": "400328"
		},
		{
			"QSid": "🐮",
			"QCid": "128046",
			"AQLid": "105",
			"QDes": "/牛",
			"EMCode": "400334"
		},
		{
			"QSid": "🐔",
			"QCid": "128020",
			"AQLid": "106",
			"QDes": "/公鸡",
			"EMCode": "400308"
		},
		{
			"QSid": "🐸",
			"QCid": "128056",
			"AQLid": "107",
			"QDes": "/青蛙",
			"EMCode": "400344"
		},
		{
			"QSid": "👻",
			"QCid": "128123",
			"AQLid": "108",
			"QDes": "/幽灵",
			"EMCode": "400562"
		},
		{
			"QSid": "🐛",
			"QCid": "128027",
			"AQLid": "109",
			"QDes": "/虫",
			"EMCode": "400315"
		},
		{
			"QSid": "🐠",
			"QCid": "128032",
			"AQLid": "110",
			"QDes": "/鱼",
			"QHide": "1",
			"EMCode": "400320"
		},
		{
			"QSid": "🐶",
			"QCid": "128054",
			"AQLid": "111",
			"QDes": "/狗",
			"EMCode": "400342"
		},
		{
			"QSid": "🐯",
			"QCid": "128047",
			"AQLid": "112",
			"QDes": "/老虎",
			"QHide": "1",
			"EMCode": "400335"
		},
		{
			"QSid": "👼",
			"QCid": "128124",
			"AQLid": "113",
			"QDes": "/天使",
			"QHide": "1",
			"EMCode": "400563"
		},
		{
			"QSid": "🐧",
			"QCid": "128039",
			"AQLid": "114",
			"QDes": "/企鹅",
			"QHide": "1",
			"EMCode": "400327"
		},
		{
			"QSid": "🐳",
			"QCid": "128051",
			"AQLid": "115",
			"QDes": "/鲸鱼",
			"EMCode": "400339"
		},
		{
			"QSid": "🐭",
			"QCid": "128045",
			"AQLid": "116",
			"QDes": "/老鼠",
			"QHide": "1",
			"EMCode": "400333"
		},
		{
			"QSid": "👒",
			"QCid": "128082",
			"AQLid": "117",
			"QDes": "/帽子",
			"QHide": "1",
			"EMCode": "400433"
		},
		{
			"QSid": "👗",
			"QCid": "128087",
			"AQLid": "118",
			"QDes": "/连衣裙",
			"QHide": "1",
			"EMCode": "400438"
		},
		{
			"QSid": "💄",
			"QCid": "128132",
			"AQLid": "119",
			"QDes": "/口红",
			"QHide": "1",
			"EMCode": "400591"
		},
		{
			"QSid": "👠",
			"QCid": "128096",
			"AQLid": "120",
			"QDes": "/高跟鞋",
			"QHide": "1",
			"EMCode": "400447"
		},
		{
			"QSid": "👢",
			"QCid": "128098",
			"AQLid": "121",
			"QDes": "/靴子",
			"EMCode": "400449"
		},
		{
			"QSid": "🌂",
			"QCid": "127746",
			"AQLid": "122",
			"QDes": "/雨伞",
			"QHide": "1",
			"EMCode": "400077"
		},
		{
			"QSid": "👜",
			"QCid": "128092",
			"AQLid": "123",
			"QDes": "/包",
			"QHide": "1",
			"EMCode": "400443"
		},
		{
			"QSid": "👙",
			"QCid": "128089",
			"AQLid": "124",
			"QDes": "/内衣",
			"QHide": "1",
			"EMCode": "400440"
		},
		{
			"QSid": "👕",
			"QCid": "128085",
			"AQLid": "125",
			"QDes": "/衣服",
			"QHide": "1",
			"EMCode": "400436"
		},
		{
			"QSid": "👟",
			"QCid": "128095",
			"AQLid": "126",
			"QDes": "/鞋子",
			"QHide": "1",
			"EMCode": "400446"
		},
		{
			"QSid": "☁",
			"QCid": "9729",
			"AQLid": "127",
			"QDes": "/云朵",
			"QHide": "1",
			"EMCode": "401329"
		},
		{
			"QSid": "☀",
			"QCid": "9728",
			"AQLid": "128",
			"QDes": "/晴天",
			"EMCode": "401328"
		},
		{
			"QSid": "☔",
			"QCid": "9748",
			"AQLid": "129",
			"QDes": "/雨天",
			"QHide": "1",
			"EMCode": "401342"
		},
		{
			"QSid": "🌙",
			"QCid": "127769",
			"AQLid": "130",
			"QDes": "/月亮",
			"QHide": "1",
			"EMCode": "400100"
		},
		{
			"QSid": "⛄",
			"QCid": "9924",
			"AQLid": "131",
			"QDes": "/雪人",
			"QHide": "1",
			"EMCode": "401346"
		},
		{
			"QSid": "⭕",
			"QCid": "11093",
			"AQLid": "132",
			"QDes": "/正确",
			"QHide": "1",
			"EMCode": "401687"
		},
		{
			"QSid": "❌",
			"QCid": "10060",
			"AQLid": "133",
			"QDes": "/错误",
			"QHide": "1",
			"EMCode": "401142"
		},
		{
			"QSid": "❔",
			"QCid": "10068",
			"AQLid": "134",
			"QDes": "/问号",
			"EMCode": "401145"
		},
		{
			"QSid": "❕",
			"QCid": "10069",
			"AQLid": "135",
			"QDes": "/叹号",
			"QHide": "1",
			"EMCode": "401146"
		},
		{
			"QSid": "☎",
			"QCid": "9742",
			"AQLid": "136",
			"QDes": "/电话",
			"QHide": "1",
			"EMCode": "401398"
		},
		{
			"QSid": "📷",
			"QCid": "128247",
			"AQLid": "137",
			"QDes": "/相机",
			"QHide": "1",
			"EMCode": "400726"
		},
		{
			"QSid": "📱",
			"QCid": "128241",
			"AQLid": "138",
			"QDes": "/手机",
			"QHide": "1",
			"EMCode": "400720"
		},
		{
			"QSid": "📠",
			"QCid": "128224",
			"AQLid": "139",
			"QDes": "/传真",
			"QHide": "1",
			"EMCode": "400703"
		},
		{
			"QSid": "💻",
			"QCid": "128187",
			"AQLid": "140",
			"QDes": "/电脑",
			"QHide": "1",
			"EMCode": "400666"
		},
		{
			"QSid": "🎥",
			"QCid": "127909",
			"AQLid": "141",
			"QDes": "/摄影机",
			"QHide": "1",
			"EMCode": "400214"
		},
		{
			"QSid": "🎤",
			"QCid": "127908",
			"AQLid": "142",
			"QDes": "/话筒",
			"QHide": "1",
			"EMCode": "400213"
		},
		{
			"QSid": "🔫",
			"QCid": "128299",
			"AQLid": "143",
			"QDes": "/手枪",
			"EMCode": "400774"
		},
		{
			"QSid": "💿",
			"QCid": "128191",
			"AQLid": "144",
			"QDes": "/光碟",
			"QHide": "1",
			"EMCode": "400670"
		},
		{
			"QSid": "💓",
			"QCid": "128147",
			"AQLid": "145",
			"QDes": "/爱心",
			"EMCode": "400621"
		},
		{
			"QSid": "♣",
			"QCid": "9827",
			"AQLid": "146",
			"QDes": "/扑克",
			"QHide": "1",
			"EMCode": "401385"
		},
		{
			"QSid": "🀄",
			"QCid": "126980",
			"AQLid": "147",
			"QDes": "/麻将",
			"QHide": "1",
			"EMCode": "401386"
		},
		{
			"QSid": "〽",
			"QCid": "12349",
			"AQLid": "148",
			"QDes": "/股票",
			"QHide": "1",
			"EMCode": "401691"
		},
		{
			"QSid": "🎰",
			"QCid": "127920",
			"AQLid": "149",
			"QDes": "/老虎机",
			"QHide": "1",
			"EMCode": "400225"
		},
		{
			"QSid": "🚥",
			"QCid": "128677",
			"AQLid": "150",
			"QDes": "/信号灯",
			"QHide": "1",
			"EMCode": "400980"
		},
		{
			"QSid": "🚧",
			"QCid": "128679",
			"AQLid": "151",
			"QDes": "/路障",
			"QHide": "1",
			"EMCode": "400982"
		},
		{
			"QSid": "🎸",
			"QCid": "127928",
			"AQLid": "152",
			"QDes": "/吉他",
			"QHide": "1",
			"EMCode": "400233"
		},
		{
			"QSid": "💈",
			"QCid": "128136",
			"AQLid": "153",
			"QDes": "/理发厅",
			"QHide": "1",
			"EMCode": "400610"
		},
		{
			"QSid": "🛀",
			"QCid": "128704",
			"AQLid": "154",
			"QDes": "/浴缸",
			"QHide": "1",
			"EMCode": "401022"
		},
		{
			"QSid": "🚽",
			"QCid": "128701",
			"AQLid": "155",
			"QDes": "/马桶",
			"QHide": "1",
			"EMCode": "401019"
		},
		{
			"QSid": "🏠",
			"QCid": "127968",
			"AQLid": "156",
			"QDes": "/家",
			"QHide": "1",
			"EMCode": "400271"
		},
		{
			"QSid": "⛪",
			"QCid": "9962",
			"AQLid": "157",
			"QDes": "/教堂",
			"QHide": "1",
			"EMCode": "401281"
		},
		{
			"QSid": "🏦",
			"QCid": "127974",
			"AQLid": "158",
			"QDes": "/银行",
			"QHide": "1",
			"EMCode": "400277"
		},
		{
			"QSid": "🏥",
			"QCid": "127973",
			"AQLid": "159",
			"QDes": "/医院",
			"QHide": "1",
			"EMCode": "400276"
		},
		{
			"QSid": "🏨",
			"QCid": "127976",
			"AQLid": "160",
			"QDes": "/酒店",
			"QHide": "1",
			"EMCode": "400279"
		},
		{
			"QSid": "🏧",
			"QCid": "127975",
			"AQLid": "161",
			"QDes": "/取款机",
			"QHide": "1",
			"EMCode": "400278"
		},
		{
			"QSid": "🏪",
			"QCid": "127978",
			"AQLid": "162",
			"QDes": "/便利店",
			"EMCode": "400281"
		},
		{
			"QSid": "🚹",
			"QCid": "128697",
			"AQLid": "163",
			"QDes": "/男性",
			"QHide": "1",
			"EMCode": "401015"
		},
		{
			"QSid": "🚺",
			"QCid": "128698",
			"AQLid": "164",
			"QDes": "/女性",
			"QHide": "1",
			"EMCode": "401016"
		}
	]
};
//#endregion
//#region src/common/image-size/lib/types/utils.ts
var decoder = new TextDecoder();
var toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
var toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), "");
var getView = (input, offset) => new DataView(input.buffer, input.byteOffset + offset);
var readInt16LE = (input, offset = 0) => getView(input, offset).getInt16(0, true);
var readUInt16BE = (input, offset = 0) => getView(input, offset).getUint16(0, false);
var readUInt16LE = (input, offset = 0) => getView(input, offset).getUint16(0, true);
var readUInt24LE = (input, offset = 0) => {
	const view = getView(input, offset);
	return view.getUint16(0, true) + (view.getUint8(2) << 16);
};
var readInt32LE = (input, offset = 0) => getView(input, offset).getInt32(0, true);
var readUInt32BE = (input, offset = 0) => getView(input, offset).getUint32(0, false);
var readUInt32LE = (input, offset = 0) => getView(input, offset).getUint32(0, true);
var readUInt64 = (input, offset, isBigEndian) => getView(input, offset).getBigUint64(0, !isBigEndian);
var methods = {
	readUInt16BE,
	readUInt16LE,
	readUInt32BE,
	readUInt32LE
};
function readUInt(input, bits, offset = 0, isBigEndian = false) {
	return methods[`readUInt${bits}${isBigEndian ? "BE" : "LE"}`](input, offset);
}
function readBox(input, offset) {
	if (input.length - offset < 4) return;
	const boxSize = readUInt32BE(input, offset);
	if (input.length - offset < boxSize) return;
	return {
		name: toUTF8String(input, 4 + offset, 8 + offset),
		offset,
		size: boxSize
	};
}
function findBox(input, boxName, currentOffset) {
	while (currentOffset < input.length) {
		const box = readBox(input, currentOffset);
		if (!box) break;
		if (box.name === boxName) return box;
		currentOffset += box.size > 0 ? box.size : 8;
	}
}
//#endregion
//#region src/common/image-size/lib/types/bmp.ts
var BMP = {
	validate: (input) => toUTF8String(input, 0, 2) === "BM",
	calculate: (input) => ({
		height: Math.abs(readInt32LE(input, 22)),
		width: readUInt32LE(input, 18)
	})
};
//#endregion
//#region src/common/image-size/lib/types/ico.ts
var TYPE_ICON = 1;
/**
* ICON Header
*
* | Offset | Size | Purpose |
* | 0	    | 2    | Reserved. Must always be 0.  |
* | 2      | 2    | Image type: 1 for icon (.ICO) image, 2 for cursor (.CUR) image. Other values are invalid. |
* | 4      | 2    | Number of images in the file. |
*
*/
var SIZE_HEADER$1 = 6;
/**
* Image Entry
*
* | Offset | Size | Purpose |
* | 0	    | 1    | Image width in pixels. Can be any number between 0 and 255. Value 0 means width is 256 pixels. |
* | 1      | 1    | Image height in pixels. Can be any number between 0 and 255. Value 0 means height is 256 pixels. |
* | 2      | 1    | Number of colors in the color palette. Should be 0 if the image does not use a color palette. |
* | 3      | 1    | Reserved. Should be 0. |
* | 4      | 2    | ICO format: Color planes. Should be 0 or 1. |
* |        |      | CUR format: The horizontal coordinates of the hotspot in number of pixels from the left. |
* | 6      | 2    | ICO format: Bits per pixel. |
* |        |      | CUR format: The vertical coordinates of the hotspot in number of pixels from the top. |
* | 8      | 4    | The size of the image's data in bytes |
* | 12     | 4    | The offset of BMP or PNG data from the beginning of the ICO/CUR file |
*
*/
var SIZE_IMAGE_ENTRY = 16;
function getSizeFromOffset(input, offset) {
	const value = input[offset];
	return value === 0 ? 256 : value;
}
function getImageSize$2(input, imageIndex) {
	const offset = SIZE_HEADER$1 + imageIndex * SIZE_IMAGE_ENTRY;
	return {
		height: getSizeFromOffset(input, offset + 1),
		width: getSizeFromOffset(input, offset)
	};
}
var ICO = {
	validate(input) {
		const reserved = readUInt16LE(input, 0);
		const imageCount = readUInt16LE(input, 4);
		if (reserved !== 0 || imageCount === 0) return false;
		return readUInt16LE(input, 2) === TYPE_ICON;
	},
	calculate(input) {
		const nbImages = readUInt16LE(input, 4);
		const imageSize = getImageSize$2(input, 0);
		if (nbImages === 1) return imageSize;
		const images = [];
		for (let imageIndex = 0; imageIndex < nbImages; imageIndex += 1) images.push(getImageSize$2(input, imageIndex));
		return {
			width: imageSize.width,
			height: imageSize.height,
			images
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/cur.ts
var TYPE_CURSOR = 2;
var CUR = {
	validate(input) {
		const reserved = readUInt16LE(input, 0);
		const imageCount = readUInt16LE(input, 4);
		if (reserved !== 0 || imageCount === 0) return false;
		return readUInt16LE(input, 2) === TYPE_CURSOR;
	},
	calculate: (input) => ICO.calculate(input)
};
//#endregion
//#region src/common/image-size/lib/types/dds.ts
var DDS = {
	validate: (input) => readUInt32LE(input, 0) === 542327876,
	calculate: (input) => ({
		height: readUInt32LE(input, 12),
		width: readUInt32LE(input, 16)
	})
};
//#endregion
//#region src/common/image-size/lib/types/gif.ts
var gifRegexp = /^GIF8[79]a/;
var GIF = {
	validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),
	calculate: (input) => ({
		height: readUInt16LE(input, 8),
		width: readUInt16LE(input, 6)
	})
};
//#endregion
//#region src/common/image-size/lib/types/heif.ts
var brandMap = {
	avif: "avif",
	mif1: "heif",
	msf1: "heif",
	heic: "heic",
	heix: "heic",
	hevc: "heic",
	hevx: "heic"
};
var HEIF = {
	validate(input) {
		if (toUTF8String(input, 4, 8) !== "ftyp") return false;
		const ftypBox = findBox(input, "ftyp", 0);
		if (!ftypBox) return false;
		return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) in brandMap;
	},
	calculate(input) {
		const metaBox = findBox(input, "meta", 0);
		const iprpBox = metaBox && findBox(input, "iprp", metaBox.offset + 12);
		const ipcoBox = iprpBox && findBox(input, "ipco", iprpBox.offset + 8);
		if (!ipcoBox) throw new TypeError("Invalid HEIF, no ipco box found");
		const type = toUTF8String(input, 8, 12);
		const images = [];
		let currentOffset = ipcoBox.offset + 8;
		while (currentOffset < ipcoBox.offset + ipcoBox.size) {
			const ispeBox = findBox(input, "ispe", currentOffset);
			if (!ispeBox) break;
			const rawWidth = readUInt32BE(input, ispeBox.offset + 12);
			const rawHeight = readUInt32BE(input, ispeBox.offset + 16);
			const clapBox = findBox(input, "clap", currentOffset);
			let width = rawWidth;
			let height = rawHeight;
			if (clapBox && clapBox.offset < ipcoBox.offset + ipcoBox.size) width = rawWidth - readUInt32BE(input, clapBox.offset + 12);
			images.push({
				height,
				width
			});
			currentOffset = ispeBox.offset + ispeBox.size;
		}
		if (images.length === 0) throw new TypeError("Invalid HEIF, no sizes found");
		return {
			width: images[0].width,
			height: images[0].height,
			type,
			...images.length > 1 ? { images } : {}
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/icns.ts
/**
* ICNS Header
*
* | Offset | Size | Purpose                                                |
* | 0	    | 4    | Magic literal, must be "icns" (0x69, 0x63, 0x6e, 0x73) |
* | 4      | 4    | Length of file, in bytes, msb first.                   |
*
*/
var SIZE_HEADER = 8;
var FILE_LENGTH_OFFSET = 4;
/**
* Image Entry
*
* | Offset | Size | Purpose                                                          |
* | 0	    | 4    | Icon type, see OSType below.                                     |
* | 4      | 4    | Length of data, in bytes (including type and length), msb first. |
* | 8      | n    | Icon data                                                        |
*/
var ENTRY_LENGTH_OFFSET = 4;
var ICON_TYPE_SIZE = {
	ICON: 32,
	"ICN#": 32,
	"icm#": 16,
	icm4: 16,
	icm8: 16,
	"ics#": 16,
	ics4: 16,
	ics8: 16,
	is32: 16,
	s8mk: 16,
	icp4: 16,
	icl4: 32,
	icl8: 32,
	il32: 32,
	l8mk: 32,
	icp5: 32,
	ic11: 32,
	ich4: 48,
	ich8: 48,
	ih32: 48,
	h8mk: 48,
	icp6: 64,
	ic12: 32,
	it32: 128,
	t8mk: 128,
	ic07: 128,
	ic08: 256,
	ic13: 256,
	ic09: 512,
	ic14: 512,
	ic10: 1024
};
function readImageHeader(input, imageOffset) {
	const imageLengthOffset = imageOffset + ENTRY_LENGTH_OFFSET;
	return [toUTF8String(input, imageOffset, imageLengthOffset), readUInt32BE(input, imageLengthOffset)];
}
function getImageSize$1(type) {
	const size = ICON_TYPE_SIZE[type];
	return {
		width: size,
		height: size,
		type
	};
}
var ICNS = {
	validate: (input) => toUTF8String(input, 0, 4) === "icns",
	calculate(input) {
		const inputLength = input.length;
		const fileLength = readUInt32BE(input, FILE_LENGTH_OFFSET);
		let imageOffset = SIZE_HEADER;
		const images = [];
		while (imageOffset < fileLength && imageOffset < inputLength) {
			const imageHeader = readImageHeader(input, imageOffset);
			const imageSize = getImageSize$1(imageHeader[0]);
			images.push(imageSize);
			imageOffset += imageHeader[1];
		}
		if (images.length === 0) throw new TypeError("Invalid ICNS, no sizes found");
		return {
			width: images[0].width,
			height: images[0].height,
			...images.length > 1 ? { images } : {}
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/j2c.ts
var J2C = {
	validate: (input) => readUInt32BE(input, 0) === 4283432785,
	calculate: (input) => ({
		height: readUInt32BE(input, 12),
		width: readUInt32BE(input, 8)
	})
};
//#endregion
//#region src/common/image-size/lib/types/jp2.ts
var JP2 = {
	validate(input) {
		if (toUTF8String(input, 4, 8) !== "jP  ") return false;
		const ftypBox = findBox(input, "ftyp", 0);
		if (!ftypBox) return false;
		return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) === "jp2 ";
	},
	calculate(input) {
		const jp2hBox = findBox(input, "jp2h", 0);
		const ihdrBox = jp2hBox && findBox(input, "ihdr", jp2hBox.offset + 8);
		if (ihdrBox) return {
			height: readUInt32BE(input, ihdrBox.offset + 8),
			width: readUInt32BE(input, ihdrBox.offset + 12)
		};
		throw new TypeError("Unsupported JPEG 2000 format");
	}
};
//#endregion
//#region src/common/image-size/lib/types/jpg.ts
var EXIF_MARKER = "45786966";
var APP1_DATA_SIZE_BYTES = 2;
var EXIF_HEADER_BYTES = 6;
var BIG_ENDIAN_BYTE_ALIGN = "4d4d";
var LITTLE_ENDIAN_BYTE_ALIGN = "4949";
var IDF_ENTRY_BYTES = 12;
function isEXIF(input) {
	return toHexString(input, 2, 6) === EXIF_MARKER;
}
function extractSize(input, index) {
	return {
		height: readUInt16BE(input, index),
		width: readUInt16BE(input, index + 2)
	};
}
function extractOrientation(exifBlock, isBigEndian) {
	const idfDirectoryEntries = readUInt(exifBlock, 16, 14, isBigEndian);
	for (let directoryEntryNumber = 0; directoryEntryNumber < idfDirectoryEntries; directoryEntryNumber++) {
		const start = 16 + directoryEntryNumber * IDF_ENTRY_BYTES;
		const end = start + IDF_ENTRY_BYTES;
		if (start > exifBlock.length) return;
		const block = exifBlock.slice(start, end);
		if (block.length < IDF_ENTRY_BYTES) return;
		if (readUInt(block, 16, 0, isBigEndian) === 274) {
			if (readUInt(block, 16, 2, isBigEndian) !== 3) return;
			if (readUInt(block, 32, 4, isBigEndian) !== 1) return;
			return readUInt(block, 16, 8, isBigEndian);
		}
	}
}
function validateExifBlock(input, index) {
	const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index);
	const byteAlign = toHexString(exifBlock, EXIF_HEADER_BYTES, 8);
	const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
	if (isBigEndian || byteAlign === LITTLE_ENDIAN_BYTE_ALIGN) return extractOrientation(exifBlock, isBigEndian);
}
function validateInput(input, index) {
	if (index > input.length) throw new TypeError("Corrupt JPG, exceeded buffer limits");
}
var JPG = {
	validate: (input) => toHexString(input, 0, 2) === "ffd8",
	calculate(_input) {
		let input = _input.slice(4);
		let orientation;
		let next;
		while (input.length) {
			const i = readUInt16BE(input, 0);
			validateInput(input, i);
			if (input[i] !== 255) {
				input = input.slice(1);
				continue;
			}
			if (isEXIF(input)) orientation = validateExifBlock(input, i);
			next = input[i + 1];
			if (next === 192 || next === 193 || next === 194) {
				const size = extractSize(input, i + 5);
				if (!orientation) return size;
				return {
					height: size.height,
					orientation,
					width: size.width
				};
			}
			input = input.slice(i + 2);
		}
		throw new TypeError("Invalid JPG, no size found");
	}
};
//#endregion
//#region src/common/image-size/lib/utils/bit-reader.ts
/** This class helps read Uint8Array bit-by-bit */
var BitReader = class {
	input;
	endianness;
	byteOffset = 2;
	bitOffset = 0;
	constructor(input, endianness) {
		this.input = input;
		this.endianness = endianness;
	}
	/** Reads a specified number of bits, and move the offset */
	getBits(length = 1) {
		let result = 0;
		let bitsRead = 0;
		while (bitsRead < length) {
			if (this.byteOffset >= this.input.length) throw new Error("Reached end of input");
			const currentByte = this.input[this.byteOffset];
			const bitsLeft = 8 - this.bitOffset;
			const bitsToRead = Math.min(length - bitsRead, bitsLeft);
			if (this.endianness === "little-endian") {
				const mask = (1 << bitsToRead) - 1;
				const bits = currentByte >> this.bitOffset & mask;
				result |= bits << bitsRead;
			} else {
				const bits = (currentByte & (1 << bitsToRead) - 1 << 8 - this.bitOffset - bitsToRead) >> 8 - this.bitOffset - bitsToRead;
				result = result << bitsToRead | bits;
			}
			bitsRead += bitsToRead;
			this.bitOffset += bitsToRead;
			if (this.bitOffset === 8) {
				this.byteOffset++;
				this.bitOffset = 0;
			}
		}
		return result;
	}
};
//#endregion
//#region src/common/image-size/lib/types/jxl-stream.ts
function calculateImageDimension(reader, isSmallImage) {
	if (isSmallImage) return 8 * (1 + reader.getBits(5));
	const extraBits = [
		9,
		13,
		18,
		30
	][reader.getBits(2)];
	return 1 + reader.getBits(extraBits);
}
function calculateImageWidth(reader, isSmallImage, widthMode, height) {
	if (isSmallImage && widthMode === 0) return 8 * (1 + reader.getBits(5));
	if (widthMode === 0) return calculateImageDimension(reader, false);
	return Math.floor(height * [
		1,
		1.2,
		4 / 3,
		1.5,
		16 / 9,
		5 / 4,
		2
	][widthMode - 1]);
}
var JXLStream = {
	validate: (input) => {
		return toHexString(input, 0, 2) === "ff0a";
	},
	calculate(input) {
		const reader = new BitReader(input, "little-endian");
		const isSmallImage = reader.getBits(1) === 1;
		const height = calculateImageDimension(reader, isSmallImage);
		return {
			width: calculateImageWidth(reader, isSmallImage, reader.getBits(3), height),
			height
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/jxl.ts
/** Extracts the codestream from a containerized JPEG XL image */
function extractCodestream(input) {
	const jxlcBox = findBox(input, "jxlc", 0);
	if (jxlcBox) return input.slice(jxlcBox.offset + 8, jxlcBox.offset + jxlcBox.size);
	const partialStreams = extractPartialStreams(input);
	if (partialStreams.length > 0) return concatenateCodestreams(partialStreams);
}
/** Extracts partial codestreams from jxlp boxes */
function extractPartialStreams(input) {
	const partialStreams = [];
	let offset = 0;
	while (offset < input.length) {
		const jxlpBox = findBox(input, "jxlp", offset);
		if (!jxlpBox) break;
		partialStreams.push(input.slice(jxlpBox.offset + 12, jxlpBox.offset + jxlpBox.size));
		offset = jxlpBox.offset + jxlpBox.size;
	}
	return partialStreams;
}
/** Concatenates partial codestreams into a single codestream */
function concatenateCodestreams(partialCodestreams) {
	const totalLength = partialCodestreams.reduce((acc, curr) => acc + curr.length, 0);
	const codestream = new Uint8Array(totalLength);
	let position = 0;
	for (const partial of partialCodestreams) {
		codestream.set(partial, position);
		position += partial.length;
	}
	return codestream;
}
var JXL = {
	validate: (input) => {
		if (toUTF8String(input, 4, 8) !== "JXL ") return false;
		const ftypBox = findBox(input, "ftyp", 0);
		if (!ftypBox) return false;
		return toUTF8String(input, ftypBox.offset + 8, ftypBox.offset + 12) === "jxl ";
	},
	calculate(input) {
		const codestream = extractCodestream(input);
		if (codestream) return JXLStream.calculate(codestream);
		throw new Error("No codestream found in JXL container");
	}
};
//#endregion
//#region src/common/image-size/lib/types/ktx.ts
var KTX = {
	validate: (input) => {
		const signature = toUTF8String(input, 1, 7);
		return ["KTX 11", "KTX 20"].includes(signature);
	},
	calculate: (input) => {
		const type = input[5] === 49 ? "ktx" : "ktx2";
		const offset = type === "ktx" ? 36 : 20;
		return {
			height: readUInt32LE(input, offset + 4),
			width: readUInt32LE(input, offset),
			type
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/png.ts
var pngSignature = "PNG\r\n\n";
var pngImageHeaderChunkName = "IHDR";
var pngFriedChunkName = "CgBI";
var PNG = {
	validate(input) {
		if (pngSignature === toUTF8String(input, 1, 8)) {
			let chunkName = toUTF8String(input, 12, 16);
			if (chunkName === pngFriedChunkName) chunkName = toUTF8String(input, 28, 32);
			if (chunkName !== pngImageHeaderChunkName) throw new TypeError("Invalid PNG");
			return true;
		}
		return false;
	},
	calculate(input) {
		if (toUTF8String(input, 12, 16) === pngFriedChunkName) return {
			height: readUInt32BE(input, 36),
			width: readUInt32BE(input, 32)
		};
		return {
			height: readUInt32BE(input, 20),
			width: readUInt32BE(input, 16)
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/pnm.ts
var PNMTypes = {
	P1: "pbm/ascii",
	P2: "pgm/ascii",
	P3: "ppm/ascii",
	P4: "pbm",
	P5: "pgm",
	P6: "ppm",
	P7: "pam",
	PF: "pfm"
};
var handlers$1 = {
	default: (lines) => {
		let dimensions = [];
		while (lines.length > 0) {
			const line = lines.shift();
			if (line[0] === "#") continue;
			dimensions = line.split(" ");
			break;
		}
		if (dimensions.length === 2) return {
			height: Number.parseInt(dimensions[1], 10),
			width: Number.parseInt(dimensions[0], 10)
		};
		throw new TypeError("Invalid PNM");
	},
	pam: (lines) => {
		const size = {};
		while (lines.length > 0) {
			const line = lines.shift();
			if (line.length > 16 || line.charCodeAt(0) > 128) continue;
			const [key, value] = line.split(" ");
			if (key && value) size[key.toLowerCase()] = Number.parseInt(value, 10);
			if (size.height && size.width) break;
		}
		if (size.height && size.width) return {
			height: size.height,
			width: size.width
		};
		throw new TypeError("Invalid PAM");
	}
};
var PNM = {
	validate: (input) => toUTF8String(input, 0, 2) in PNMTypes,
	calculate(input) {
		const type = PNMTypes[toUTF8String(input, 0, 2)];
		const lines = toUTF8String(input, 3).split(/[\r\n]+/);
		return (handlers$1[type] || handlers$1.default)(lines);
	}
};
//#endregion
//#region src/common/image-size/lib/types/psd.ts
var PSD = {
	validate: (input) => toUTF8String(input, 0, 4) === "8BPS",
	calculate: (input) => ({
		height: readUInt32BE(input, 14),
		width: readUInt32BE(input, 18)
	})
};
//#endregion
//#region src/common/image-size/lib/types/svg.ts
var svgReg = /<svg\s([^>"']|"[^"]*"|'[^']*')*>/;
var extractorRegExps = {
	height: /\sheight=(['"])([^%]+?)\1/,
	root: svgReg,
	viewbox: /\sviewBox=(['"])(.+?)\1/i,
	width: /\swidth=(['"])([^%]+?)\1/
};
var INCH_CM = 2.54;
var units = {
	in: 96,
	cm: 96 / INCH_CM,
	em: 16,
	ex: 8,
	m: 96 / INCH_CM * 100,
	mm: 96 / INCH_CM / 10,
	pc: 96 / 72 / 12,
	pt: 96 / 72,
	px: 1
};
var unitsReg = new RegExp(`^([0-9.]+(?:e\\d+)?)(${Object.keys(units).join("|")})?$`);
function parseLength(len) {
	const m = unitsReg.exec(len);
	if (!m) return;
	return Math.round(Number(m[1]) * (units[m[2]] || 1));
}
function parseViewbox(viewbox) {
	const bounds = viewbox.split(" ");
	return {
		height: parseLength(bounds[3]),
		width: parseLength(bounds[2])
	};
}
function parseAttributes(root) {
	const width = root.match(extractorRegExps.width);
	const height = root.match(extractorRegExps.height);
	const viewbox = root.match(extractorRegExps.viewbox);
	return {
		height: height && parseLength(height[2]),
		viewbox: viewbox && parseViewbox(viewbox[2]),
		width: width && parseLength(width[2])
	};
}
function calculateByDimensions(attrs) {
	return {
		height: attrs.height,
		width: attrs.width
	};
}
function calculateByViewbox(attrs, viewbox) {
	const ratio = viewbox.width / viewbox.height;
	if (attrs.width) return {
		height: Math.floor(attrs.width / ratio),
		width: attrs.width
	};
	if (attrs.height) return {
		height: attrs.height,
		width: Math.floor(attrs.height * ratio)
	};
	return {
		height: viewbox.height,
		width: viewbox.width
	};
}
var SVG = {
	validate: (input) => svgReg.test(toUTF8String(input, 0, 1e3)),
	calculate(input) {
		const root = toUTF8String(input).match(extractorRegExps.root);
		if (root) {
			const attrs = parseAttributes(root[0]);
			if (attrs.width && attrs.height) return calculateByDimensions(attrs);
			if (attrs.viewbox) return calculateByViewbox(attrs, attrs.viewbox);
		}
		throw new TypeError("Invalid SVG");
	}
};
//#endregion
//#region src/common/image-size/lib/types/tga.ts
var TGA = {
	validate(input) {
		return readUInt16LE(input, 0) === 0 && readUInt16LE(input, 4) === 0;
	},
	calculate(input) {
		return {
			height: readUInt16LE(input, 14),
			width: readUInt16LE(input, 12)
		};
	}
};
//#endregion
//#region src/common/image-size/lib/types/tiff.ts
var CONSTANTS = {
	TAG: {
		WIDTH: 256,
		HEIGHT: 257,
		COMPRESSION: 259
	},
	TYPE: {
		SHORT: 3,
		LONG: 4,
		LONG8: 16
	},
	ENTRY_SIZE: {
		STANDARD: 12,
		BIG: 20
	},
	COUNT_SIZE: {
		STANDARD: 2,
		BIG: 8
	}
};
function readIFD(input, { isBigEndian, isBigTiff }) {
	const ifdOffset = isBigTiff ? Number(readUInt64(input, 8, isBigEndian)) : readUInt(input, 32, 4, isBigEndian);
	const entryCountSize = isBigTiff ? CONSTANTS.COUNT_SIZE.BIG : CONSTANTS.COUNT_SIZE.STANDARD;
	return input.slice(ifdOffset + entryCountSize);
}
function readTagValue(input, type, offset, isBigEndian) {
	switch (type) {
		case CONSTANTS.TYPE.SHORT: return readUInt(input, 16, offset, isBigEndian);
		case CONSTANTS.TYPE.LONG: return readUInt(input, 32, offset, isBigEndian);
		case CONSTANTS.TYPE.LONG8: {
			const value = Number(readUInt64(input, offset, isBigEndian));
			if (value > Number.MAX_SAFE_INTEGER) throw new TypeError("Value too large");
			return value;
		}
		default: return 0;
	}
}
function nextTag(input, isBigTiff) {
	const entrySize = isBigTiff ? CONSTANTS.ENTRY_SIZE.BIG : CONSTANTS.ENTRY_SIZE.STANDARD;
	if (input.length > entrySize) return input.slice(entrySize);
}
function extractTags(input, { isBigEndian, isBigTiff }) {
	const tags = {};
	let temp = input;
	while (temp?.length) {
		const code = readUInt(temp, 16, 0, isBigEndian);
		const type = readUInt(temp, 16, 2, isBigEndian);
		const length = isBigTiff ? Number(readUInt64(temp, 4, isBigEndian)) : readUInt(temp, 32, 4, isBigEndian);
		if (code === 0) break;
		if (length === 1 && (type === CONSTANTS.TYPE.SHORT || type === CONSTANTS.TYPE.LONG || isBigTiff && type === CONSTANTS.TYPE.LONG8)) tags[code] = readTagValue(temp, type, isBigTiff ? 12 : 8, isBigEndian);
		temp = nextTag(temp, isBigTiff);
	}
	return tags;
}
function determineFormat(input) {
	const signature = toUTF8String(input, 0, 2);
	const version = readUInt(input, 16, 2, signature === "MM");
	return {
		isBigEndian: signature === "MM",
		isBigTiff: version === 43
	};
}
function validateBigTIFFHeader(input, isBigEndian) {
	const byteSize = readUInt(input, 16, 4, isBigEndian);
	const reserved = readUInt(input, 16, 6, isBigEndian);
	if (byteSize !== 8 || reserved !== 0) throw new TypeError("Invalid BigTIFF header");
}
var signatures = /* @__PURE__ */ new Set([
	"49492a00",
	"4d4d002a",
	"49492b00",
	"4d4d002b"
]);
var TIFF = {
	validate: (input) => {
		const signature = toHexString(input, 0, 4);
		return signatures.has(signature);
	},
	calculate(input) {
		const format = determineFormat(input);
		if (format.isBigTiff) validateBigTIFFHeader(input, format.isBigEndian);
		const tags = extractTags(readIFD(input, format), format);
		const info = {
			height: tags[CONSTANTS.TAG.HEIGHT],
			width: tags[CONSTANTS.TAG.WIDTH],
			type: format.isBigTiff ? "bigtiff" : "tiff"
		};
		if (tags[CONSTANTS.TAG.COMPRESSION]) info.compression = tags[CONSTANTS.TAG.COMPRESSION];
		if (!info.width || !info.height) throw new TypeError("Invalid Tiff. Missing tags");
		return info;
	}
};
//#endregion
//#region src/common/image-size/lib/types/webp.ts
function calculateExtended(input) {
	return {
		height: 1 + readUInt24LE(input, 7),
		width: 1 + readUInt24LE(input, 4)
	};
}
function calculateLossless(input) {
	return {
		height: 1 + ((input[4] & 15) << 10 | input[3] << 2 | (input[2] & 192) >> 6),
		width: 1 + ((input[2] & 63) << 8 | input[1])
	};
}
function calculateLossy(input) {
	return {
		height: readInt16LE(input, 8) & 16383,
		width: readInt16LE(input, 6) & 16383
	};
}
//#endregion
//#region src/common/image-size/lib/types/index.ts
var typeHandlers = /* @__PURE__ */ new Map([
	["bmp", BMP],
	["cur", CUR],
	["dds", DDS],
	["gif", GIF],
	["heif", HEIF],
	["icns", ICNS],
	["ico", ICO],
	["j2c", J2C],
	["jp2", JP2],
	["jpg", JPG],
	["jxl", JXL],
	["jxl-stream", JXLStream],
	["ktx", KTX],
	["png", PNG],
	["pnm", PNM],
	["psd", PSD],
	["svg", SVG],
	["tga", TGA],
	["tiff", TIFF],
	["webp", {
		validate(input) {
			const riffHeader = "RIFF" === toUTF8String(input, 0, 4);
			const webpHeader = "WEBP" === toUTF8String(input, 8, 12);
			const vp8Header = "VP8" === toUTF8String(input, 12, 15);
			return riffHeader && webpHeader && vp8Header;
		},
		calculate(_input) {
			const chunkHeader = toUTF8String(_input, 12, 16);
			const input = _input.slice(20, 30);
			if (chunkHeader === "VP8X") {
				const extendedHeader = input[0];
				const validStart = (extendedHeader & 192) === 0;
				const validEnd = (extendedHeader & 1) === 0;
				if (validStart && validEnd) return calculateExtended(input);
				throw new TypeError("Invalid WebP");
			}
			if (chunkHeader === "VP8 " && input[0] !== 47) return calculateLossy(input);
			const signature = toHexString(input, 3, 6);
			if (chunkHeader === "VP8L" && signature !== "9d012a") return calculateLossless(input);
			throw new TypeError("Invalid WebP");
		}
	}]
]);
var types = Array.from(typeHandlers.keys());
//#endregion
//#region src/common/image-size/lib/detector.ts
var firstBytes = /* @__PURE__ */ new Map([
	[0, "heif"],
	[56, "psd"],
	[66, "bmp"],
	[68, "dds"],
	[71, "gif"],
	[73, "tiff"],
	[77, "tiff"],
	[82, "webp"],
	[105, "icns"],
	[137, "png"],
	[255, "jpg"]
]);
function detector(input) {
	const byte = input[0];
	const type = firstBytes.get(byte);
	if (type && typeHandlers.get(type).validate(input)) return type;
	return types.find((type) => typeHandlers.get(type).validate(input));
}
//#endregion
//#region src/common/image-size/lib/lookup.ts
var globalOptions = { disabledTypes: [] };
/**
* Return size information based on an Uint8Array
*
* @param {Uint8Array} input
* @returns {ISizeCalculationResult}
*/
function imageSize(input) {
	const type = detector(input);
	if (typeof type !== "undefined") {
		if (globalOptions.disabledTypes.indexOf(type) > -1) throw new TypeError(`disabled file type: ${type}`);
		const size = typeHandlers.get(type).calculate(input);
		if (size !== void 0) {
			size.type = size.type ?? type;
			if (size.images && size.images.length > 1) {
				const largestImage = size.images.reduce((largest, current) => {
					return current.width * current.height > largest.width * largest.height ? current : largest;
				}, size.images[0]);
				size.width = largestImage.width;
				size.height = largestImage.height;
			}
			return size;
		}
	}
	throw new TypeError(`unsupported file type: ${type}`);
}
//#endregion
//#region src/common/image-size/lib/fromFile.ts
var MaxInputSize = 1048576;
var queue = [];
var concurrency = 100;
var processQueue = async () => {
	const promises = queue.splice(0, concurrency).map(async ({ filePath, resolve, reject }) => {
		let handle;
		try {
			handle = await fs$6.promises.open(path$4.resolve(filePath), "r");
		} catch (err) {
			return reject(err);
		}
		try {
			const { size } = await handle.stat();
			if (size <= 0) throw new Error("Empty file");
			const inputSize = Math.min(size, MaxInputSize);
			const input = new Uint8Array(inputSize);
			await handle.read(input, 0, inputSize, 0);
			resolve(imageSize(input));
		} catch (err) {
			reject(err);
		} finally {
			await handle.close();
		}
	});
	await Promise.allSettled(promises);
	if (queue.length) setTimeout(processQueue, 100);
};
/**
* @param {string} filePath - relative/absolute path of the image file
*/
var imageSizeFromFile = async (filePath) => new Promise((resolve, reject) => {
	queue.push({
		filePath,
		resolve,
		reject
	});
	processQueue();
});
//#endregion
//#region src/common/utils/file.ts
function checkUriType(uri) {
	if (uri.startsWith("base64://")) return { type: 3 };
	if (uri.startsWith("data:")) return { type: 4 };
	if (uri.startsWith("http://") || uri.startsWith("https://")) return { type: 2 };
	if (uri.startsWith("file://")) return { type: 1 };
	if (fs.existsSync(uri)) return { type: 5 };
	return { type: 0 };
}
async function fetchFile(url, headersInit) {
	const headers = new Headers({
		"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36",
		"Host": new URL(url).hostname,
		...headersInit
	});
	let raw = await fetch(url, { headers }).catch((err) => {
		if (err.cause) throw err.cause;
		throw err;
	});
	if (raw.status === 403 && !headers.has("Referer")) {
		headers.set("Referer", url);
		raw = await fetch(url, { headers }).catch((err) => {
			if (err.cause) throw err.cause;
			throw err;
		});
	}
	if (!raw.ok) throw new Error(`statusText: ${raw.statusText}`);
	return {
		data: Buffer.from(await raw.arrayBuffer()),
		url: raw.url
	};
}
async function uri2local(ctx, uri, needExt) {
	const { type } = checkUriType(uri);
	if (type === 1) {
		const filePath = fileURLToPath(uri);
		if (!fs.existsSync(filePath)) return {
			success: false,
			errMsg: "路径不存在",
			fileName: "",
			path: "",
			isLocal: false
		};
		return {
			success: true,
			errMsg: "",
			fileName: path.basename(filePath),
			path: filePath,
			isLocal: true
		};
	}
	if (type === 5) return {
		success: true,
		errMsg: "",
		fileName: path.basename(uri),
		path: uri,
		isLocal: true
	};
	if (type === 2) try {
		const res = await fetchFile(uri);
		let fileName = randomUUID();
		let filePath = path.join(TEMP_DIR, fileName);
		await fsPromise.writeFile(filePath, res.data);
		if (needExt) {
			const ext = (await getFileType(filePath)).ext;
			fileName += `.${ext}`;
			const newPath = `${filePath}.${ext}`;
			await fsPromise.rename(filePath, newPath);
			filePath = newPath;
		}
		return {
			success: true,
			errMsg: "",
			fileName,
			path: filePath,
			isLocal: false
		};
	} catch (e) {
		return {
			success: false,
			errMsg: `${uri} 下载失败, ${e.message}`,
			fileName: "",
			path: "",
			isLocal: false
		};
	}
	if (type === 3) {
		let filename = randomUUID();
		let filePath = path.join(TEMP_DIR, filename);
		const base64 = uri.replace(/^base64:\/\//, "");
		await fsPromise.writeFile(filePath, base64, "base64");
		if (needExt) {
			const ext = (await getFileType(filePath)).ext;
			filename += `.${ext}`;
			await fsPromise.rename(filePath, `${filePath}.${ext}`);
			filePath = `${filePath}.${ext}`;
		}
		return {
			success: true,
			errMsg: "",
			fileName: filename,
			path: filePath,
			isLocal: false
		};
	}
	if (type === 4) {
		const capture = /^data:([\w/.+-]+);base64,(.*)$/.exec(uri);
		if (capture) {
			let filename = randomUUID();
			const [, _type, base64] = capture;
			let filePath = path.join(TEMP_DIR, filename);
			await fsPromise.writeFile(filePath, base64, "base64");
			if (needExt) {
				const ext = (await getFileType(filePath)).ext;
				filename += `.${ext}`;
				await fsPromise.rename(filePath, `${filePath}.${ext}`);
				filePath = `${filePath}.${ext}`;
			}
			return {
				success: true,
				errMsg: "",
				fileName: filename,
				path: filePath,
				isLocal: false
			};
		}
	}
	if (type === 0) {
		let fileCache = await ctx.store.getFileCacheById(uri);
		if (!fileCache?.length) fileCache = await ctx.store.getFileCacheByName(uri);
		if (fileCache?.length) {
			const isGroup = fileCache[0].chatType === ChatType.Group;
			let url;
			if (fileCache[0].elementType === ElementType.Pic) url = await ctx.ntFileApi.getImageUrl(fileCache[0].originImageUrl, fileCache[0].md5HexStr);
			else if (fileCache[0].elementType === ElementType.Video) url = await ctx.ntFileApi.getVideoUrl(fileCache[0].fileUuid, isGroup);
			else if (fileCache[0].elementType === ElementType.Ptt) url = await ctx.ntFileApi.getPttUrl(fileCache[0].fileUuid, isGroup);
			else if (fileCache[0].elementType === ElementType.File) url = (await ctx.ntFileApi.getFileUrl(fileCache[0].fileUuid, isGroup, isGroup ? +fileCache[0].peerUid : void 0)).url;
			if (url) return await uri2local(ctx, url, needExt);
			else return {
				success: false,
				errMsg: `不支持的文件类型: ${fileCache[0].elementType}`,
				fileName: "",
				path: "",
				isLocal: false
			};
		}
	}
	return {
		success: false,
		errMsg: `未知文件类型或路径不存在: ${uri}`,
		fileName: "",
		path: "",
		isLocal: false
	};
}
async function getFileType(filePath) {
	try {
		const type = await fileType.fileTypeFromFile(filePath);
		if (!type) return {
			mime: "application/octet-stream",
			ext: path.extname(filePath).slice(0) || ""
		};
		return {
			mime: type.mime,
			ext: type.ext
		};
	} catch (error) {
		getLogger("file-util").error("Error detecting file type:", error);
		return {
			mime: "",
			ext: ""
		};
	}
}
async function getImageSize(path) {
	return await imageSizeFromFile(path);
}
function getMd5HexFromBuffer(buf) {
	return createHash("md5").update(buf).digest("hex");
}
function getSha1HexFromBuffer(buf) {
	return createHash("sha1").update(buf).digest("hex");
}
async function getMd5HexFromFile(filePath) {
	const hash = createHash("md5");
	const stream = fs.createReadStream(filePath);
	for await (const chunk of stream) hash.update(chunk);
	return hash.digest("hex");
}
async function getSha1HexFromFile(filePath) {
	const hash = createHash("sha1");
	const stream = fs.createReadStream(filePath);
	for await (const chunk of stream) hash.update(chunk);
	return hash.digest("hex");
}
function getMd5BufferFromBuffer(buf) {
	return createHash("md5").update(buf).digest();
}
async function getMd5BufferFromFile(filePath) {
	const hash = createHash("md5");
	const stream = fs.createReadStream(filePath);
	for await (const chunk of stream) hash.update(chunk);
	return hash.digest();
}
async function getSha1BufferFromFile(filePath) {
	const hash = createHash("sha1");
	const stream = fs.createReadStream(filePath);
	for await (const chunk of stream) hash.update(chunk);
	return hash.digest();
}
var Sha1Stream = class Sha1Stream {
	static padding = new Uint8Array([
		128,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0,
		0
	]);
	_state;
	_count;
	_buffer;
	_w;
	constructor() {
		this._state = /* @__PURE__ */ new Uint32Array(5);
		this._count = /* @__PURE__ */ new Uint32Array(2);
		this._buffer = /* @__PURE__ */ new Uint8Array(64);
		this._w = /* @__PURE__ */ new Uint32Array(80);
		this.reset();
	}
	reset() {
		this._state[0] = 1732584193;
		this._state[1] = 4023233417;
		this._state[2] = 2562383102;
		this._state[3] = 271733878;
		this._state[4] = 3285377520;
		this._count[0] = 0;
		this._count[1] = 0;
	}
	transform(chunk) {
		const w = this._w;
		for (let i = 0; i < 16; i++) {
			const j = i * 4;
			w[i] = chunk[j] << 24 | chunk[j + 1] << 16 | chunk[j + 2] << 8 | chunk[j + 3];
		}
		for (let i = 16; i < 80; i++) {
			const v = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
			w[i] = v << 1 | v >>> 31;
		}
		let a = this._state[0];
		let b = this._state[1];
		let c = this._state[2];
		let d = this._state[3];
		let e = this._state[4];
		const K1 = 1518500249;
		const K2 = 1859775393;
		const K3 = 2400959708;
		const K4 = 3395469782;
		for (let i = 0; i < 20; i++) {
			const t = (a << 5 | a >>> 27) + (b & c | ~b & d) + e + w[i] + K1 >>> 0;
			e = d;
			d = c;
			c = b << 30 | b >>> 2;
			b = a;
			a = t;
		}
		for (let i = 20; i < 40; i++) {
			const t = (a << 5 | a >>> 27) + (b ^ c ^ d) + e + w[i] + K2 >>> 0;
			e = d;
			d = c;
			c = b << 30 | b >>> 2;
			b = a;
			a = t;
		}
		for (let i = 40; i < 60; i++) {
			const t = (a << 5 | a >>> 27) + (b & c | b & d | c & d) + e + w[i] + K3 >>> 0;
			e = d;
			d = c;
			c = b << 30 | b >>> 2;
			b = a;
			a = t;
		}
		for (let i = 60; i < 80; i++) {
			const t = (a << 5 | a >>> 27) + (b ^ c ^ d) + e + w[i] + K4 >>> 0;
			e = d;
			d = c;
			c = b << 30 | b >>> 2;
			b = a;
			a = t;
		}
		this._state[0] = this._state[0] + a >>> 0;
		this._state[1] = this._state[1] + b >>> 0;
		this._state[2] = this._state[2] + c >>> 0;
		this._state[3] = this._state[3] + d >>> 0;
		this._state[4] = this._state[4] + e >>> 0;
	}
	update(data) {
		if (!(data instanceof Uint8Array)) data = new Uint8Array(data);
		const len = data.length;
		let index = this._count[0] >>> 3 & 63;
		this._count[0] += len << 3;
		if (this._count[0] < len << 3) this._count[1]++;
		this._count[1] += len >>> 29;
		const partLen = 64 - index;
		let i = 0;
		if (len >= partLen) {
			this._buffer.set(data.subarray(0, partLen), index);
			this.transform(this._buffer);
			for (i = partLen; i + 63 < len; i += 64) this.transform(data.subarray(i, i + 64));
			index = 0;
		}
		this._buffer.set(data.subarray(i), index);
	}
	hash(bigEnding = true) {
		const out = /* @__PURE__ */ new Uint8Array(20);
		const st = this._state;
		if (bigEnding) {
			out[0] = st[0] >>> 24;
			out[1] = st[0] >>> 16 & 255;
			out[2] = st[0] >>> 8 & 255;
			out[3] = st[0] & 255;
			out[4] = st[1] >>> 24;
			out[5] = st[1] >>> 16 & 255;
			out[6] = st[1] >>> 8 & 255;
			out[7] = st[1] & 255;
			out[8] = st[2] >>> 24;
			out[9] = st[2] >>> 16 & 255;
			out[10] = st[2] >>> 8 & 255;
			out[11] = st[2] & 255;
			out[12] = st[3] >>> 24;
			out[13] = st[3] >>> 16 & 255;
			out[14] = st[3] >>> 8 & 255;
			out[15] = st[3] & 255;
			out[16] = st[4] >>> 24;
			out[17] = st[4] >>> 16 & 255;
			out[18] = st[4] >>> 8 & 255;
			out[19] = st[4] & 255;
		} else {
			out[0] = st[0] & 255;
			out[1] = st[0] >>> 8 & 255;
			out[2] = st[0] >>> 16 & 255;
			out[3] = st[0] >>> 24;
			out[4] = st[1] & 255;
			out[5] = st[1] >>> 8 & 255;
			out[6] = st[1] >>> 16 & 255;
			out[7] = st[1] >>> 24;
			out[8] = st[2] & 255;
			out[9] = st[2] >>> 8 & 255;
			out[10] = st[2] >>> 16 & 255;
			out[11] = st[2] >>> 24;
			out[12] = st[3] & 255;
			out[13] = st[3] >>> 8 & 255;
			out[14] = st[3] >>> 16 & 255;
			out[15] = st[3] >>> 24;
			out[16] = st[4] & 255;
			out[17] = st[4] >>> 8 & 255;
			out[18] = st[4] >>> 16 & 255;
			out[19] = st[4] >>> 24;
		}
		return out;
	}
	final() {
		const digest = /* @__PURE__ */ new Uint8Array(20);
		const bits = /* @__PURE__ */ new Uint8Array(8);
		for (let i = 0; i < 8; i++) {
			const byteIndex = i >= 4 ? 0 : 1;
			const shift = (3 - (i & 3)) * 8;
			bits[i] = this._count[byteIndex] >>> shift & 255;
		}
		const index = this._count[0] >>> 3 & 63;
		const padLen = index < 56 ? 56 - index : 120 - index;
		this.update(Sha1Stream.padding.subarray(0, padLen));
		this.update(bits);
		for (let i = 0; i < 20; i++) {
			const word = this._state[i >> 2];
			const shift = (3 - (i & 3)) * 8;
			digest[i] = word >>> shift & 255;
		}
		return digest;
	}
};
async function calculateSha1StreamBytes(filePath) {
	const sha1 = new Sha1Stream();
	const blockSize = 1048576;
	let tail = Buffer.alloc(0);
	let bytesRead = 0;
	let nextBlockBoundary = blockSize;
	const byteArrayList = [];
	const readable = fs.createReadStream(filePath);
	for await (const chunk of readable) {
		let buf;
		if (tail.length > 0) {
			buf = Buffer.concat([tail, chunk]);
			tail = Buffer.alloc(0);
		} else buf = chunk;
		let offset = 0;
		while (buf.length - offset >= 64) {
			sha1.update(buf.subarray(offset, offset + 64));
			offset += 64;
			bytesRead += 64;
			if (bytesRead >= nextBlockBoundary) {
				byteArrayList.push(Buffer.from(sha1.hash(false)));
				nextBlockBoundary += blockSize;
			}
		}
		tail = buf.subarray(offset);
	}
	if (tail.length > 0) sha1.update(tail);
	byteArrayList.push(Buffer.from(sha1.final()));
	return byteArrayList;
}
async function readAndHash10M(filePath) {
	const maxSize = 10002432;
	const fd = await fsPromise.open(filePath, "r");
	const buffer = Buffer.allocUnsafe(maxSize);
	const { bytesRead } = await fd.read(buffer, 0, maxSize, 0);
	await fd.close();
	return getMd5BufferFromBuffer(buffer.subarray(0, bytesRead));
}
var TriSha1 = class {
	hasher = createHash("sha1");
	offset = 0;
	fileSize;
	ranges;
	constructor(fileSize) {
		this.fileSize = fileSize;
		if (fileSize < 31457280) this.ranges = [[0, fileSize]];
		else this.ranges = [
			[0, 10485759],
			[(fileSize >> 1) - 5242880, (fileSize >> 1) + 5242880 - 1],
			[fileSize - 10485760, fileSize - 1]
		];
	}
	update(data) {
		const start = this.offset;
		const end = start + data.length;
		for (const [rs, re] of this.ranges) {
			const from = Math.max(start, rs);
			const to = Math.min(end, re + 1);
			if (from < to) {
				const slice = data.subarray(from - start, to - start);
				this.hasher.update(slice);
			}
		}
		this.offset = end;
	}
	finalize() {
		const sizeBytes = Buffer.allocUnsafe(8);
		sizeBytes.writeBigUInt64LE(BigInt(this.fileSize));
		this.hasher.update(sizeBytes);
		return this.hasher.digest();
	}
};
async function calculateTriSha1(filePath, fileSize) {
	const hash = new TriSha1(fileSize);
	const stream = fs.createReadStream(filePath);
	for await (const chunk of stream) hash.update(chunk);
	return hash.finalize();
}
//#endregion
//#region src/common/utils/misc.ts
function isNumeric(str) {
	return /^\d+$/.test(str);
}
/** 在保证老对象已有的属性不变化的情况下将新对象的属性复制到老对象 */
function mergeNewProperties(newObj, oldObj) {
	Object.keys(newObj).forEach((key) => {
		if (!oldObj.hasOwnProperty(key)) oldObj[key] = newObj[key];
		else if (typeof oldObj[key] === "object" && typeof newObj[key] === "object") mergeNewProperties(newObj[key], oldObj[key]);
		else if (typeof oldObj[key] === "object" || typeof newObj[key] === "object") oldObj[key] = newObj[key];
	});
}
function filterNullable(array) {
	return array.filter((e) => isNonNullable(e));
}
function parseBool(value) {
	if ([
		"",
		"true",
		"1"
	].includes(value)) return true;
	return false;
}
var cloneObj = (obj) => Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
function uint32ToIPV4Addr(value) {
	return [
		value & 255,
		value >> 8 & 255,
		value >> 16 & 255,
		value >> 24 & 255
	].join(".");
}
function sleep(ms = 0) {
	return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* 并发有界地执行异步任务，保持输出顺序与输入一致。
* @param items 输入数组
* @param concurrency 最大并发数
* @param fn 处理函数（按输入顺序返回位置对应的结果）
* @param shouldStop 可选中止判定：返回 true 时停止派发新任务（已 in-flight 的任务会自然完成，
*                   未启动的位置在结果数组中保持 undefined）。
*/
async function mapWithConcurrency(items, concurrency, fn, shouldStop) {
	const results = new Array(items.length);
	if (items.length === 0) return results;
	const limit = Math.max(1, Math.min(concurrency, items.length));
	let cursor = 0;
	let stopped = false;
	async function worker() {
		while (!stopped && cursor < items.length) {
			const i = cursor++;
			const r = await fn(items[i], i);
			results[i] = r;
			if (shouldStop?.(r, i)) {
				stopped = true;
				break;
			}
		}
	}
	await Promise.all(Array.from({ length: limit }, () => worker()));
	return results;
}
function isHttpUrl(str) {
	return /^https?:\/\/.+/.test(str);
}
function formatYYYYMMDD(date = /* @__PURE__ */ new Date()) {
	return date.toISOString().slice(0, 10).replace(/-/g, "");
}
/**
* 将数组中指定 index 的元素移动到另一个 index 位置
* @param arr 目标数组 (原地修改)
* @param from 源元素 index
* @param to 目标 index
* @returns 修改后的原数组
*/
function moveElement(arr, from, to) {
	if (arr.length === 0) return arr;
	if (from === to) return arr;
	const [item] = arr.splice(from, 1);
	arr.splice(to, 0, item);
	return arr;
}
//#endregion
//#region src/common/utils/group.ts
/**
* 把"用户看到的群号"（group_code）转成 QQ 内部的 group_uin。
* 部分 highway/老协议字段（比如 GroupAvatarExtra.groupUin）要的是 group_uin，
* 错传 group_code 服务器会拒。映射表是 QQ 协议固有的。
*/
function groupCodeToGroupUin(groupCode) {
	let left = Math.floor(groupCode / 1e6);
	if (left >= 0 && left <= 10) left += 202;
	else if (left >= 11 && left <= 19) left += 469;
	else if (left >= 20 && left <= 66) left += 2080;
	else if (left >= 67 && left <= 156) left += 1943;
	else if (left >= 157 && left <= 209) left += 1990;
	else if (left >= 210 && left <= 309) left += 3890;
	else if (left >= 310 && left <= 499) left += 3490;
	return left * 1e6 + groupCode % 1e6;
}
var defaultVideoThumb = Buffer.from(" ", "base64");
async function getVideoInfo(filePath) {
	const size = fs.statSync(filePath).size;
	return new Promise((resolve, reject) => {
		(0, import_fluent_ffmpeg.default)(filePath).ffprobe((err, metadata) => {
			if (err) reject(err);
			else {
				const videoStream = metadata.streams.find((s) => s.codec_type === "video");
				resolve({
					width: videoStream?.width,
					height: videoStream?.height,
					time: +videoStream?.duration,
					format: metadata.format.format_name,
					size,
					filePath
				});
			}
		});
	});
}
function createThumb(ctx, videoFilePath) {
	return new Promise((resolve, reject) => {
		const thumbFileName = `${randomUUID()}.png`;
		const thumbPath = path.join(TEMP_DIR, thumbFileName);
		ctx.logger.info("开始生成视频缩略图", videoFilePath);
		let completed = false;
		function useDefaultThumb() {
			if (completed) return;
			completed = true;
			ctx.logger.info("获取视频封面失败，使用默认封面");
			writeFile(thumbPath, defaultVideoThumb).then(() => resolve(thumbPath)).catch((err) => reject(err));
		}
		const timeout = setTimeout(useDefaultThumb, 5e3);
		try {
			const cmd = (0, import_fluent_ffmpeg.default)(videoFilePath);
			cmd.on("error", (err) => {
				clearTimeout(timeout);
				ctx.logger.warn("FFmpeg 生成缩略图失败:", err?.message || err);
				useDefaultThumb();
			});
			cmd.on("end", () => {
				if (completed) return;
				completed = true;
				clearTimeout(timeout);
				resolve(thumbPath);
			});
			cmd.screenshots({
				timestamps: [0],
				filename: thumbFileName,
				folder: TEMP_DIR
			});
		} catch (e) {
			clearTimeout(timeout);
			ctx.logger.warn("FFmpeg 调用异常:", e);
			useDefaultThumb();
		}
	});
}
//#endregion
//#region src/common/utils/audio.ts
function convert(ctx, input, options, outputPath) {
	return new Promise((resolve, reject) => {
		const chunks = [];
		let command = (0, import_fluent_ffmpeg.default)(input).on("error", (err) => {
			ctx.logger.error(`FFmpeg处理转换出错: `, err.message);
			reject(err);
		}).on("end", () => {
			if (!outputPath) resolve(Buffer.concat(chunks));
			else resolve(outputPath);
		});
		if (options.input) command = command.inputOptions(options.input);
		if (options.output) command = command.outputOptions(options.output);
		if (!outputPath) command.pipe().on("data", (chunk) => {
			chunks.push(chunk);
		});
		else command.save(outputPath);
	});
}
async function encodeSilk(ctx, filePath) {
	const file = await fsPromise.readFile(filePath);
	if (!isSilk(file)) {
		ctx.logger.info(`语音文件${filePath}需要转换成silk`);
		let result;
		if (isWav(file) && [
			8e3,
			12e3,
			16e3,
			24e3,
			32e3,
			44100,
			48e3
		].includes(getWavFileInfo(file).fmt.sampleRate)) result = await encode(file, 0);
		else {
			const input = await convert(ctx, filePath, { output: [
				"-ar 24000",
				"-ac 1",
				"-f s16le"
			] });
			result = await encode(input, 24e3);
		}
		const pttPath = path.join(TEMP_DIR, randomUUID());
		await fsPromise.writeFile(pttPath, result.data);
		ctx.logger.info(`语音文件${filePath}转换成功!`, pttPath, `时长:`, result.duration);
		return {
			converted: true,
			path: pttPath,
			duration: result.duration / 1e3
		};
	} else {
		const silk = file;
		let duration = 1;
		try {
			duration = getDuration(silk) / 1e3;
		} catch (e) {
			ctx.logger.warn("获取语音文件时长失败, 默认为1秒", filePath, e.stack);
		}
		return {
			converted: false,
			path: filePath,
			duration
		};
	}
}
async function decodeSilk(ctx, inputFilePath, outFormat) {
	const silk = await fsPromise.readFile(inputFilePath);
	const { data } = await decode(silk, 24e3);
	const tmpPath = path.join(TEMP_DIR, path.basename(inputFilePath));
	const outFilePath = tmpPath + `.${outFormat}`;
	const pcmFilePath = tmpPath + ".pcm";
	await fsPromise.writeFile(pcmFilePath, data);
	return convert(ctx, pcmFilePath, { input: [
		"-f s16le",
		"-ar 24000",
		"-ac 1"
	] }, outFilePath);
}
//#endregion
//#region src/ntqqapi/helper/messageParsing.ts
function parseElements(elems, isGroup) {
	let result = [];
	let skipIndex;
	for (const [index, elem] of elems.entries()) {
		if (index === skipIndex) continue;
		if (elem.text) {
			const textElem = elem.text;
			const isAt = textElem.attr6Buf && textElem.attr6Buf.length > 0;
			let atTargetUin = 0;
			if (isAt && textElem.attr6Buf.length >= 11 && textElem.attr6Buf[6] !== 1) {
				if (elem.text.pbReserve) {
					const attr = Msg.TextResvAttr.decode(elem.text.pbReserve);
					if (attr.atType === 2 && attr.atMemberUin === 0) {
						skipIndex = index + 1;
						continue;
					}
				}
				atTargetUin = textElem.attr6Buf.readUInt32BE(7);
			}
			result.push({
				elementType: ElementType.Text,
				textElement: {
					content: textElem.str,
					atType: isAt ? textElem.attr6Buf[6] === 1 ? 1 : 2 : 0,
					atUin: atTargetUin
				}
			});
			continue;
		}
		if (elem.face) {
			const faceIndex = elem.face.index;
			const face = face_config_default.sysface.find((face) => face.QSid === faceIndex.toString());
			result.push({
				elementType: ElementType.Face,
				faceElement: {
					faceIndex,
					faceType: 1,
					faceText: face?.QDes ?? ""
				}
			});
			continue;
		}
		if (elem.notOnlineImage) {
			const img = elem.notOnlineImage;
			result.push({
				elementType: ElementType.Pic,
				picElement: {
					fileName: img.filePath,
					fileSize: img.fileLen,
					picWidth: img.picWidth,
					picHeight: img.picHeight,
					md5HexStr: img.picMd5.toString("hex"),
					sourcePath: "",
					picType: img.imgType,
					picSubType: img.bizType,
					fileUuid: img.resId.split("-")[1],
					originImageUrl: img.origUrl,
					summary: ""
				}
			});
			continue;
		}
		if (elem.customFace) {
			const cf = elem.customFace;
			result.push({
				elementType: ElementType.Pic,
				picElement: {
					fileName: cf.filePath,
					fileSize: cf.size,
					picWidth: cf.width,
					picHeight: cf.height,
					md5HexStr: cf.md5.toString("hex"),
					sourcePath: "",
					picSubType: cf.bizType,
					fileUuid: cf.fileId.toString(),
					originImageUrl: cf.origUrl,
					picType: cf.imageType,
					summary: ""
				}
			});
			continue;
		}
		if (elem.marketFace) {
			const mf = elem.marketFace;
			result.push({
				elementType: ElementType.MarketFace,
				marketFaceElement: {
					emojiPackageId: mf.tabId ?? 0,
					imageWidth: mf.width ?? 0,
					imageHeight: mf.height ?? 0,
					faceName: mf.summary ?? "",
					emojiId: mf.faceId ? Buffer.from(mf.faceId).toString("hex") : "",
					key: mf.key ?? ""
				}
			});
			break;
		}
		if (elem.richMsg) {
			const isForward = elem.richMsg.serviceId === 35;
			let template = "";
			try {
				const buf = elem.richMsg.template;
				if (buf && buf.length > 1) template = unzipSync(buf.subarray(1)).toString();
			} catch {
				template = elem.richMsg.template?.toString() ?? "";
			}
			if (isForward) {
				const resid = template.match(/m_resid="([^"]+)"/)?.[1];
				const fileName = template.match(/m_fileName="([^"]+)"/)?.[1];
				result.push({
					elementType: ElementType.MultiForward,
					multiForwardMsgElement: {
						xmlContent: template,
						resId: resid ?? "",
						fileName: fileName ?? "",
						nodes: [],
						title: "",
						preview: [],
						summary: "",
						prompt: ""
					}
				});
			}
			continue;
		}
		if (elem.transElemInfo) {
			if (elem.transElemInfo.elemType === 24) {
				const buf = elem.transElemInfo.elemValue;
				const length = buf.readInt16BE(1);
				const data = buf.subarray(3, 3 + length);
				const { inner } = Msg.GroupFileExtra.decode(data);
				result.push({
					elementType: ElementType.File,
					fileElement: {
						fileName: inner.info.fileName,
						fileSize: inner.info.fileSize,
						fileMd5: inner.info.fileMd5,
						fileUuid: inner.info.fileId,
						fileBizId: inner.info.busId,
						folderId: "",
						filePath: "",
						expireTime: 0
					}
				});
				continue;
			}
		}
		if (elem.lightApp) {
			let jsonStr = "";
			if (elem.lightApp.data && elem.lightApp.data.length > 1) try {
				jsonStr = unzipSync(elem.lightApp.data.subarray(1)).toString();
			} catch {
				jsonStr = elem.lightApp.data.subarray(1).toString();
			}
			result.push({
				elementType: ElementType.Ark,
				arkElement: { bytesData: jsonStr }
			});
			break;
		}
		if (elem.srcMsg) {
			result.push({
				elementType: ElementType.Reply,
				replyElement: {
					replyMsgSeq: isGroup ? elem.srcMsg.origSeqs[0] : elem.srcMsg.attr.ntMsgSeq ?? 0,
					replyMsgTime: elem.srcMsg.time,
					senderUin: elem.srcMsg.senderUin,
					senderUid: elem.srcMsg.attr.senderUid,
					replyMsgClientSeq: isGroup ? 0 : elem.srcMsg.origSeqs[0]
				}
			});
			continue;
		}
		if (elem.commonElem) {
			const svcType = elem.commonElem.serviceType;
			const bizType = elem.commonElem.businessType;
			const pbElem = elem.commonElem.pbElem;
			if (svcType === 2) {
				result.push({
					elementType: ElementType.Face,
					faceElement: {
						faceIndex: bizType,
						faceType: 5,
						faceText: "",
						pokeType: 1
					}
				});
				break;
			} else if (svcType === 33) {
				const ext = Msg.QSmallFaceExtra.decode(pbElem);
				result.push({
					elementType: ElementType.Face,
					faceElement: {
						faceIndex: ext.faceId,
						faceType: 2,
						faceText: ext.text
					}
				});
			} else if (svcType === 37) {
				const ext = Msg.LargeFaceExtra.decode(pbElem);
				const faceIndex = Number(ext.faceId ?? 0);
				const face = face_config_default.sysface.find((f) => f.QSid === String(faceIndex));
				result.push({
					elementType: ElementType.Face,
					faceElement: {
						faceIndex,
						faceType: 3,
						faceText: face?.QDes ?? "",
						packId: ext.aniStickerPackId,
						stickerId: ext.aniStickerId,
						stickerType: ext.aniStickerType,
						resultId: ext.resultId !== void 0 ? String(ext.resultId) : void 0
					}
				});
				break;
			} else if (svcType === 45) {
				const ext = Msg.MarkdownExtra.decode(pbElem);
				result.push({
					elementType: ElementType.Markdown,
					markdownElement: { content: ext.content }
				});
			} else if (svcType === 48) {
				const parsed = parseMsgInfoElement(pbElem, bizType);
				if (parsed) result.push(parsed);
			}
		}
	}
	if (isGroup) {
		if (result[0]?.textElement && result[2]?.replyElement) result = result.slice(2);
	} else {
		const index = result.findIndex((e) => e.replyElement);
		if (index !== -1 && index !== 0) moveElement(result, index, 0);
	}
	return result;
}
/**
* Parse commonElem.pbElem (MsgInfo protobuf) for serviceType=48.
* bizType: 10/20=image, 11/21=video, 12/22=voice
*/
function parseMsgInfoElement(pbElem, bizType) {
	const msgInfo = Media.MsgInfo.decode(pbElem);
	const body = msgInfo.msgInfoBody[0];
	if (!body) return null;
	const fileInfo = body.index.info;
	const fileUuid = body.index.fileUuid;
	const fileSize = fileInfo.fileSize;
	const fileName = fileInfo.fileName;
	const md5 = fileInfo.md5HexStr;
	if (bizType === 10 || bizType === 20) {
		const picInfo = body.pic;
		let originImageUrl = "";
		if (picInfo?.urlPath) {
			originImageUrl = picInfo.urlPath;
			if (picInfo.ext?.originalParam) originImageUrl += picInfo.ext.originalParam;
		}
		return {
			elementType: ElementType.Pic,
			picElement: {
				fileName,
				fileSize,
				picWidth: fileInfo.width,
				picHeight: fileInfo.height,
				md5HexStr: md5,
				sourcePath: "",
				picType: fileInfo.fileType.picFormat,
				picSubType: msgInfo.extBizInfo.pic.bizType,
				fileUuid,
				originImageUrl,
				summary: msgInfo.extBizInfo.pic.summary
			}
		};
	} else if (bizType === 12 || bizType === 22) return {
		elementType: ElementType.Ptt,
		pttElement: {
			fileName,
			filePath: "",
			md5HexStr: md5,
			fileSize,
			duration: fileInfo.time,
			formatType: fileInfo.fileType.pttFormat,
			fileUuid
		}
	};
	else if (bizType === 11 || bizType === 21) return {
		elementType: ElementType.Video,
		videoElement: {
			filePath: "",
			fileName,
			videoMd5: md5,
			fileTime: fileInfo?.time || 0,
			fileFormat: fileInfo?.fileType?.videoFormat || 0,
			fileSize,
			thumbWidth: 0,
			thumbHeight: 0,
			thumbPath: "",
			fileUuid
		}
	};
	return null;
}
//#endregion
//#region src/ntqqapi/dispatcher.ts
var logger$7 = getLogger("dispatcher");
var MSG_PUSH_CMD = "trpc.msg.olpush.OlPushService.MsgPush";
var KICK_CMD = "trpc.qq_new_tech.status_svc.StatusService.KickNT";
var INFO_SYNC_PUSH_CMD = "trpc.msg.register_proxy.RegisterProxy.InfoSyncPush";
var PUSH_PARAMS_CMD = "trpc.msg.register_proxy.RegisterProxy.PushParams";
var CONFIG_PUSH_CMD = "ConfigPushSvc.PushReq";
/**
* 解析 QQ 协议原始 protobuf 推送，emit 对应 cordis 事件。
* 直连模式和 PMHQ 模式都通过 'qq/raw' 事件喂数据进来。
*/
function registerDispatcher(ctx) {
	ctx.on("qq/raw", ({ cmd, payload }) => {
		logger$7.debug(`cmd=${cmd} bodyLen=${payload.length} bodyHex=%h`, payload);
		try {
			switch (cmd) {
				case MSG_PUSH_CMD:
					handleMsgPush(ctx, payload);
					break;
				case KICK_CMD:
					handleKickNT(ctx, payload);
					break;
				case INFO_SYNC_PUSH_CMD: break;
				case PUSH_PARAMS_CMD: break;
				case CONFIG_PUSH_CMD:
			}
		} catch (e) {
			ctx.logger.warn("dispatch error:", e);
		}
	});
}
function handleMsgPush(ctx, payload) {
	const msg = Msg.PushMsg.decode(payload).message;
	logger$7.debug(`MsgPush msgType=${msg?.contentHead.msgType} subType=${msg?.contentHead.subType} fromUid=${msg?.routingHead?.fromUid ?? "?"} fromUin=${msg?.routingHead?.fromUin ?? "?"} groupCode=${msg?.routingHead?.group?.groupCode ?? "?"}`);
	if (!msg) return;
	const msgType = msg.contentHead.msgType;
	const subType = msg.contentHead.subType;
	switch (msgType) {
		case 82:
		case 166:
		case 167:
		case 141:
		case 208:
		case 529:
			handleChatMessage(ctx, msg, msgType, payload);
			break;
		case 33:
			handleGroupMemberIncrease(ctx, msg);
			break;
		case 34:
			handleGroupMemberDecrease(ctx, msg);
			break;
		case 44:
			handleGroupAdminChange(ctx, msg);
			break;
		case 528:
			handle0x210(ctx, msg, subType);
			break;
		case 732:
			handle0x2DC(ctx, msg, subType);
			break;
		case 84:
			handleGroupJoinRequest(ctx, msg);
			break;
		case 87:
		case 525:
			handleGroupInvitation(ctx, msg, msgType);
			break;
		case 85: handleGroupJoined(ctx, msg);
	}
}
async function handleGroupAdminChange(ctx, msg) {
	const content = msg.body?.msgContent;
	if (!content) return;
	const decoded = Notify.GroupAdminChange.decode(content);
	const adminUid = decoded.isPromote ? decoded.body.extraEnable?.adminUid : decoded.body.extraDisable?.adminUid;
	if (!adminUid) return null;
	const group = await ctx.ntGroupApi.getGroup(decoded.groupCode, false);
	ctx.parallel("nt/group-admin-changed", {
		groupCode: decoded.groupCode,
		targetUin: await ctx.ntUserApi.getUinByUid(adminUid),
		targetUid: adminUid,
		operatorUin: await ctx.ntUserApi.getUinByUid(group.ownerUid),
		operatorUid: group.ownerUid,
		isSet: decoded.isPromote
	});
}
async function handleGroupMemberDecrease(ctx, msg) {
	const content = msg.body?.msgContent;
	if (!content) return;
	const decoded = Notify.GroupMemberChange.decode(content);
	let adminUin;
	let adminUid;
	if (decoded.adminUid) {
		const adminUidMatch = decoded.adminUid.match(/\x18([^\x18\x10]+)\x10/);
		if (adminUidMatch) {
			adminUid = adminUidMatch[1];
			adminUin = await ctx.ntUserApi.getUinByUid(adminUid);
		}
	}
	if (decoded.type === 129) ctx.parallel("nt/group-disband", {
		groupCode: decoded.groupCode,
		operatorUin: adminUin,
		operatorUid: adminUid
	});
	else ctx.parallel("nt/group-member-removed", {
		groupCode: decoded.groupCode,
		memberUin: await ctx.ntUserApi.getUinByUid(decoded.memberUid),
		memberUid: decoded.memberUid,
		operatorUin: adminUin,
		operatorUid: adminUid
	});
}
async function handleGroupMemberIncrease(ctx, msg) {
	const content = msg.body?.msgContent;
	if (!content) return;
	const decoded = Notify.GroupMemberChange.decode(content);
	if (decoded.memberUid === selfInfo.uid && decoded.type === 131) ctx.parallel("nt/group-added", { groupCode: decoded.groupCode });
	if (decoded.type === 130) ctx.parallel("nt/group-member-added", {
		groupCode: decoded.groupCode,
		memberUin: await ctx.ntUserApi.getUinByUid(decoded.memberUid),
		memberUid: decoded.memberUid,
		operatorUin: await ctx.ntUserApi.getUinByUid(decoded.adminUid),
		operatorUid: decoded.adminUid
	});
	else if (decoded.type === 131) ctx.parallel("nt/group-member-added", {
		groupCode: decoded.groupCode,
		memberUin: await ctx.ntUserApi.getUinByUid(decoded.memberUid),
		memberUid: decoded.memberUid,
		invitorUin: await ctx.ntUserApi.getUinByUid(decoded.adminUid),
		invitorUid: decoded.adminUid
	});
}
function handleGroupJoined(ctx, msg) {
	const content = msg.body?.msgContent;
	if (!content) return;
	const decoded = Notify.GroupJoined.decode(content);
	ctx.parallel("nt/group-added", { groupCode: decoded.groupCode });
}
/** 解析 KickNT 被踢下线推送 */
function handleKickNT(ctx, payload) {
	const decoded = Msg.KickNTPush.decode(payload);
	selfInfo.online = false;
	ctx.logger.warn(`[Kick] code=${decoded.code} title="${decoded.tipsTitle}" desc="${decoded.tipsDesc}"`);
	ctx.parallel("nt/kicked-offline", {
		tipsDesc: decoded.tipsDesc,
		tipsTitle: decoded.tipsTitle,
		kickedType: decoded.code
	});
}
function handle0x210(ctx, msg, subType) {
	const content = msg.body?.msgContent;
	if (!content) return;
	switch (subType) {
		case 35:
			handleFriendRequest$2(ctx, msg, content);
			break;
		case 138:
		case 139:
			handleFriendRecall(ctx, content);
			break;
		case 39:
			handleFriendRelatedOrPin(ctx, msg, content);
			break;
		case 290:
			handleFriendGrayTip(ctx, msg, content);
			break;
		case 61:
			handlePttTransResult(ctx, content);
			break;
		case 212:
			handleGroupRemoved(ctx, content);
			break;
		case 179: handleFriendAdded(ctx, msg, content);
	}
}
function handleFriendAdded(ctx, msg, content) {
	const decoded = Notify.FriendAdded.decode(content);
	ctx.parallel("nt/friend-added", {
		uin: msg.routingHead.fromUin,
		uid: decoded.body.friendUid
	});
}
function handleGroupRemoved(ctx, content) {
	const decoded = Notify.GroupRemoved.decode(content);
	ctx.parallel("nt/group-removed", decoded);
}
async function handleFriendRelatedOrPin(ctx, msg, content) {
	try {
		const decoded = Notify.FriendRelatedOrPinChange.decode(content);
		if (decoded.body.friendDeleted) {
			const { uid } = decoded.body.friendDeleted;
			ctx.parallel("nt/friend-removed", {
				uin: await ctx.ntUserApi.getUinByUid(uid),
				uid
			});
		} else if (decoded.body.pinChanged) {
			const { body } = decoded.body.pinChanged;
			ctx.parallel("nt/pin-changed", {
				chatType: body.groupCode ? ChatType.Group : ChatType.C2C,
				peerUin: body.groupCode ?? await ctx.ntUserApi.getUinByUid(body.uid),
				peerUid: body.groupCode ? body.groupCode.toString() : body.uid,
				isPinned: body.info.timestamp.length !== 0
			});
		} else if (decoded.body.profileLike) {
			const { msg } = decoded.body.profileLike;
			ctx.parallel("nt/profile-like", {
				uin: msg.detail.uin,
				uid: await ctx.ntUserApi.getUidByUin(msg.detail.uin),
				nick: msg.detail.nickname,
				times: Number(msg.detail.txt?.match(/\d+/)?.[0] ?? 0)
			});
		}
	} catch (e) {
		ctx.logger.warn("FriendRelatedOrPin parse error:", e.message);
	}
}
function handleFriendGrayTip(ctx, msg, content) {
	try {
		const decoded = Notify.GeneralGrayTip.decode(content);
		if (decoded.bizType === 12) ctx.parallel("nt/friend-nudge", {
			uin: msg.routingHead.fromUin,
			uid: msg.routingHead.fromUid,
			isSelfSend: decoded.templParam.get("uin_str1") === selfInfo.uin,
			isSelfReceive: decoded.templParam.get("uin_str2") === selfInfo.uin,
			displayAction: decoded.templParam.get("action_str"),
			displaySuffix: decoded.templParam.get("suffix_str"),
			displayActionImgUrl: decoded.templParam.get("action_img_url")
		});
	} catch (e) {
		ctx.logger.warn("FriendGrayTip parse error:", e.message);
	}
}
function handlePttTransResult(ctx, content) {
	try {
		const body = Msg.PttTransResultPush.decode(content).body;
		if (!body) return;
		ctx.parallel("nt/ptt-trans-result", {
			msgId: body.msgUid.toString(),
			text: body.text
		});
	} catch (e) {
		ctx.logger.warn("PttTransResult parse error:", e.message);
	}
}
function handleFriendRequest$2(ctx, msg, content) {
	const decoded = Notify.FriendRequest.decode(content);
	if (!decoded.body) return;
	ctx.parallel("nt/friend-request", {
		initiatorUin: msg.routingHead.fromUin,
		initiatorUid: decoded.body.fromUid,
		comment: decoded.body.message,
		via: decoded.body.via
	});
}
async function handleFriendRecall(ctx, content) {
	try {
		const body = Notify.FriendRecall.decode(content).body;
		if (!body) return;
		const fromUid = body.fromUid;
		const toUid = body.toUid;
		const fromUin = await ctx.ntUserApi.getUinByUid(fromUid);
		const toUin = await ctx.ntUserApi.getUinByUid(toUid);
		const peerUid = fromUid === selfInfo.uid ? toUid : fromUid;
		const peerUin = fromUid === selfInfo.uid ? toUin : fromUin;
		ctx.parallel("nt/message-deleted", {
			chatType: await ctx.ntFriendApi.isFriend(peerUid) ? ChatType.C2C : ChatType.TempC2CFromGroup,
			peerUin,
			peerUid,
			msgId: body.msgUid.toString(),
			msgSeq: body.sequence,
			msgRandom: body.random,
			senderUin: fromUin,
			senderUid: fromUid,
			operatorUin: fromUin,
			operatorUid: fromUid,
			displaySuffix: body.tipInfo?.tip ?? ""
		});
	} catch (e) {
		ctx.logger.warn("Failed to parse FriendRecall:", e.message);
	}
}
function handle0x2DC(ctx, msg, subType) {
	const content = msg.body?.msgContent;
	if (!content) return;
	switch (subType) {
		case 17:
			handleGroupRecall(ctx, content);
			break;
		case 12:
			handleGroupMute(ctx, content);
			break;
		case 16:
			handleGroupGeneralEvent(ctx, content);
			break;
		case 20:
			handleGroupGrayTip(ctx, msg, content);
			break;
		case 21: handleGroupEssenceChange(ctx, content);
	}
}
async function handleGroupMute(ctx, content) {
	try {
		const decoded = Notify.GroupMute.decode(content);
		const { state } = decoded.info;
		if (state.targetUid) ctx.parallel("nt/group-mute", {
			groupCode: decoded.groupCode,
			memberUin: await ctx.ntUserApi.getUinByUid(state.targetUid),
			memberUid: state.targetUid,
			operatorUin: await ctx.ntUserApi.getUinByUid(decoded.operatorUid),
			operatorUid: decoded.operatorUid,
			duration: state.duration
		});
		else ctx.parallel("nt/group-whole-mute", {
			groupCode: decoded.groupCode,
			operatorUin: await ctx.ntUserApi.getUinByUid(decoded.operatorUid),
			operatorUid: decoded.operatorUid,
			isMute: state.duration !== 0
		});
	} catch (e) {
		ctx.logger.warn("GroupMute parse error:", e.message);
	}
}
async function handleGroupGeneralEvent(ctx, content) {
	try {
		if (content.length < 7) return;
		const groupUinFromTLV = content.readUInt32BE(0);
		const inner = unwrap0x2DCContent(content);
		const notifyBody = Notify.NotifyMessageBody.decode(inner);
		const groupCode = notifyBody.groupCode || groupUinFromTLV;
		const field13 = notifyBody.subType ?? 0;
		if (field13 === 35) {
			const { data } = notifyBody.reaction.data;
			ctx.parallel("nt/group-message-reaction", {
				groupCode,
				operatorUin: await ctx.ntUserApi.getUinByUid(data.data.operatorUid),
				operatorUid: data.data.operatorUid,
				msgSeq: data.target.sequence,
				faceId: data.data.code,
				count: data.data.count,
				type: data.data.reactionType,
				isAdd: data.data.actionType === 1
			});
		} else if (field13 === 6) {
			const eventParam = notifyBody.eventParam;
			if (!eventParam) return;
			const decoded = Notify.GroupMemberSpecialTitleChange.decode(eventParam);
			const title = decoded.tipText.match(/\{"cmd":1,[^}]*?"text":"([^"]+)"/)?.[1] ?? "";
			ctx.parallel("nt/group-member-special-title-changed", {
				groupCode,
				uin: decoded.memberUin,
				uid: await ctx.ntUserApi.getUidByUin(decoded.memberUin, groupCode),
				newSpecialTitle: title
			});
		} else if (field13 === 12) {
			const eventParam = notifyBody.eventParam;
			if (!eventParam || !notifyBody.operatorUid) return;
			const body = Notify.GroupNameChangeBody.decode(eventParam);
			ctx.parallel("nt/group-name-changed", {
				groupCode,
				newGroupName: body.newName,
				operatorUin: await ctx.ntUserApi.getUinByUid(notifyBody.operatorUid),
				operatorUid: notifyBody.operatorUid
			});
		}
	} catch (e) {
		ctx.logger.warn("GroupGeneralEvent parse error:", e.message);
	}
}
async function handleGroupGrayTip(ctx, msg, content) {
	try {
		if (content.length < 7) return;
		const groupUinFromTLV = content.readUInt32BE(0);
		const inner = unwrap0x2DCContent(content);
		if (!inner) return;
		const notifyBody = Notify.NotifyMessageBody.decode(inner);
		const grayTip = notifyBody.generalGrayTip;
		if (!grayTip) return;
		const groupCode = notifyBody.groupCode || groupUinFromTLV;
		if (grayTip.bizType === 12) {
			const uin1 = +grayTip.templParam.get("uin_str1");
			const uin2 = +grayTip.templParam.get("uin_str2");
			ctx.parallel("nt/group-nudge", {
				groupCode,
				senderUin: uin1,
				senderUid: await ctx.ntUserApi.getUidByUin(uin1, groupCode),
				receiverUin: uin2,
				receiverUid: await ctx.ntUserApi.getUidByUin(uin2, groupCode),
				displayAction: grayTip.templParam.get("action_str"),
				displaySuffix: grayTip.templParam.get("suffix_str"),
				displayActionImgUrl: grayTip.templParam.get("action_img_url")
			});
		}
	} catch (e) {
		ctx.logger.warn("GroupGrayTip parse error:", e.message);
	}
}
async function handleGroupEssenceChange(ctx, content) {
	try {
		if (content.length < 7) return;
		const groupUin = content.readUInt32BE(0);
		const inner = unwrap0x2DCContent(content);
		if (!inner) return;
		const notifyBody = Notify.NotifyMessageBody.decode(inner);
		const groupCode = notifyBody.groupCode || groupUin;
		const info = notifyBody.essenceMessage;
		ctx.parallel("nt/group-essence-message-changed", {
			groupCode,
			msgId: String(16777216n << 32n | BigInt(info.random)),
			msgSeq: info.msgSequence,
			msgRandom: info.random,
			senderUin: info.memberUin,
			senderUid: await ctx.ntUserApi.getUidByUin(info.memberUin, groupCode),
			operatorUin: info.operatorUin,
			operatorUid: await ctx.ntUserApi.getUidByUin(info.operatorUin, groupCode),
			isSet: info.setFlag === 1
		});
	} catch (e) {
		ctx.logger.warn("GroupEssenceChange parse error:", e.message);
	}
}
/**
* Strip the leading [4 bytes group code + 1 byte unknown + length-prefix] from 0x2DC content.
* Returns the inner protobuf body.
*/
function unwrap0x2DCContent(content) {
	const length = content.readUInt16BE(5);
	return content.subarray(7, 7 + length);
}
/**
* 0x2DC subtype 17 - Group recall
* Content layout: [4 bytes BE: groupUin][1 byte: ?][2 bytes BE length][NotifyMessageBody bytes]
* NotifyMessageBody.field11 = GroupRecall (with repeated RecallMessages at field 3)
*/
async function handleGroupRecall(ctx, content) {
	try {
		if (content.length < 7) return;
		const groupCode = content.readUInt32BE(0);
		const length = content.readUInt16BE(5);
		const bodyBytes = content.subarray(7, 7 + length);
		const notifyBody = Notify.NotifyMessageBody.decode(bodyBytes);
		const recall = notifyBody.recall;
		if (!recall || !recall.recallMessages || recall.recallMessages.length === 0) return;
		const operatorUid = recall.operatorUid || notifyBody.operatorUid || "";
		const operatorUin = await ctx.ntUserApi.getUinByUid(operatorUid);
		for (const rm of recall.recallMessages) ctx.parallel("nt/message-deleted", {
			chatType: ChatType.Group,
			peerUin: groupCode,
			peerUid: groupCode.toString(),
			msgId: String(16777216n << 32n | BigInt(rm.random)),
			msgSeq: rm.sequence,
			msgRandom: rm.random,
			senderUin: await ctx.ntUserApi.getUinByUid(rm.authorUid),
			senderUid: rm.authorUid,
			operatorUin,
			operatorUid,
			displaySuffix: recall.tipInfo?.tip ?? ""
		});
	} catch (e) {
		ctx.logger.warn("Failed to parse GroupRecall:", e.message);
	}
}
async function handleGroupJoinRequest(ctx, msg) {
	try {
		if (!msg.body) return;
		const decoded = Notify.GroupJoinRequest.decode(msg.body.msgContent);
		let notificationSeq, commit;
		let isDoubt = false;
		const notification = (await ctx.ntGroupApi.getGroupNotifications(false, 20)).notifications.filter((e) => e.type === GroupNotificationType.JoinRequest).find((e) => e.group.groupCode === decoded.groupCode && e.user1.uid === decoded.memberUid && e.requestState === RequestState.Unhandle);
		if (notification) {
			notificationSeq = notification.sequence;
			commit = notification.comment;
		} else {
			const notification = (await ctx.ntGroupApi.getGroupNotifications(true, 10)).notifications.filter((e) => e.type === GroupNotificationType.JoinRequest).find((e) => e.group.groupCode === decoded.groupCode && e.user1.uid === decoded.memberUid && e.requestState === RequestState.Unhandle);
			if (notification) {
				isDoubt = true;
				notificationSeq = notification.sequence;
				commit = notification.comment;
			}
		}
		if (notificationSeq) ctx.parallel("nt/group-join-request", {
			groupCode: decoded.groupCode,
			initiatorUin: await ctx.ntUserApi.getUinByUid(decoded.memberUid),
			initiatorUid: decoded.memberUid,
			notificationSeq,
			isDoubt,
			comment: commit ?? ""
		});
	} catch (e) {
		ctx.logger.warn("Failed to parse GroupJoinRequest:", e.message);
	}
}
async function handleGroupInvitation(ctx, msg, msgType) {
	try {
		if (!msg.body) return;
		const content = msg.body.msgContent;
		if (msgType === 525) {
			const { inner } = Notify.GroupInvitedJoinRequest.decode(content).info;
			const notification = (await ctx.ntGroupApi.getGroupNotifications(false, 20)).notifications.filter((e) => e.type === GroupNotificationType.InvitedJoinRequest).find((e) => e.group.groupCode === inner.groupCode && e.user2.uid === inner.invitorUid && e.user1.uid === inner.targetUid && e.requestState === RequestState.Unhandle);
			if (notification) ctx.parallel("nt/group-invited-join-request", {
				groupCode: inner.groupCode,
				initiatorUin: await ctx.ntUserApi.getUinByUid(inner.invitorUid),
				initiatorUid: inner.invitorUid,
				targetUserUin: await ctx.ntUserApi.getUinByUid(inner.targetUid),
				targetUserUid: inner.targetUid,
				notificationSeq: notification.sequence
			});
		} else {
			const decoded = Notify.GroupInvitation.decode(content);
			const notification = (await ctx.ntGroupApi.getGroupNotifications(false, 20)).notifications.filter((e) => e.type === GroupNotificationType.Invitation).find((e) => e.group.groupCode === decoded.groupCode && e.user2.uid === decoded.invitorUid && e.requestState === RequestState.Unhandle);
			if (notification) ctx.parallel("nt/group-invitation", {
				groupCode: decoded.groupCode,
				initiatorUin: await ctx.ntUserApi.getUinByUid(decoded.invitorUid),
				initiatorUid: decoded.invitorUid,
				invitationSeq: notification.sequence
			});
		}
	} catch (e) {
		ctx.logger.warn("Failed to parse GroupInvitation:", e.message);
	}
}
function handleChatMessage(ctx, msg, msgType, payload) {
	const routingHead = msg.routingHead;
	ctx.store.addUix([{
		uid: routingHead.fromUid,
		uin: routingHead.fromUin
	}]).catch((e) => ctx.logger.warn(e));
	if (msgType === 141) {
		let peerUid;
		if (routingHead.fromUid === selfInfo.uid && routingHead.toUid) peerUid = routingHead.toUid;
		else peerUid = routingHead.fromUid;
		ctx.store.addTempChatInfo({
			peerUid,
			groupCode: routingHead.c2c.fromTinyId
		}).catch((e) => ctx.logger.warn(e));
	} else if (msgType === 166) {
		if (msg.body?.richText.elems[0]?.lightApp) {
			const { data } = msg.body.richText.elems[0].lightApp;
			const jumpUrlMatch = unzipSync(data.subarray(1)).toString().match(/(?=.*?"app"\s*:\s*"com\.tencent\.tuwen\.lua")(?=.*?"bizsrc"\s*:\s*"qun\.invite")[\s\S]*?"jumpUrl"\s*:\s*"([^"]*)"/);
			if (jumpUrlMatch?.[1]) {
				const params = new URLSearchParams(jumpUrlMatch[1]);
				const receiverUin = params.get("receiveruin");
				const senderUin = params.get("senderuin");
				const msgFromUin = msg.routingHead.fromUin.toString();
				if (receiverUin === selfInfo.uin && senderUin === msgFromUin) {
					const groupCode = params.get("groupcode");
					const seq = params.get("msgseq");
					ctx.parallel("nt/group-invitation", {
						groupCode: +groupCode,
						initiatorUin: msg.routingHead.fromUin,
						initiatorUid: msg.routingHead.fromUid,
						invitationSeq: +seq
					});
				}
			}
		}
	} else if (msgType === 82) {
		const peerUin = routingHead.group.groupCode;
		const senderUin = routingHead.fromUin;
		const senderUid = routingHead.fromUid;
		const sendMemberName = routingHead.group.groupCardType === 1 ? routingHead.group.groupCard : "";
		ctx.store.getGroupMemberCardName(peerUin, senderUin).then((oldCard) => {
			if (oldCard === void 0) ctx.store.setGroupMemberCardName(peerUin, senderUin, sendMemberName).catch((e) => ctx.logger.warn(e));
			else if (oldCard !== sendMemberName) {
				ctx.store.setGroupMemberCardName(peerUin, senderUin, sendMemberName).catch((e) => ctx.logger.warn(e));
				ctx.parallel("nt/group-member-card-name-changed", {
					groupCode: peerUin,
					uin: senderUin,
					uid: senderUid,
					oldCardName: oldCard,
					newCardName: sendMemberName
				});
			}
		}).catch((e) => ctx.logger.warn(e));
	}
	const rawMessage = convertToRawMessage(msg, payload.toString("hex"));
	if (!rawMessage) return;
	{
		const elemSummary = rawMessage.elements.map((e) => `type=${e.elementType}` + (e.fileElement ? ` file=${e.fileElement.fileName}` : "") + (e.textElement ? ` text="${e.textElement.content?.slice(0, 30)}"` : "")).join(", ");
		logger$7.debug(`convertedRawMsg msgId=${rawMessage.msgId} chatType=${rawMessage.chatType} peerUin=${rawMessage.peerUin} senderUin=${rawMessage.senderUin} elementsLen=${rawMessage.elements.length} [${elemSummary}]`);
	}
	if (rawMessage.senderUin === +selfInfo.uin) {
		logger$7.debug(`emit nt/message-sent msgId=${rawMessage.msgId}`);
		ctx.parallel("nt/message-sent", { message: rawMessage });
		return;
	}
	ctx.parallel("nt/message-created", { message: rawMessage });
}
/** 把 Msg.Message protobuf 转换为上层用的 RawMessage（OlPush 推送和 SsoGetGroupMsg 拉历史共用） */
function convertToRawMessage(msg, rawPb) {
	const routingHead = msg.routingHead;
	const contentHead = msg.contentHead;
	const body = msg.body;
	const msgType = contentHead.msgType;
	if (!routingHead || !contentHead) return null;
	if (!routingHead.fromUin) return null;
	let chatType;
	let peerUin;
	let peerUid;
	let sendMemberName = "";
	let sendNickName = "";
	let peerName = "";
	let tempFromGroupCode = 0;
	if (msgType === 82) {
		chatType = ChatType.Group;
		peerUin = routingHead.group.groupCode;
		peerUid = peerUin.toString();
		if (routingHead.group.groupCardType === 1) sendMemberName = routingHead.group.groupCard;
		else sendNickName = routingHead.group.groupCard;
		peerName = routingHead.group.groupName;
	} else if (msgType === 141) {
		chatType = ChatType.TempC2CFromGroup;
		if (routingHead.fromUid === selfInfo.uid && routingHead.toUid) {
			peerUin = routingHead.toUin;
			peerUid = routingHead.toUid;
		} else {
			peerUin = routingHead.fromUin;
			peerUid = routingHead.fromUid;
		}
		tempFromGroupCode = routingHead.c2c.fromTinyId;
		sendNickName = routingHead.c2c.name;
	} else {
		chatType = ChatType.C2C;
		if (routingHead.fromUid === selfInfo.uid && routingHead.toUid) {
			peerUin = routingHead.toUin;
			peerUid = routingHead.toUid;
		} else {
			peerUin = routingHead.fromUin;
			peerUid = routingHead.fromUid;
		}
		sendNickName = routingHead.c2c.name;
	}
	const elements = parseElements(body?.richText?.elems ?? [], chatType === ChatType.Group);
	if (msgType === 529 && body?.msgContent && elements.length === 0) try {
		const nof = Msg.FileExtra.decode(Buffer.from(body.msgContent)).file;
		if (nof) elements.push({
			elementType: ElementType.File,
			fileElement: {
				fileName: nof.fileName,
				fileSize: nof.fileSize,
				fileMd5: nof.fileMd5 ? Buffer.from(nof.fileMd5).toString("hex") : "",
				expireTime: nof.expireTime,
				fileUuid: nof.fileUuid,
				fileBizId: 0,
				filePath: "",
				folderId: ""
			}
		});
	} catch (e) {
		logger$7.warn("PrivateFile FileExtra decode failed:", e.message);
	}
	let style;
	const elems = body?.richText?.elems ?? [];
	const elemFlags2 = elems.find((e) => e.elemFlags2)?.elemFlags2;
	if (elemFlags2) {
		style = {};
		style.bubbleId = Number(elemFlags2.colorTextId);
	}
	const generalFlags = elems.find((e) => e.generalFlags)?.generalFlags;
	if (generalFlags) {
		style ??= {};
		style.bubbleDiyTextId = generalFlags.bubbleDiyTextId;
		style.pendantId = Number(generalFlags.pendantId);
		const extra = Msg.MessageStyleExtra.decode(generalFlags.pbReserve);
		style.fontId = Number((extra.font & 65280n) >> 8n | (extra.font & 255n) << 8n);
		style.fontEffectId = extra.fontEffectId;
		style.isCsFontEffectEnabled = (extra.font & 65536n) !== 0n;
	}
	return {
		msgId: String(contentHead.msgUid || 16777216n << 32n | BigInt(contentHead.random)),
		msgTime: contentHead.msgTime,
		msgSeq: contentHead.c2cMsgSeq || contentHead.groupMsgSeqOrC2cClientSeq,
		msgRandom: contentHead.random,
		senderUid: routingHead.fromUid,
		senderUin: routingHead.fromUin,
		peerUid,
		peerUin,
		sendNickName,
		sendMemberName,
		chatType,
		elements,
		peerName,
		tempFromGroupCode,
		clientSeq: contentHead.c2cMsgSeq ? contentHead.groupMsgSeqOrC2cClientSeq : 0,
		forwardAvatar: contentHead.forward?.avatar ?? "",
		rawPb,
		memberRole: routingHead.group ? {
			0: GroupMemberRole.Normal,
			8: GroupMemberRole.Owner,
			16: GroupMemberRole.Admin
		}[routingHead.group.msgFlag] : GroupMemberRole.NotApplicable,
		msgStyle: style ? style : void 0
	};
}
//#endregion
//#region src/ntqqapi/core.ts
var Core = class extends Service {
	ctx;
	config;
	static inject = [
		"ntMsgApi",
		"ntFriendApi",
		"store",
		"ntFileApi",
		"ntGroupApi",
		"ntUserApi"
	];
	startupTime = 0;
	messageReceivedCount = 0;
	messageSentCount = 0;
	lastMessageTime = 0;
	constructor(ctx, config) {
		super(ctx, "app");
		this.ctx = ctx;
		this.config = config;
	}
	async [Service.init]() {
		this.start();
		return noop;
	}
	start() {
		this.startupTime = Math.trunc(Date.now() / 1e3);
		this.registerListener();
		registerDispatcher(this.ctx);
		setFFMpegPath("");
		this.ctx.on("llob/config-updated", (input) => {
			Object.assign(this.config, input);
			setFFMpegPath(input.ffmpeg || "");
		});
	}
	async sendMessage(ctx, peer, sendElements, deleteAfterSentFiles) {
		let groupMsgMask;
		if (peer.chatType === ChatType.Group) {
			const info = await ctx.ntGroupApi.getGroup(+peer.peerUid, false);
			groupMsgMask = info.msgMask;
			if (info.personShutupExpireTime * 1e3 > Date.now() || info.groupShutupExpireTime * 1e3 > Date.now() && info.memberRole === GroupMemberRole.Normal) {
				deleteAfterSentFiles.forEach((path) => {
					unlink(path).catch(noop);
				});
				throw new Error("当前处于被禁言状态");
			}
		}
		if (!sendElements.length) {
			deleteAfterSentFiles.forEach((path) => {
				unlink(path).catch(noop);
			});
			throw new Error("消息体无法解析，请检查是否发送了不支持的消息类型");
		}
		try {
			const returnMsg = await ctx.ntMsgApi.sendMsg(peer, sendElements, groupMsgMask);
			this.messageSentCount++;
			if (returnMsg.chatType !== ChatType.Group) this.ctx.parallel("nt/message-sent", { message: returnMsg });
			return returnMsg;
		} finally {
			deleteAfterSentFiles.forEach((path) => {
				unlink(path).catch(noop);
			});
		}
	}
	registerListener() {
		this.ctx.on("nt/message-created", (data) => {
			this.ctx.store.addMsgCache(data.message);
			this.lastMessageTime = data.message.msgTime;
			this.messageReceivedCount++;
			logSummaryMessage(this.ctx, data.message);
		});
		this.ctx.on("nt/message-sent", (data) => {
			this.ctx.store.addMsgCache(data.message);
		});
	}
};
//#endregion
//#region src/onebot11/types.ts
var OB11UserSex = /* @__PURE__ */ function(OB11UserSex) {
	OB11UserSex["Male"] = "male";
	OB11UserSex["Female"] = "female";
	OB11UserSex["Unknown"] = "unknown";
	return OB11UserSex;
}({});
var OB11GroupMemberRole = /* @__PURE__ */ function(OB11GroupMemberRole) {
	OB11GroupMemberRole["Owner"] = "owner";
	OB11GroupMemberRole["Admin"] = "admin";
	OB11GroupMemberRole["Member"] = "member";
	return OB11GroupMemberRole;
}({});
var OB11MessageDataType = /* @__PURE__ */ function(OB11MessageDataType) {
	OB11MessageDataType["Text"] = "text";
	OB11MessageDataType["Image"] = "image";
	OB11MessageDataType["Music"] = "music";
	OB11MessageDataType["Video"] = "video";
	OB11MessageDataType["Record"] = "record";
	OB11MessageDataType["File"] = "file";
	OB11MessageDataType["FlashFile"] = "flash_file";
	OB11MessageDataType["At"] = "at";
	OB11MessageDataType["Reply"] = "reply";
	OB11MessageDataType["Json"] = "json";
	OB11MessageDataType["Face"] = "face";
	OB11MessageDataType["Mface"] = "mface";
	OB11MessageDataType["Markdown"] = "markdown";
	OB11MessageDataType["Node"] = "node";
	OB11MessageDataType["Forward"] = "forward";
	OB11MessageDataType["Xml"] = "xml";
	OB11MessageDataType["Poke"] = "poke";
	OB11MessageDataType["Dice"] = "dice";
	OB11MessageDataType["Rps"] = "rps";
	OB11MessageDataType["Contact"] = "contact";
	OB11MessageDataType["Shake"] = "shake";
	OB11MessageDataType["Keyboard"] = "keyboard";
	return OB11MessageDataType;
}({});
//#endregion
//#region src/onebot11/event/OB11BaseEvent.ts
var EventType = /* @__PURE__ */ function(EventType) {
	EventType["META"] = "meta_event";
	EventType["REQUEST"] = "request";
	EventType["NOTICE"] = "notice";
	EventType["MESSAGE"] = "message";
	EventType["MESSAGE_SENT"] = "message_sent";
	return EventType;
}({});
var OB11BaseEvent = class {
	time = Math.floor(Date.now() / 1e3);
	self_id = +selfInfo.uin;
	getSummaryEventName() {
		return this.post_type + "." + this[(this.post_type === "message_sent" ? "message" : this.post_type) + "_type"];
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11BaseNoticeEvent.ts
var OB11BaseNoticeEvent = class extends OB11BaseEvent {
	post_type = EventType.NOTICE;
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupNoticeEvent.ts
var OB11GroupNoticeEvent = class extends OB11BaseNoticeEvent {};
//#endregion
//#region src/onebot11/event/notice/OB11GroupUploadNoticeEvent.ts
var OB11GroupUploadNoticeEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_upload";
	file;
	group_id;
	user_id;
	constructor(groupId, userId, file) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.file = file;
	}
};
//#endregion
//#region src/onebot11/cqcode.ts
var pattern = /\[CQ:(\w+)((,\w+=[^,\]]*)*)\]/;
function unescape$1(source) {
	return String(source).replace(/&#91;/g, "[").replace(/&#93;/g, "]").replace(/&#44;/g, ",").replace(/&amp;/g, "&");
}
function from(source) {
	const capture = pattern.exec(source);
	if (!capture) return null;
	const [, type, attrs] = capture;
	const data = {};
	if (attrs) attrs.slice(1).split(",").forEach((str) => {
		const index = str.indexOf("=");
		data[str.slice(0, index)] = unescape$1(str.slice(index + 1));
	});
	return {
		type,
		data,
		capture
	};
}
function h(type, data) {
	return {
		type,
		data
	};
}
function decodeCQCode(source) {
	const elements = [];
	let result;
	while (result = from(source)) {
		const { type, data, capture } = result;
		if (capture.index) elements.push(h("text", { text: unescape$1(source.slice(0, capture.index)) }));
		elements.push(h(type, data));
		source = source.slice(capture.index + capture[0].length);
	}
	if (source) elements.push(h("text", { text: unescape$1(source) }));
	return elements;
}
function encodeCQCode(input) {
	const CQCodeEscapeText = (text) => {
		return text.replace(/\&/g, "&amp;").replace(/\[/g, "&#91;").replace(/\]/g, "&#93;");
	};
	const CQCodeEscape = (text) => {
		return text.replace(/\&/g, "&amp;").replace(/\[/g, "&#91;").replace(/\]/g, "&#93;").replace(/,/g, "&#44;");
	};
	if (input.type === "text") return CQCodeEscapeText(input.data.text);
	let result = "[CQ:" + input.type;
	for (const [key, value] of Object.entries(input.data)) {
		if (value === void 0) continue;
		try {
			const text = value.toString();
			result += `,${key}=${CQCodeEscape(text)}`;
		} catch (error) {}
	}
	result += "]";
	return result;
}
//#endregion
//#region src/onebot11/transform/message/incoming.ts
async function transformIncomingSegments$1(ctx, message) {
	const segments = [];
	let cqCode = "";
	for (const element of message.elements) {
		let messageSegment;
		if (element.textElement && element.textElement?.atType !== AtType.Unknown) {
			let qq;
			let name;
			if (element.textElement.atType === AtType.All) qq = "all";
			else {
				const { atUin, content } = element.textElement;
				qq = atUin.toString();
				name = content.replace("@", "");
			}
			messageSegment = {
				type: OB11MessageDataType.At,
				data: {
					qq,
					name
				}
			};
		} else if (element.textElement) {
			const text = element.textElement.content;
			if (!text) continue;
			messageSegment = {
				type: OB11MessageDataType.Text,
				data: { text }
			};
		} else if (element.replyElement) {
			const { replyElement } = element;
			const peer = {
				chatType: message.chatType,
				peerUid: message.peerUid,
				guildId: ""
			};
			try {
				const { replyMsgSeq, replyMsgTime, replyMsgClientSeq } = replyElement;
				let replyMsg = ctx.store.getMsgBySeq(peer.peerUid, replyMsgSeq);
				if (!replyMsg) {
					const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, replyMsgSeq);
					replyMsg = msgList[0];
				}
				if (!replyMsg && peer.chatType !== ChatType.Group) {
					const { msgList } = await ctx.ntMsgApi.getC2CMsgsByTimeAndCount(peer, replyMsgTime + 1, 3, true);
					replyMsg = msgList.find((e) => e.clientSeq === replyMsgClientSeq);
				}
				if (!replyMsg) {
					ctx.logger.warn("reply 原消息未找到", replyElement);
					continue;
				} else messageSegment = {
					type: OB11MessageDataType.Reply,
					data: { id: ctx.store.createMsgShortId(replyMsg).toString() }
				};
			} catch (e) {
				ctx.logger.error("解析 reply 失败", e, replyElement, e.stack);
				continue;
			}
		} else if (element.picElement) {
			const { picElement } = element;
			const fileSize = picElement.fileSize.toString();
			messageSegment = {
				type: OB11MessageDataType.Image,
				data: {
					file: picElement.fileName,
					subType: picElement.picSubType,
					url: await ctx.ntFileApi.getImageUrl(picElement.originImageUrl, picElement.md5HexStr),
					file_size: fileSize
				}
			};
			ctx.store.addFileCache({
				msgTime: +message.msgTime,
				peerUid: message.peerUid,
				chatType: message.chatType,
				elementType: element.elementType,
				fileName: picElement.fileName,
				fileUuid: picElement.fileUuid,
				fileSize,
				md5HexStr: picElement.md5HexStr,
				originImageUrl: picElement.originImageUrl
			});
		} else if (element.videoElement) {
			const { videoElement } = element;
			const videoUrl = await ctx.ntFileApi.getVideoUrl(videoElement.fileUuid, message.chatType === ChatType.Group);
			const fileSize = videoElement.fileSize.toString();
			messageSegment = {
				type: OB11MessageDataType.Video,
				data: {
					file: videoElement.fileName,
					url: videoUrl || pathToFileURL(videoElement.filePath).href,
					path: videoElement.filePath,
					file_size: fileSize
				}
			};
			ctx.store.addFileCache({
				msgTime: +message.msgTime,
				peerUid: message.peerUid,
				chatType: message.chatType,
				elementType: element.elementType,
				fileName: videoElement.fileName,
				fileUuid: videoElement.fileUuid,
				fileSize,
				md5HexStr: videoElement.videoMd5
			});
		} else if (element.fileElement) {
			const { fileElement } = element;
			const fileSize = fileElement.fileSize.toString();
			messageSegment = {
				type: OB11MessageDataType.File,
				data: {
					file: fileElement.fileName,
					url: fileElement.filePath ? pathToFileURL(fileElement.filePath).href : "",
					file_id: fileElement.fileUuid,
					path: fileElement.filePath,
					file_size: fileSize
				}
			};
			ctx.store.addFileCache({
				msgTime: +message.msgTime,
				peerUid: message.peerUid,
				chatType: message.chatType,
				elementType: element.elementType,
				fileName: fileElement.fileName,
				fileUuid: fileElement.fileUuid,
				fileSize,
				md5HexStr: fileElement.fileMd5
			});
		} else if (element.pttElement) {
			const { pttElement } = element;
			const fileSize = pttElement.fileSize.toString();
			messageSegment = {
				type: OB11MessageDataType.Record,
				data: {
					file: pttElement.fileName,
					url: await ctx.ntFileApi.getPttUrl(pttElement.fileUuid, message.chatType === ChatType.Group),
					path: pttElement.filePath,
					file_size: fileSize
				}
			};
			ctx.store.addFileCache({
				msgTime: +message.msgTime,
				peerUid: message.peerUid,
				chatType: message.chatType,
				elementType: element.elementType,
				fileName: pttElement.fileName,
				fileUuid: pttElement.fileUuid,
				fileSize,
				md5HexStr: pttElement.md5HexStr
			});
		} else if (element.arkElement) {
			const { arkElement } = element;
			messageSegment = {
				type: OB11MessageDataType.Json,
				data: { data: arkElement.bytesData }
			};
		} else if (element.faceElement) {
			const { faceElement } = element;
			const { faceIndex, faceType } = faceElement;
			if (faceType === FaceType.Poke && faceIndex === 1) messageSegment = {
				type: OB11MessageDataType.Shake,
				data: {}
			};
			else if (faceIndex === FaceIndex.Dice) messageSegment = {
				type: OB11MessageDataType.Dice,
				data: { result: faceElement.resultId }
			};
			else if (faceIndex === FaceIndex.RPS) messageSegment = {
				type: OB11MessageDataType.Rps,
				data: { result: faceElement.resultId }
			};
			else messageSegment = {
				type: OB11MessageDataType.Face,
				data: {
					id: faceIndex.toString(),
					sub_type: faceType
				}
			};
		} else if (element.marketFaceElement) {
			const { marketFaceElement } = element;
			const { emojiId } = marketFaceElement;
			const url = `https://gxh.vip.qq.com/club/item/parcel/item/${emojiId.substring(0, 2)}/${emojiId}/raw300.gif`;
			messageSegment = {
				type: OB11MessageDataType.Mface,
				data: {
					summary: marketFaceElement.faceName,
					url,
					emoji_id: emojiId,
					emoji_package_id: marketFaceElement.emojiPackageId,
					key: marketFaceElement.key
				}
			};
		} else if (element.markdownElement) {
			const { markdownElement } = element;
			if (markdownElement?.content.startsWith("[闪传](")) {
				const mqqapiUrl = markdownElement?.content.substring(5, markdownElement?.content.length - 1);
				const urlJson = new URL(mqqapiUrl).searchParams.get("json");
				if (urlJson) {
					const jsonData = JSON.parse(urlJson);
					if (jsonData?.busId === "FlashTransfer") {
						const fileAttribute = (jsonData?.attributes?.attributes || []).find((a) => a.viewId === "file");
						if (fileAttribute) {
							const urlParams = new URL(fileAttribute.schema).searchParams;
							const fileSetId = urlParams.get("fileset_id") || "";
							const sceneType = urlParams.get("scene_type") || "";
							const title = (fileAttribute?.attributes || []).find((a) => a.viewId === "title")?.text;
							messageSegment = {
								type: OB11MessageDataType.FlashFile,
								data: {
									title,
									file_set_id: fileSetId,
									scene_type: +sceneType
								}
							};
						}
					}
				}
			} else messageSegment = {
				type: OB11MessageDataType.Markdown,
				data: { content: markdownElement.content }
			};
		} else if (element.multiForwardMsgElement) messageSegment = {
			type: OB11MessageDataType.Forward,
			data: { id: element.multiForwardMsgElement.resId }
		};
		else if (element.inlineKeyboardElement) messageSegment = {
			type: OB11MessageDataType.Keyboard,
			data: { rows: element.inlineKeyboardElement.rows.map((row) => ({ buttons: row.buttons.map((button) => ({
				id: button.id,
				render_data: {
					label: button.label,
					visited_label: button.visitedLabel,
					style: button.style
				},
				action: {
					type: button.type,
					permission: {
						type: button.permissionType,
						specify_role_ids: button.specifyRoleIds,
						specify_user_ids: button.specifyTinyids
					},
					unsupport_tips: button.unsupportTips,
					data: button.data,
					reply: button.isReply,
					enter: button.enter
				}
			})) })) }
		};
		if (messageSegment) {
			segments.push(messageSegment);
			cqCode += encodeCQCode(messageSegment);
		}
	}
	return {
		segments,
		cqCode
	};
}
//#endregion
//#region src/onebot11/entities.ts
var OB11Entities;
(function(_OB11Entities) {
	async function message(ctx, msg, config) {
		const selfUin = +selfInfo.uin;
		const msgShortId = ctx.store.createMsgShortId(msg);
		const { segments, cqCode } = await transformIncomingSegments$1(ctx, msg);
		const resMsg = {
			self_id: selfUin,
			user_id: msg.senderUin,
			time: msg.msgTime,
			message_id: msgShortId,
			message_seq: msg.msgSeq,
			message_type: msg.chatType === ChatType.Group ? "group" : "private",
			sender: {
				user_id: msg.senderUin,
				nickname: msg.sendNickName
			},
			raw_message: cqCode,
			font: 14,
			sub_type: "friend",
			message: config?.messageFormat === "string" ? cqCode : segments,
			message_format: config?.messageFormat === "string" ? "string" : "array",
			post_type: selfUin === msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
			getSummaryEventName() {
				return this.post_type + "." + this.message_type;
			}
		};
		if (!config || config.debug) {
			resMsg.raw = msg;
			resMsg.raw_pb = msg.rawPb ?? "";
		}
		if (msg.chatType === ChatType.Group) {
			resMsg.sub_type = "normal";
			resMsg.group_id = msg.peerUin;
			resMsg.group_name = msg.peerName;
			resMsg.sender.card = msg.sendMemberName;
			if (msg.peerUin !== 284840486) {
				resMsg.sender.role = groupMemberRole(msg.memberRole);
				try {
					const member = await ctx.ntGroupApi.getGroupMemberByUid(msg.peerUin, msg.senderUid, false);
					resMsg.sender.nickname = member.nick;
					resMsg.sender.level = member.level.toString();
					resMsg.sender.title = member.specialTitle;
				} catch {
					resMsg.sender.nickname = msg.sendMemberName || msg.sendNickName;
				}
			}
		} else if (msg.chatType === ChatType.C2C) {
			resMsg.sub_type = "friend";
			if (msg.senderUin === 1094950020) resMsg.sender.nickname = "QQ用户";
			else try {
				resMsg.sender.nickname = (await ctx.ntFriendApi.getFriendByUid(msg.senderUid, false)).nick;
			} catch {
				resMsg.sender.nickname = msg.sendNickName || msg.senderUin.toString();
			}
		} else if (msg.chatType === ChatType.TempC2CFromGroup) {
			resMsg.sub_type = "group";
			resMsg.temp_source = 0;
			if (msg.senderUin === 1094950020) resMsg.sender.nickname = "QQ用户";
			else resMsg.sender.nickname = (await ctx.ntUserApi.getUserByUid(msg.senderUid)).nick;
			resMsg.sender.group_id = msg.tempFromGroupCode;
		}
		return resMsg;
	}
	_OB11Entities.message = message;
	async function groupEvent(ctx, msg) {
		if (msg.chatType !== ChatType.Group) return;
		for (const element of msg.elements) if (element.fileElement) return new OB11GroupUploadNoticeEvent(msg.peerUin, msg.senderUin, {
			id: element.fileElement.fileUuid,
			name: element.fileElement.fileName,
			size: element.fileElement.fileSize,
			busid: element.fileElement.fileBizId
		});
	}
	_OB11Entities.groupEvent = groupEvent;
	function friend(raw) {
		return {
			user_id: raw.uin,
			nickname: raw.nick,
			remark: raw.remark,
			sex: sex(raw.gender),
			birthday_year: raw.birthdayYear,
			birthday_month: raw.birthdayMonth,
			birthday_day: raw.birthdayDay,
			age: raw.age,
			qid: raw.qid,
			long_nick: raw.bio
		};
	}
	_OB11Entities.friend = friend;
	function friends(raw) {
		return raw.map(friend);
	}
	_OB11Entities.friends = friends;
	function groupMemberRole(role) {
		if (role === GroupMemberRole.Owner) return OB11GroupMemberRole.Owner;
		if (role === GroupMemberRole.Admin) return OB11GroupMemberRole.Admin;
		return OB11GroupMemberRole.Member;
	}
	_OB11Entities.groupMemberRole = groupMemberRole;
	function sex(sex) {
		return {
			[Sex.Unknown]: OB11UserSex.Unknown,
			[Sex.Male]: OB11UserSex.Male,
			[Sex.Female]: OB11UserSex.Female,
			[Sex.Hidden]: OB11UserSex.Unknown
		}[sex] ?? OB11UserSex.Unknown;
	}
	_OB11Entities.sex = sex;
	function groupMember(groupId, member) {
		return {
			group_id: groupId,
			user_id: member.uin,
			nickname: member.nick,
			card: member.cardName,
			card_or_nickname: member.cardName || member.nick,
			sex: OB11UserSex.Unknown,
			age: 0,
			area: "",
			level: String(member.level),
			qq_level: 0,
			join_time: member.joinedAt,
			last_sent_time: member.lastSpokeAt,
			title_expire_time: 0,
			unfriendly: false,
			card_changeable: true,
			is_robot: [
				{
					minUin: 3328144510,
					maxUin: 3328144510
				},
				{
					minUin: 2854196301,
					maxUin: 2854216399
				},
				{
					minUin: 666e5,
					maxUin: 666e5
				},
				{
					minUin: 3889e6,
					maxUin: 3889999999
				},
				{
					minUin: 401e7,
					maxUin: 4019999999
				}
			].some((e) => member.uin >= e.minUin && member.uin <= e.maxUin),
			shut_up_timestamp: member.shutupExpireTime,
			role: groupMemberRole(member.role),
			title: member.specialTitle
		};
	}
	_OB11Entities.groupMember = groupMember;
})(OB11Entities || (OB11Entities = {}));
//#endregion
//#region src/onebot11/event/request/OB11GroupRequest.ts
var OB11GroupRequestAddEvent = class extends OB11BaseNoticeEvent {
	post_type = EventType.REQUEST;
	request_type = "group";
	sub_type;
	group_id;
	user_id;
	comment;
	flag;
	invitor_id;
	constructor(groupId, userId, flag, comment, invitorId = 0) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.comment = comment;
		this.flag = flag;
		this.sub_type = "add";
		this.invitor_id = invitorId;
	}
};
var OB11GroupRequestInviteBotEvent = class extends OB11BaseNoticeEvent {
	post_type = EventType.REQUEST;
	request_type = "group";
	sub_type;
	group_id;
	user_id;
	comment;
	flag;
	source_group_id;
	constructor(groupId, userId, flag, comment, sourceGroupId) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.comment = comment;
		this.flag = flag;
		this.sub_type = "invite";
		this.source_group_id = sourceGroupId;
	}
};
//#endregion
//#region src/onebot11/event/request/OB11FriendRequest.ts
var OB11FriendRequestEvent = class extends OB11BaseNoticeEvent {
	post_type = EventType.REQUEST;
	request_type = "friend";
	user_id;
	comment;
	flag;
	via;
	constructor(userId, comment, flag, via) {
		super();
		this.user_id = userId;
		this.comment = comment;
		this.flag = flag;
		this.via = via;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupDecreaseEvent.ts
var OB11GroupDecreaseEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_decrease";
	sub_type = "leave";
	operator_id;
	group_id;
	user_id;
	constructor(groupId, userId, operatorId, subType = "leave") {
		super();
		this.group_id = groupId;
		this.operator_id = operatorId;
		this.user_id = userId;
		this.sub_type = subType;
	}
};
//#endregion
//#region src/onebot11/action/OB11Response.ts
var OB11Response = class OB11Response {
	static res(data, status, retcode, message = "") {
		return {
			status,
			retcode,
			data,
			message,
			wording: message,
			echo: void 0
		};
	}
	static ok(data, echo) {
		const res = OB11Response.res(data, "ok", 0);
		if (!isNullable(echo)) res.echo = echo;
		return res;
	}
	static error(err, retcode, echo) {
		const res = OB11Response.res(null, "failed", retcode, err);
		if (!isNullable(echo)) res.echo = echo;
		return res;
	}
};
//#endregion
//#region src/onebot11/event/meta/OB11BaseMetaEvent.ts
var OB11BaseMetaEvent = class extends OB11BaseEvent {
	post_type = EventType.META;
};
//#endregion
//#region src/onebot11/event/meta/OB11LifeCycleEvent.ts
var LifeCycleSubType = /* @__PURE__ */ function(LifeCycleSubType) {
	LifeCycleSubType["ENABLE"] = "enable";
	LifeCycleSubType["DISABLE"] = "disable";
	LifeCycleSubType["CONNECT"] = "connect";
	return LifeCycleSubType;
}({});
var OB11LifeCycleEvent = class extends OB11BaseMetaEvent {
	meta_event_type = "lifecycle";
	sub_type;
	constructor(subType) {
		super();
		this.sub_type = subType;
	}
};
//#endregion
//#region src/onebot11/event/meta/OB11HeartbeatEvent.ts
var OB11HeartbeatEvent = class extends OB11BaseMetaEvent {
	meta_event_type = "heartbeat";
	status;
	interval;
	constructor(isOnline, isGood, interval) {
		super();
		this.interval = interval;
		this.status = {
			online: isOnline,
			good: isGood
		};
	}
};
//#endregion
//#region src/version.ts
var version$3 = "8.1.7";
//#endregion
//#region node_modules/sift/es5m/index.js
/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var extendStatics = function(d, b) {
	extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
		d.__proto__ = b;
	} || function(d, b) {
		for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
	};
	return extendStatics(d, b);
};
function __extends(d, b) {
	if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
	extendStatics(d, b);
	function __() {
		this.constructor = d;
	}
	d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var typeChecker = function(type) {
	var typeString = "[object " + type + "]";
	return function(value) {
		return getClassName(value) === typeString;
	};
};
var getClassName = function(value) {
	return Object.prototype.toString.call(value);
};
var comparable = function(value) {
	if (value instanceof Date) return value.getTime();
	else if (isArray(value)) return value.map(comparable);
	else if (value && typeof value.toJSON === "function") return value.toJSON();
	return value;
};
var coercePotentiallyNull = function(value) {
	return value == null ? null : value;
};
var isArray = typeChecker("Array");
var isObject$1 = typeChecker("Object");
var isFunction = typeChecker("Function");
var isProperty = function(item, key) {
	return item.hasOwnProperty(key) && !isFunction(item[key]);
};
var isVanillaObject = function(value) {
	return value && (value.constructor === Object || value.constructor === Array || value.constructor.toString() === "function Object() { [native code] }" || value.constructor.toString() === "function Array() { [native code] }") && !value.toJSON;
};
var equals = function(a, b) {
	if (a == null && a == b) return true;
	if (a === b) return true;
	if (Object.prototype.toString.call(a) !== Object.prototype.toString.call(b)) return false;
	if (isArray(a)) {
		if (a.length !== b.length) return false;
		for (var i = 0, length_1 = a.length; i < length_1; i++) if (!equals(a[i], b[i])) return false;
		return true;
	} else if (isObject$1(a)) {
		if (Object.keys(a).length !== Object.keys(b).length) return false;
		for (var key in a) if (!equals(a[key], b[key])) return false;
		return true;
	}
	return false;
};
/**
* Walks through each value given the context - used for nested operations. E.g:
* { "person.address": { $eq: "blarg" }}
*/
var walkKeyPathValues = function(item, keyPath, next, depth, key, owner) {
	var currentKey = keyPath[depth];
	if (isArray(item) && isNaN(Number(currentKey)) && !isProperty(item, currentKey)) {
		for (var i = 0, length_1 = item.length; i < length_1; i++) if (!walkKeyPathValues(item[i], keyPath, next, depth, i, item)) return false;
	}
	if (depth === keyPath.length || item == null) return next(item, key, owner, depth === 0, depth === keyPath.length);
	return walkKeyPathValues(item[currentKey], keyPath, next, depth + 1, currentKey, item);
};
var BaseOperation = function() {
	function BaseOperation(params, owneryQuery, options, name) {
		this.params = params;
		this.owneryQuery = owneryQuery;
		this.options = options;
		this.name = name;
		this.init();
	}
	BaseOperation.prototype.init = function() {};
	BaseOperation.prototype.reset = function() {
		this.done = false;
		this.keep = false;
	};
	return BaseOperation;
}();
var GroupOperation = function(_super) {
	__extends(GroupOperation, _super);
	function GroupOperation(params, owneryQuery, options, children) {
		var _this = _super.call(this, params, owneryQuery, options) || this;
		_this.children = children;
		return _this;
	}
	/**
	*/
	GroupOperation.prototype.reset = function() {
		this.keep = false;
		this.done = false;
		for (var i = 0, length_2 = this.children.length; i < length_2; i++) this.children[i].reset();
	};
	/**
	*/
	GroupOperation.prototype.childrenNext = function(item, key, owner, root, leaf) {
		var done = true;
		var keep = true;
		for (var i = 0, length_3 = this.children.length; i < length_3; i++) {
			var childOperation = this.children[i];
			if (!childOperation.done) childOperation.next(item, key, owner, root, leaf);
			if (!childOperation.keep) keep = false;
			if (childOperation.done) {
				if (!childOperation.keep) break;
			} else done = false;
		}
		this.done = done;
		this.keep = keep;
	};
	return GroupOperation;
}(BaseOperation);
var NamedGroupOperation = function(_super) {
	__extends(NamedGroupOperation, _super);
	function NamedGroupOperation(params, owneryQuery, options, children, name) {
		var _this = _super.call(this, params, owneryQuery, options, children) || this;
		_this.name = name;
		return _this;
	}
	return NamedGroupOperation;
}(GroupOperation);
var QueryOperation = function(_super) {
	__extends(QueryOperation, _super);
	function QueryOperation() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	/**
	*/
	QueryOperation.prototype.next = function(item, key, parent, root) {
		this.childrenNext(item, key, parent, root);
	};
	return QueryOperation;
}(GroupOperation);
var NestedOperation = function(_super) {
	__extends(NestedOperation, _super);
	function NestedOperation(keyPath, params, owneryQuery, options, children) {
		var _this = _super.call(this, params, owneryQuery, options, children) || this;
		_this.keyPath = keyPath;
		_this.propop = true;
		/**
		*/
		_this._nextNestedValue = function(value, key, owner, root, leaf) {
			_this.childrenNext(value, key, owner, root, leaf);
			return !_this.done;
		};
		return _this;
	}
	/**
	*/
	NestedOperation.prototype.next = function(item, key, parent) {
		walkKeyPathValues(item, this.keyPath, this._nextNestedValue, 0, key, parent);
	};
	return NestedOperation;
}(GroupOperation);
var createTester = function(a, compare) {
	if (a instanceof Function) return a;
	if (a instanceof RegExp) return function(b) {
		var result = typeof b === "string" && a.test(b);
		a.lastIndex = 0;
		return result;
	};
	var comparableA = comparable(a);
	return function(b) {
		return compare(comparableA, comparable(b));
	};
};
var EqualsOperation = function(_super) {
	__extends(EqualsOperation, _super);
	function EqualsOperation() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	EqualsOperation.prototype.init = function() {
		this._test = createTester(this.params, this.options.compare);
	};
	EqualsOperation.prototype.next = function(item, key, parent) {
		if (!Array.isArray(parent) || parent.hasOwnProperty(key)) {
			if (this._test(item, key, parent)) {
				this.done = true;
				this.keep = true;
			}
		}
	};
	return EqualsOperation;
}(BaseOperation);
var numericalOperationCreator = function(createNumericalOperation) {
	return function(params, owneryQuery, options, name) {
		return createNumericalOperation(params, owneryQuery, options, name);
	};
};
var numericalOperation = function(createTester) {
	return numericalOperationCreator(function(params, owneryQuery, options, name) {
		var typeofParams = typeof comparable(params);
		var test = createTester(params);
		return new EqualsOperation(function(b) {
			var actualValue = coercePotentiallyNull(b);
			return typeof comparable(actualValue) === typeofParams && test(actualValue);
		}, owneryQuery, options, name);
	});
};
var createNamedOperation = function(name, params, parentQuery, options) {
	var operationCreator = options.operations[name];
	if (!operationCreator) throwUnsupportedOperation(name);
	return operationCreator(params, parentQuery, options, name);
};
var throwUnsupportedOperation = function(name) {
	throw new Error("Unsupported operation: ".concat(name));
};
var containsOperation = function(query, options) {
	for (var key in query) if (options.operations.hasOwnProperty(key) || key.charAt(0) === "$") return true;
	return false;
};
var createNestedOperation = function(keyPath, nestedQuery, parentKey, owneryQuery, options) {
	if (containsOperation(nestedQuery, options)) {
		var _a = createQueryOperations(nestedQuery, parentKey, options), selfOperations = _a[0];
		if (_a[1].length) throw new Error("Property queries must contain only operations, or exact objects.");
		return new NestedOperation(keyPath, nestedQuery, owneryQuery, options, selfOperations);
	}
	return new NestedOperation(keyPath, nestedQuery, owneryQuery, options, [new EqualsOperation(nestedQuery, owneryQuery, options)]);
};
var createQueryOperation = function(query, owneryQuery, _a) {
	if (owneryQuery === void 0) owneryQuery = null;
	var _b = _a === void 0 ? {} : _a, compare = _b.compare, operations = _b.operations;
	var options = {
		compare: compare || equals,
		operations: Object.assign({}, operations || {})
	};
	var _c = createQueryOperations(query, null, options), selfOperations = _c[0], nestedOperations = _c[1];
	var ops = [];
	if (selfOperations.length) ops.push(new NestedOperation([], query, owneryQuery, options, selfOperations));
	ops.push.apply(ops, nestedOperations);
	if (ops.length === 1) return ops[0];
	return new QueryOperation(query, owneryQuery, options, ops);
};
var createQueryOperations = function(query, parentKey, options) {
	var selfOperations = [];
	var nestedOperations = [];
	if (!isVanillaObject(query)) {
		selfOperations.push(new EqualsOperation(query, query, options));
		return [selfOperations, nestedOperations];
	}
	for (var key in query) if (options.operations.hasOwnProperty(key)) {
		var op = createNamedOperation(key, query[key], query, options);
		if (op) {
			if (!op.propop && parentKey && !options.operations[parentKey]) throw new Error("Malformed query. ".concat(key, " cannot be matched against property."));
		}
		if (op != null) selfOperations.push(op);
	} else if (key.charAt(0) === "$") throwUnsupportedOperation(key);
	else nestedOperations.push(createNestedOperation(key.split("."), query[key], key, query, options));
	return [selfOperations, nestedOperations];
};
var createOperationTester = function(operation) {
	return function(item, key, owner) {
		operation.reset();
		operation.next(item, key, owner);
		return operation.keep;
	};
};
var $Ne = function(_super) {
	__extends($Ne, _super);
	function $Ne() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$Ne.prototype.init = function() {
		this._test = createTester(this.params, this.options.compare);
	};
	$Ne.prototype.reset = function() {
		_super.prototype.reset.call(this);
		this.keep = true;
	};
	$Ne.prototype.next = function(item) {
		if (this._test(item)) {
			this.done = true;
			this.keep = false;
		}
	};
	return $Ne;
}(BaseOperation);
var $ElemMatch = function(_super) {
	__extends($ElemMatch, _super);
	function $ElemMatch() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$ElemMatch.prototype.init = function() {
		if (!this.params || typeof this.params !== "object") throw new Error("Malformed query. $elemMatch must by an object.");
		this._queryOperation = createQueryOperation(this.params, this.owneryQuery, this.options);
	};
	$ElemMatch.prototype.reset = function() {
		_super.prototype.reset.call(this);
		this._queryOperation.reset();
	};
	$ElemMatch.prototype.next = function(item) {
		if (isArray(item)) {
			for (var i = 0, length_1 = item.length; i < length_1; i++) {
				this._queryOperation.reset();
				var child = item[i];
				this._queryOperation.next(child, i, item, false);
				this.keep = this.keep || this._queryOperation.keep;
			}
			this.done = true;
		} else {
			this.done = false;
			this.keep = false;
		}
	};
	return $ElemMatch;
}(BaseOperation);
var $Not = function(_super) {
	__extends($Not, _super);
	function $Not() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$Not.prototype.init = function() {
		this._queryOperation = createQueryOperation(this.params, this.owneryQuery, this.options);
	};
	$Not.prototype.reset = function() {
		_super.prototype.reset.call(this);
		this._queryOperation.reset();
	};
	$Not.prototype.next = function(item, key, owner, root) {
		this._queryOperation.next(item, key, owner, root);
		this.done = this._queryOperation.done;
		this.keep = !this._queryOperation.keep;
	};
	return $Not;
}(BaseOperation);
var $Size = function(_super) {
	__extends($Size, _super);
	function $Size() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$Size.prototype.init = function() {};
	$Size.prototype.next = function(item) {
		if (isArray(item) && item.length === this.params) {
			this.done = true;
			this.keep = true;
		}
	};
	return $Size;
}(BaseOperation);
var assertGroupNotEmpty = function(values) {
	if (values.length === 0) throw new Error("$and/$or/$nor must be a nonempty array");
};
var $Or = function(_super) {
	__extends($Or, _super);
	function $Or() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = false;
		return _this;
	}
	$Or.prototype.init = function() {
		var _this = this;
		assertGroupNotEmpty(this.params);
		this._ops = this.params.map(function(op) {
			return createQueryOperation(op, null, _this.options);
		});
	};
	$Or.prototype.reset = function() {
		this.done = false;
		this.keep = false;
		for (var i = 0, length_2 = this._ops.length; i < length_2; i++) this._ops[i].reset();
	};
	$Or.prototype.next = function(item, key, owner) {
		var done = false;
		var success = false;
		for (var i = 0, length_3 = this._ops.length; i < length_3; i++) {
			var op = this._ops[i];
			op.next(item, key, owner);
			if (op.keep) {
				done = true;
				success = op.keep;
				break;
			}
		}
		this.keep = success;
		this.done = done;
	};
	return $Or;
}(BaseOperation);
var $Nor = function(_super) {
	__extends($Nor, _super);
	function $Nor() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = false;
		return _this;
	}
	$Nor.prototype.next = function(item, key, owner) {
		_super.prototype.next.call(this, item, key, owner);
		this.keep = !this.keep;
	};
	return $Nor;
}($Or);
var $In = function(_super) {
	__extends($In, _super);
	function $In() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$In.prototype.init = function() {
		var _this = this;
		var params = Array.isArray(this.params) ? this.params : [this.params];
		this._testers = params.map(function(value) {
			if (containsOperation(value, _this.options)) throw new Error("cannot nest $ under ".concat(_this.name.toLowerCase()));
			return createTester(value, _this.options.compare);
		});
	};
	$In.prototype.next = function(item, key, owner) {
		var done = false;
		var success = false;
		for (var i = 0, length_4 = this._testers.length; i < length_4; i++) {
			var test = this._testers[i];
			if (test(item)) {
				done = true;
				success = true;
				break;
			}
		}
		this.keep = success;
		this.done = done;
	};
	return $In;
}(BaseOperation);
var $Nin = function(_super) {
	__extends($Nin, _super);
	function $Nin(params, ownerQuery, options, name) {
		var _this = _super.call(this, params, ownerQuery, options, name) || this;
		_this.propop = true;
		_this._in = new $In(params, ownerQuery, options, name);
		return _this;
	}
	$Nin.prototype.next = function(item, key, owner, root) {
		this._in.next(item, key, owner);
		if (isArray(owner) && !root) {
			if (this._in.keep) {
				this.keep = false;
				this.done = true;
			} else if (key == owner.length - 1) {
				this.keep = true;
				this.done = true;
			}
		} else {
			this.keep = !this._in.keep;
			this.done = true;
		}
	};
	$Nin.prototype.reset = function() {
		_super.prototype.reset.call(this);
		this._in.reset();
	};
	return $Nin;
}(BaseOperation);
var $Exists = function(_super) {
	__extends($Exists, _super);
	function $Exists() {
		var _this = _super !== null && _super.apply(this, arguments) || this;
		_this.propop = true;
		return _this;
	}
	$Exists.prototype.next = function(item, key, owner, root, leaf) {
		if (!leaf) {
			this.done = true;
			this.keep = !this.params;
		} else if (owner.hasOwnProperty(key) === this.params) {
			this.done = true;
			this.keep = true;
		}
	};
	return $Exists;
}(BaseOperation);
var $And = function(_super) {
	__extends($And, _super);
	function $And(params, owneryQuery, options, name) {
		var _this = _super.call(this, params, owneryQuery, options, params.map(function(query) {
			return createQueryOperation(query, owneryQuery, options);
		}), name) || this;
		_this.propop = false;
		assertGroupNotEmpty(params);
		return _this;
	}
	$And.prototype.next = function(item, key, owner, root) {
		this.childrenNext(item, key, owner, root);
	};
	return $And;
}(NamedGroupOperation);
var $All = function(_super) {
	__extends($All, _super);
	function $All(params, owneryQuery, options, name) {
		var _this = _super.call(this, params, owneryQuery, options, params.map(function(query) {
			return createQueryOperation(query, owneryQuery, options);
		}), name) || this;
		_this.propop = true;
		return _this;
	}
	$All.prototype.next = function(item, key, owner, root) {
		this.childrenNext(item, key, owner, root);
	};
	return $All;
}(NamedGroupOperation);
var $eq = function(params, owneryQuery, options) {
	return new EqualsOperation(params, owneryQuery, options);
};
var $ne = function(params, owneryQuery, options, name) {
	return new $Ne(params, owneryQuery, options, name);
};
var $or = function(params, owneryQuery, options, name) {
	return new $Or(params, owneryQuery, options, name);
};
var $nor = function(params, owneryQuery, options, name) {
	return new $Nor(params, owneryQuery, options, name);
};
var $elemMatch = function(params, owneryQuery, options, name) {
	return new $ElemMatch(params, owneryQuery, options, name);
};
var $nin = function(params, owneryQuery, options, name) {
	return new $Nin(params, owneryQuery, options, name);
};
var $in = function(params, owneryQuery, options, name) {
	return new $In(params, owneryQuery, options, name);
};
var $lt = numericalOperation(function(params) {
	return function(b) {
		return b != null && b < params;
	};
});
var $lte = numericalOperation(function(params) {
	return function(b) {
		return b === params || b <= params;
	};
});
var $gt = numericalOperation(function(params) {
	return function(b) {
		return b != null && b > params;
	};
});
var $gte = numericalOperation(function(params) {
	return function(b) {
		return b === params || b >= params;
	};
});
var $mod = function(_a, owneryQuery, options) {
	var mod = _a[0], equalsValue = _a[1];
	return new EqualsOperation(function(b) {
		return comparable(b) % mod === equalsValue;
	}, owneryQuery, options);
};
var $exists = function(params, owneryQuery, options, name) {
	return new $Exists(params, owneryQuery, options, name);
};
var $regex = function(pattern, owneryQuery, options) {
	return new EqualsOperation(new RegExp(pattern, owneryQuery.$options), owneryQuery, options);
};
var $not = function(params, owneryQuery, options, name) {
	return new $Not(params, owneryQuery, options, name);
};
var typeAliases = {
	number: function(v) {
		return typeof v === "number";
	},
	string: function(v) {
		return typeof v === "string";
	},
	bool: function(v) {
		return typeof v === "boolean";
	},
	array: function(v) {
		return Array.isArray(v);
	},
	null: function(v) {
		return v === null;
	},
	timestamp: function(v) {
		return v instanceof Date;
	}
};
var $type = function(clazz, owneryQuery, options) {
	return new EqualsOperation(function(b) {
		if (typeof clazz === "string") {
			if (!typeAliases[clazz]) throw new Error("Type alias does not exist");
			return typeAliases[clazz](b);
		}
		return b != null ? b instanceof clazz || b.constructor === clazz : false;
	}, owneryQuery, options);
};
var $and = function(params, ownerQuery, options, name) {
	return new $And(params, ownerQuery, options, name);
};
var $all = function(params, ownerQuery, options, name) {
	return new $All(params, ownerQuery, options, name);
};
var $size = function(params, ownerQuery, options) {
	return new $Size(params, ownerQuery, options, "$size");
};
var $options = function() {
	return null;
};
var $where = function(params, ownerQuery, options) {
	var test;
	if (isFunction(params)) test = params;
	else if (!process.env.CSP_ENABLED) test = new Function("obj", "return " + params);
	else throw new Error("In CSP mode, sift does not support strings in \"$where\" condition");
	return new EqualsOperation(function(b) {
		return test.bind(b)(b);
	}, ownerQuery, options);
};
var defaultOperations = /*#__PURE__*/ Object.freeze({
	__proto__: null,
	$Size,
	$all,
	$and,
	$elemMatch,
	$eq,
	$exists,
	$gt,
	$gte,
	$in,
	$lt,
	$lte,
	$mod,
	$ne,
	$nin,
	$nor,
	$not,
	$options,
	$or,
	$regex,
	$size,
	$type,
	$where
});
var createDefaultQueryOperation = function(query, ownerQuery, _a) {
	var _b = _a === void 0 ? {} : _a, compare = _b.compare, operations = _b.operations;
	return createQueryOperation(query, ownerQuery, {
		compare,
		operations: Object.assign({}, defaultOperations, operations || {})
	});
};
var createDefaultQueryTester = function(query, options) {
	if (options === void 0) options = {};
	return createOperationTester(createDefaultQueryOperation(query, null, options));
};
//#endregion
//#region src/onebot11/eventfilter.ts
function matchEventFilter(filter, event) {
	if (filter === void 0 || filter === null) return true;
	try {
		return createDefaultQueryTester(filter)(event);
	} catch {
		return false;
	}
}
//#endregion
//#region src/onebot11/connect/ws.ts
function toBuffer(data) {
	if (Buffer.isBuffer(data)) return data;
	if (Array.isArray(data)) return Buffer.concat(data);
	return Buffer.from(data);
}
function extractEcho(buf) {
	const key = [
		34,
		101,
		99,
		104,
		111,
		34
	];
	const len = buf.length;
	let keyIdx = -1;
	outer: for (let i = 0; i <= len - key.length; i++) {
		for (let k = 0; k < key.length; k++) if (buf[i + k] !== key[k]) continue outer;
		keyIdx = i;
		break;
	}
	if (keyIdx < 0) return void 0;
	let i = keyIdx + key.length;
	while (i < len) {
		const b = buf[i];
		if (b !== 32 && b !== 9 && b !== 10 && b !== 13) break;
		i++;
	}
	if (buf[i] !== 58) return void 0;
	i++;
	while (i < len) {
		const b = buf[i];
		if (b !== 32 && b !== 9 && b !== 10 && b !== 13) break;
		i++;
	}
	if (i >= len) return void 0;
	const start = i;
	const first = buf[i];
	let end = start;
	if (first === 34) {
		i++;
		while (i < len) {
			const b = buf[i];
			if (b === 92) {
				i += 2;
				continue;
			}
			if (b === 34) {
				i++;
				break;
			}
			i++;
		}
		end = i;
	} else if (first === 123 || first === 91) {
		const open = first;
		const close = open === 123 ? 125 : 93;
		let depth = 0;
		let inStr = false;
		while (i < len) {
			const b = buf[i];
			if (inStr) {
				if (b === 92) {
					i += 2;
					continue;
				}
				if (b === 34) inStr = false;
				i++;
				continue;
			}
			if (b === 34) inStr = true;
			else if (b === open) depth++;
			else if (b === close) {
				depth--;
				if (depth === 0) {
					i++;
					break;
				}
			}
			i++;
		}
		end = i;
	} else {
		while (i < len) {
			const b = buf[i];
			if (b === 44 || b === 125 || b === 93 || b === 32 || b === 9 || b === 10 || b === 13) break;
			i++;
		}
		end = i;
	}
	if (end <= start) return void 0;
	const slice = buf.subarray(start, end).toString("utf8").trim();
	if (!slice) return void 0;
	try {
		return JSON.parse(slice);
	} catch {
		return;
	}
}
var OB11WebSocket = class {
	ctx;
	config;
	wsServer;
	wsClients = [];
	activated = false;
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		if (this.wsServer || !this.config.enable) return;
		const host = this.config.host;
		this.ctx.logger.info(`OneBot V11 WebSocket server started ${host}:${this.config.port}`);
		this.wsServer = new WebSocketServer({
			host,
			port: this.config.port,
			maxPayload: 0
		});
		this.wsServer.on("error", (err) => {
			this.ctx.logger.error("OneBot V11 正向 WS 错误", err);
		});
		this.wsServer?.on("connection", (socket, req) => {
			if (this.authorize(socket, req)) {
				this.connect(socket, req);
				const url = req.url?.split("?").shift();
				this.ctx.logger.info("ws connect", url);
			} else {
				this.reply(socket, OB11Response.res(null, "failed", 1403, "token验证失败"));
				socket.close(1008, "invalid access token");
				const url = req.url?.split("?").shift();
				this.ctx.logger.info("ws authentication failed", url);
			}
		});
		this.activated = true;
	}
	stop() {
		return new Promise((resolve) => {
			this.ctx.logger.info("OneBot V11 WebSocket Server closing...");
			this.wsClients.forEach(({ socket }) => {
				try {
					socket.close();
				} catch (e) {
					this.ctx.logger.error("关闭 OneBot V11 WebSocket 客户端连接失败", e);
				}
			});
			this.wsClients = [];
			if (this.wsServer) {
				this.wsServer.close((err) => {
					if (err) {
						this.ctx.logger.error(`OneBot V11 WebSocket Server closing ${err}`);
						return resolve(false);
					}
					this.ctx.logger.info("OneBot V11 WebSocket Server closed");
					resolve(true);
				});
				this.wsServer = void 0;
			} else resolve(true);
			this.activated = false;
		});
	}
	async emitEvent(event) {
		if (!matchEventFilter(this.config.filter, event)) return;
		if (!this.activated) return;
		this.wsClients.forEach(({ socket, emitEvent }) => {
			if (emitEvent && socket.readyState === WebSocket$1.OPEN) {
				socket.send(JSON.stringify(event));
				const eventName = event.getSummaryEventName();
				this.ctx.logger.info("WebSocket 事件上报", eventName);
			}
		});
	}
	async emitMessageLikeEvent(event, self, offline) {
		if (self && !this.config.reportSelfMessage) return;
		if (offline && !this.config.reportOfflineMessage) return;
		if (event.post_type === "message" || event.post_type === "message_sent") {
			const msg = event;
			if (!this.config.debug && msg.message.length === 0) return;
			if (!this.config.debug) {
				delete msg.raw;
				delete msg.raw_pb;
			}
			if (this.config.messageFormat === "string") {
				msg.message = msg.raw_message;
				msg.message_format = "string";
			}
		}
		await this.emitEvent(event);
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
	reply(socket, data) {
		if (socket.readyState !== WebSocket$1.OPEN) return;
		socket.send(JSON.stringify(data));
		if ("post_type" in data) this.ctx.logger.info("WebSocket 事件上报", data.post_type);
	}
	authorize(socket, req) {
		if (this.config.token) {
			let clientToken = "";
			const authHeader = req.headers["authorization"];
			if (authHeader) {
				clientToken = authHeader.split("Bearer ").pop();
				this.ctx.logger.info("receive ws header token", clientToken);
			} else {
				const { searchParams } = new URL(`http://localhost${req.url}`);
				const urlToken = searchParams.get("access_token");
				if (urlToken) {
					clientToken = urlToken;
					this.ctx.logger.info("receive ws url token", clientToken);
				}
			}
			if (clientToken !== this.config.token) return false;
		}
		return true;
	}
	async handleAction(socket, data) {
		let receive = {
			action: null,
			params: {}
		};
		try {
			receive = JSON.parse(data.toString());
			this.ctx.logger.info("收到正向 Websocket 消息", receive);
		} catch (error) {
			const echo = extractEcho(toBuffer(data));
			const { message } = error;
			return this.reply(socket, OB11Response.error(`JSON 解析失败: ${message}`, 1400, echo));
		}
		const action = this.config.actionMap.get(receive.action);
		if (!action) return this.reply(socket, OB11Response.error(`${receive.action} API 不存在`, 1404, receive.echo));
		const handleResult = await action.websocketHandle(receive.params, receive.echo, {
			messageFormat: this.config.messageFormat,
			debug: this.config.debug
		});
		this.reply(socket, handleResult);
	}
	connect(socket, req) {
		const url = req.url?.split("?").shift();
		let disposeHeartBeat;
		if ([
			"/api",
			"/api/",
			"/",
			void 0
		].includes(url)) socket.on("message", (data) => {
			this.handleAction(socket, data);
		});
		if ([
			"/event",
			"/event/",
			"/",
			void 0
		].includes(url)) {
			try {
				this.reply(socket, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT));
			} catch (e) {
				this.ctx.logger.error("发送生命周期失败", e);
			}
			disposeHeartBeat = this.ctx.interval(() => {
				const event = new OB11HeartbeatEvent(selfInfo.online, true, this.config.heartInterval);
				this.reply(socket, event);
			}, this.config.heartInterval);
		}
		socket.on("close", () => {
			disposeHeartBeat?.();
			this.wsClients = this.wsClients.filter((c) => c.socket !== socket);
			this.ctx.logger.info("有一个 Websocket 连接断开");
		});
		socket.on("error", (err) => this.ctx.logger.error(err.message));
		socket.on("ping", () => {
			socket.pong();
		});
		this.wsClients.push({
			socket,
			emitEvent: [
				"/event",
				"/event/",
				"/",
				void 0
			].includes(url)
		});
	}
};
var OB11WebSocketReverse = class {
	ctx;
	config;
	activated = false;
	wsClient;
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		if (!this.config.enable) return;
		if (!this.activated) {
			this.activated = true;
			this.tryConnect();
		}
	}
	stop() {
		this.activated = false;
		this.wsClient?.close();
	}
	async emitEvent(event) {
		if (!matchEventFilter(this.config.filter, event)) return;
		if (!this.activated) return;
		if (this.wsClient && this.wsClient.readyState === WebSocket$1.OPEN) {
			this.wsClient.send(JSON.stringify(event));
			const eventName = event.getSummaryEventName();
			this.ctx.logger.info("WebSocket 事件上报", this.wsClient.url ?? "", eventName);
		}
	}
	async emitMessageLikeEvent(event, self, offline) {
		if (self && !this.config.reportSelfMessage) return;
		if (offline && !this.config.reportOfflineMessage) return;
		if (event.post_type === "message" || event.post_type === "message_sent") {
			const msg = event;
			if (!this.config.debug && msg.message.length === 0) return;
			if (!this.config.debug) {
				delete msg.raw;
				delete msg.raw_pb;
			}
			if (this.config.messageFormat === "string") {
				msg.message = msg.raw_message;
				msg.message_format = "string";
			}
		}
		await this.emitEvent(event);
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
	reply(socket, data) {
		if (socket.readyState !== WebSocket$1.OPEN) return;
		socket.send(JSON.stringify(data));
		if ("post_type" in data) this.ctx.logger.info("WebSocket 事件上报", socket.url ?? "", data.post_type);
	}
	async handleAction(data) {
		let receive = {
			action: null,
			params: {}
		};
		try {
			receive = JSON.parse(data.toString());
			this.ctx.logger.info("收到反向 Websocket 消息", receive);
		} catch (error) {
			const echo = extractEcho(toBuffer(data));
			const { message } = error;
			return this.reply(this.wsClient, OB11Response.error(`JSON 解析失败: ${message}`, 1400, echo));
		}
		const action = this.config.actionMap.get(receive.action);
		if (!action) return this.reply(this.wsClient, OB11Response.error(`${receive.action} API 不存在`, 1404, receive.echo));
		const handleResult = await action.websocketHandle(receive.params, receive.echo, {
			messageFormat: this.config.messageFormat,
			debug: this.config.debug
		});
		this.reply(this.wsClient, handleResult);
	}
	tryConnect() {
		if (this.wsClient && !this.activated) return;
		this.wsClient = new WebSocket$1(this.config.url, {
			maxPayload: 0,
			handshakeTimeout: 2e3,
			perMessageDeflate: false,
			headers: {
				"X-Self-ID": selfInfo.uin,
				"Authorization": `Bearer ${this.config.token}`,
				"x-client-role": "Universal",
				"User-Agent": `LLOneBot/${version$3}`
			}
		});
		this.ctx.logger.info("Trying to connect to the websocket server: " + this.config.url);
		this.wsClient.on("open", () => {
			this.ctx.logger.info("Connected to the websocket server: " + this.config.url);
			try {
				this.reply(this.wsClient, new OB11LifeCycleEvent(LifeCycleSubType.CONNECT));
			} catch (e) {
				this.ctx.logger.error("发送生命周期失败", e);
			}
		});
		this.wsClient.on("error", (err) => this.ctx.logger.error(err));
		this.wsClient.on("message", (data) => {
			this.handleAction(data);
		});
		this.wsClient.on("ping", () => {
			this.wsClient?.pong();
		});
		const disposeHeartBeat = this.ctx.interval(() => {
			if (this.wsClient) {
				const event = new OB11HeartbeatEvent(selfInfo.online, true, this.config.heartInterval);
				this.reply(this.wsClient, event);
			}
		}, this.config.heartInterval);
		this.wsClient.on("close", (code) => {
			disposeHeartBeat();
			this.ctx.logger.info(`The websocket connection: ${this.config.url} closed, code ${code}${this.activated ? ", trying reconnecting..." : ""}`);
			if (this.activated) this.ctx.timeout(() => this.tryConnect(), 3e3);
		});
	}
};
//#endregion
//#region src/ntqqapi/entities.ts
var SendElement;
(function(_SendElement) {
	function text(content) {
		return {
			elementType: ElementType.Text,
			textElement: {
				content,
				atType: AtType.Unknown,
				atUin: 0
			}
		};
	}
	_SendElement.text = text;
	function at(atUin, atType, display) {
		return {
			elementType: ElementType.Text,
			textElement: {
				content: display,
				atType,
				atUin
			}
		};
	}
	_SendElement.at = at;
	function reply(msgSeq, senderUin, senderUid, msgTime, clientSeq, srcMsg) {
		return {
			elementType: ElementType.Reply,
			replyElement: {
				replyMsgSeq: msgSeq,
				senderUin,
				senderUid,
				replyMsgTime: msgTime,
				replyMsgClientSeq: clientSeq,
				srcMsg
			}
		};
	}
	_SendElement.reply = reply;
	async function pic(ctx, picPath, summary = "", subType = 0) {
		if ((await stat$1(picPath)).size === 0) throw new Error(`文件异常，大小为 0: ${picPath}`);
		const size = await getImageSize(picPath);
		return {
			elementType: ElementType.Pic,
			picElement: {
				picWidth: size.width,
				picHeight: size.height,
				sourcePath: picPath,
				picSubType: subType,
				summary
			}
		};
	}
	_SendElement.pic = pic;
	async function video(ctx, filePath, diyThumbPath) {
		const fileSize = (await stat$1(filePath)).size;
		if (fileSize === 0) throw new Error(`文件异常，大小为 0: ${filePath}`);
		const maxMB = 1024;
		if (fileSize > 1048576 * maxMB) throw new Error(`视频过大，最大支持${maxMB}MB，当前文件大小${fileSize}B`);
		let videoInfo = {
			width: 1920,
			height: 1080,
			time: 15,
			format: "mp4",
			size: fileSize,
			filePath
		};
		try {
			videoInfo = await getVideoInfo(filePath);
			ctx.logger.info("视频信息", videoInfo);
		} catch (e) {
			ctx.logger.info("获取视频信息失败", e);
		}
		const md5 = await getMd5HexFromFile(filePath);
		const thumbDir = TEMP_DIR;
		const thumbFilePath = path.join(thumbDir, `${md5}_0.png`);
		await mkdir(thumbDir, { recursive: true });
		if (diyThumbPath) await copyFile(diyThumbPath, thumbFilePath);
		else {
			const path = await createThumb(ctx, videoInfo.filePath);
			await copyFile(path, thumbFilePath);
			unlink(path).catch(noop);
		}
		const element = {
			elementType: ElementType.Video,
			videoElement: {
				filePath,
				fileTime: Math.trunc(videoInfo.time),
				thumbPath: thumbFilePath,
				thumbWidth: videoInfo.width,
				thumbHeight: videoInfo.height
			}
		};
		ctx.logger.info("videoElement", element);
		return element;
	}
	_SendElement.video = video;
	async function ptt(ctx, pttPath) {
		const { converted, path: silkPath, duration } = await encodeSilk(ctx, pttPath);
		if ((await stat$1(silkPath)).size === 0) throw new Error(`文件异常，大小为 0: ${silkPath}`);
		return {
			elementType: ElementType.Ptt,
			pttElement: {
				filePath: silkPath,
				duration
			}
		};
	}
	_SendElement.ptt = ptt;
	function face(faceId, faceType) {
		const face = face_config_default.sysface.find((face) => face.QSid === String(faceId));
		if (!faceType) {
			if (faceId < 222) faceType = 1;
			else if (faceId < 1e5) faceType = 2;
			else faceType = 4;
			if (face?.AniStickerType) faceType = 3;
		}
		return {
			elementType: ElementType.Face,
			faceElement: {
				faceIndex: faceId,
				faceType,
				faceText: face?.QDes ?? "",
				stickerId: face?.AniStickerId,
				stickerType: face?.AniStickerType,
				packId: face?.AniStickerPackId
			}
		};
	}
	_SendElement.face = face;
	function mface(emojiPackageId, emojiId, key, summary) {
		return {
			elementType: ElementType.MarketFace,
			marketFaceElement: {
				imageWidth: 300,
				imageHeight: 300,
				emojiPackageId,
				emojiId,
				key,
				faceName: summary || "[商城表情]"
			}
		};
	}
	_SendElement.mface = mface;
	function dice(resultId) {
		if (isNullable(resultId)) resultId = Math.floor(Math.random() * 6) + 1;
		return {
			elementType: ElementType.Face,
			faceElement: {
				faceIndex: FaceIndex.Dice,
				faceType: 3,
				faceText: "[骰子]",
				packId: "1",
				stickerId: "33",
				stickerType: 2,
				resultId: resultId.toString()
			}
		};
	}
	_SendElement.dice = dice;
	function rps(resultId) {
		if (isNullable(resultId)) resultId = Math.floor(Math.random() * 3) + 1;
		return {
			elementType: ElementType.Face,
			faceElement: {
				faceIndex: FaceIndex.RPS,
				faceText: "[包剪锤]",
				faceType: 3,
				packId: "1",
				stickerId: "34",
				stickerType: 2,
				resultId: resultId.toString()
			}
		};
	}
	_SendElement.rps = rps;
	function ark(data) {
		return {
			elementType: ElementType.Ark,
			arkElement: { bytesData: data }
		};
	}
	_SendElement.ark = ark;
	function shake() {
		return {
			elementType: ElementType.Face,
			faceElement: {
				faceIndex: 1,
				faceType: 5,
				faceText: "",
				pokeType: 1
			}
		};
	}
	_SendElement.shake = shake;
	function forward(nodes, title, preview, summary, prompt) {
		return {
			elementType: ElementType.MultiForward,
			multiForwardMsgElement: {
				nodes,
				title,
				preview,
				summary,
				prompt
			}
		};
	}
	_SendElement.forward = forward;
	async function file(ctx, filePath, fileName) {
		const fileSize = (await stat$1(filePath)).size;
		if (fileSize === 0) throw new Error("文件异常，大小为 0");
		return {
			elementType: ElementType.File,
			fileElement: {
				fileName,
				filePath,
				fileSize
			}
		};
	}
	_SendElement.file = file;
})(SendElement || (SendElement = {}));
//#endregion
//#region src/common/utils/sign.ts
var MusicSign = class {
	ctx;
	url;
	constructor(ctx, url) {
		this.ctx = ctx;
		this.url = url;
	}
	async sign(postData) {
		const resp = await fetch(this.url, {
			method: "POST",
			headers: { "Content-Type": "application/json" },
			body: JSON.stringify(postData)
		});
		const data = await resp.text();
		if (!resp.ok) throw new Error(data);
		this.ctx.logger.info("音乐消息生成成功", data);
		return data;
	}
};
//#endregion
//#region src/onebot11/utils.ts
var CreatePeerMode = /* @__PURE__ */ function(CreatePeerMode) {
	CreatePeerMode[CreatePeerMode["Normal"] = 0] = "Normal";
	CreatePeerMode[CreatePeerMode["Private"] = 1] = "Private";
	CreatePeerMode[CreatePeerMode["Group"] = 2] = "Group";
	return CreatePeerMode;
}({});
async function createPeer(ctx, payload, mode = 0) {
	if ((mode === 2 || mode === 0) && payload.group_id) return {
		chatType: ChatType.Group,
		peerUid: payload.group_id.toString()
	};
	if ((mode === 1 || mode === 0) && payload.user_id) {
		const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id, payload.group_id ? +payload.group_id : void 0);
		if (!uid) throw new Error("无法获取用户信息");
		if (!await ctx.ntFriendApi.isFriend(uid)) return {
			chatType: ChatType.TempC2CFromGroup,
			peerUid: uid
		};
		return {
			chatType: ChatType.C2C,
			peerUid: uid
		};
	}
	throw new Error("请指定 group_id 或 user_id");
}
function message2List(message, autoEscape = false) {
	if (typeof message === "string") if (autoEscape === true) return [{
		type: OB11MessageDataType.Text,
		data: { text: message }
	}];
	else return decodeCQCode(message);
	else if (!Array.isArray(message)) return [message];
	return message;
}
function encodeGroupRequestFlag$2(groupCode, seq, type, doubt) {
	return `${groupCode}|${seq}|${type}|${doubt ? 1 : 0}`;
}
function decodeGroupRequestFlag$2(flag) {
	const flagitem = flag.split("|");
	return {
		groupCode: +flagitem[0],
		seq: +flagitem[1],
		type: +flagitem[2],
		doubt: flagitem[3] === "1"
	};
}
//#endregion
//#region src/onebot11/transform/message/outgoing.ts
async function transformOutgoingSegments(ctx, messageData, peer, isInsideForward) {
	const sendElements = [];
	const deleteAfterSentFiles = [];
	const nodes = [];
	for (const segment of messageData) switch (segment.type) {
		case OB11MessageDataType.Text:
			if (segment.data?.text) sendElements.push(SendElement.text(segment.data.text));
			break;
		case OB11MessageDataType.At:
			if (!peer) continue;
			if (segment.data?.qq) {
				if (segment.data.qq === "all") {
					const groupCode = peer.peerUid;
					let remainAtAllCount = 1;
					let isAdmin = true;
					if (groupCode) try {
						remainAtAllCount = (await ctx.ntGroupApi.getGroupRemainAtTimes(+groupCode)).remainAtAllCountForUin;
						ctx.logger.info(`群${groupCode}剩余at全体次数`, remainAtAllCount);
						const self = await ctx.ntGroupApi.getGroupMemberByUid(+groupCode, selfInfo.uid, false);
						isAdmin = self?.role === GroupMemberRole.Admin || self?.role === GroupMemberRole.Owner;
					} catch (e) {}
					if (isAdmin && remainAtAllCount > 0) sendElements.push(SendElement.at(0, AtType.All, "@全体成员"));
				} else if (peer.chatType === ChatType.Group) {
					const uin = +segment.data.qq;
					let display;
					if (segment.data.name) display = `@${segment.data.name}`;
					else {
						const info = await ctx.ntGroupApi.getGroupMemberByUin(+peer.peerUid, uin, false);
						display = `@${info?.cardName || info?.nick || ""}`;
					}
					sendElements.push(SendElement.at(uin, AtType.One, display));
				}
			}
			break;
		case OB11MessageDataType.Reply:
			if (segment.data?.id) {
				const info = await ctx.store.getMsgInfoByShortId(+segment.data.id);
				if (!info) {
					ctx.logger.warn("回复消息不存在", info);
					continue;
				}
				let msg = ctx.store.getMsgByMsgId(info.msgId);
				let srcMsg;
				let fetchFromServer = false;
				if (!msg) {
					const { msgList } = await ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq);
					msg = msgList[0];
					fetchFromServer = true;
				}
				if (msg) {
					if (isInsideForward) {
						if (msg.rawPb) srcMsg = Buffer.from(msg.rawPb, "hex");
						else if (!fetchFromServer) {
							const { msgList } = await ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq);
							srcMsg = msgList[0]?.rawPb ? Buffer.from(msgList[0].rawPb, "hex") : void 0;
						}
					}
					sendElements.push(SendElement.reply(msg.msgSeq, msg.senderUin, msg.senderUid, msg.msgTime, msg.clientSeq, srcMsg));
				}
			}
			break;
		case OB11MessageDataType.Face:
			{
				const faceId = segment.data?.id;
				const faceType = segment.data?.sub_type;
				if (faceId) sendElements.push(SendElement.face(+faceId, faceType));
			}
			break;
		case OB11MessageDataType.Mface:
			sendElements.push(SendElement.mface(+segment.data.emoji_package_id, segment.data.emoji_id, segment.data.key, segment.data.summary));
			break;
		case OB11MessageDataType.Image:
			{
				const res = await SendElement.pic(ctx, (await handleOb11RichMedia(ctx, segment, deleteAfterSentFiles)).path, segment.data.summary ?? "", Number(segment.data.subType) || 0);
				sendElements.push(res);
			}
			break;
		case OB11MessageDataType.Video:
			{
				const { path } = await handleOb11RichMedia(ctx, segment, deleteAfterSentFiles);
				let thumb = segment.data.cover ?? segment.data.thumb;
				if (thumb) {
					const uri2LocalRes = await uri2local(ctx, thumb);
					if (uri2LocalRes.success) {
						if (!uri2LocalRes.isLocal) deleteAfterSentFiles.push(uri2LocalRes.path);
						thumb = uri2LocalRes.path;
					} else throw new Error(uri2LocalRes.errMsg);
				}
				const res = await SendElement.video(ctx, path, thumb);
				sendElements.push(res);
			}
			break;
		case OB11MessageDataType.Record:
			{
				const { path } = await handleOb11RichMedia(ctx, segment, deleteAfterSentFiles);
				sendElements.push(await SendElement.ptt(ctx, path));
			}
			break;
		case OB11MessageDataType.Json:
			sendElements.push(SendElement.ark(segment.data.data));
			break;
		case OB11MessageDataType.Dice:
			{
				const resultId = segment.data?.result;
				sendElements.push(SendElement.dice(resultId));
			}
			break;
		case OB11MessageDataType.Rps:
			{
				const resultId = segment.data?.result;
				sendElements.push(SendElement.rps(resultId));
			}
			break;
		case OB11MessageDataType.Contact:
			{
				const { type, id } = segment.data;
				const data = type === "qq" ? ctx.ntFriendApi.getFriendRecommendContactArk(+id) : ctx.ntGroupApi.getGroupRecommendContactArk(+id);
				sendElements.push(SendElement.ark(await data));
			}
			break;
		case OB11MessageDataType.Shake:
			sendElements.push(SendElement.shake());
			break;
		case OB11MessageDataType.Music:
			{
				const { musicSignUrl } = ctx.onebot.config;
				if (!musicSignUrl) throw new Error("音乐卡片签名地址未配置");
				const { type } = segment.data;
				if (![
					"qq",
					"163",
					"kugou",
					"kuwo",
					"migu",
					"custom"
				].includes(type)) throw new Error(`不支持的音乐卡片 type ${type}`);
				if (!("id" in segment.data)) {
					if (!segment.data.url) throw new Error("自定义音卡缺少参数url");
					if (!segment.data.title) throw new Error("自定义音卡缺少参数title");
				}
				try {
					const content = await new MusicSign(ctx, musicSignUrl).sign(segment.data);
					sendElements.push(SendElement.ark(content));
				} catch (e) {
					throw new Error(`签名音乐消息失败：${e.message}`);
				}
			}
			break;
		case OB11MessageDataType.Forward:
			{
				const resid = segment.data.id;
				const filename = randomUUID();
				const { msgList } = await ctx.ntMsgApi.getForwardedMsgs(resid);
				if (msgList.length === 0) continue;
				const source = msgList[0].chatType === ChatType.Group ? "群聊的聊天记录" : "聊天记录";
				const summary = `查看${msgList.length}条转发消息`;
				const news = [];
				for (const msg of msgList) {
					if (news.length === 4) continue;
					const content = msg.elements.reduce((acc, curr) => {
						let preview;
						if (curr.elementType === ElementType.Text) preview = curr.textElement.content.slice(0, 70);
						else if (curr.elementType === ElementType.Face) preview = curr.faceElement.faceText;
						else if (curr.elementType === ElementType.MarketFace) preview = curr.marketFaceElement.faceName;
						else if (curr.elementType === ElementType.Pic) preview = curr.picElement.summary || "[图片]";
						else if (curr.elementType === ElementType.Video) preview = "[视频]";
						else if (curr.elementType === ElementType.Ptt) preview = "[语音]";
						else if (curr.elementType === ElementType.Ark) preview = curr.arkElement.bytesData.match(/"prompt"\s*:\s*"([^"]*)"/)?.[1] ?? "";
						else if (curr.elementType === ElementType.MultiForward) preview = "[合并转发]";
						return acc + preview;
					}, "");
					news.push({ text: `${msg.sendNickName}: ${content}` });
				}
				const content = JSON.stringify({
					app: "com.tencent.multimsg",
					config: {
						autosize: 1,
						forward: 1,
						round: 1,
						type: "normal",
						width: 300
					},
					desc: "[聊天记录]",
					extra: JSON.stringify({
						filename,
						tsum: 0
					}),
					meta: { detail: {
						news,
						resid,
						source,
						summary,
						uniseq: filename
					} },
					prompt: "[聊天记录]",
					ver: "0.0.0.5",
					view: "contact"
				});
				sendElements.push(SendElement.ark(content));
			}
			break;
		case OB11MessageDataType.Node:
			{
				const inner = await transformOutgoingSegments(ctx, segment.data.content ? message2List(segment.data.content) : [], peer, true);
				deleteAfterSentFiles.push(...inner.deleteAfterSentFiles);
				const { message_style } = segment.data;
				nodes.push({
					senderUin: Number(segment.data.uin ?? segment.data.user_id ?? selfInfo.uin),
					senderName: segment.data.name ?? segment.data.nickname ?? selfInfo.nick,
					elements: inner.sendElements,
					msgSeq: segment.data.seq,
					msgTime: segment.data.time ? +segment.data.time : void 0,
					msgStyle: message_style ? {
						bubbleId: message_style.bubble_id,
						pendantId: message_style.pendant_id,
						fontId: message_style.font_id,
						fontEffectId: message_style.font_effect_id,
						isCsFontEffectEnabled: message_style.is_cs_font_effect_enabled,
						bubbleDiyTextId: message_style.bubble_diy_text_id
					} : void 0
				});
			}
			break;
		case OB11MessageDataType.File: {
			const { path, fileName } = await handleOb11RichMedia(ctx, segment, deleteAfterSentFiles);
			sendElements.push(await SendElement.file(ctx, path, fileName));
		}
	}
	if (nodes.length > 0) sendElements.push(SendElement.forward(nodes));
	return {
		sendElements,
		deleteAfterSentFiles
	};
}
async function handleOb11RichMedia(ctx, segment, deleteAfterSentFiles) {
	const res = await uri2local(ctx, segment.data.url || segment.data.file);
	if (!res.success) throw new Error(res.errMsg);
	if (!res.isLocal) deleteAfterSentFiles.push(res.path);
	return {
		path: res.path,
		fileName: segment.data.name || res.fileName
	};
}
//#endregion
//#region src/onebot11/helper/quickOperation.ts
async function handleQuickOperation(ctx, event, quickAction) {
	if (event.post_type === "message") handleMsg(ctx, event, quickAction).then().catch((e) => ctx.logger.error(e));
	if (event.post_type === "request") {
		const friendRequest = event;
		const groupRequest = event;
		if (friendRequest.request_type === "friend") handleFriendRequest$1(ctx, friendRequest, quickAction).then().catch((e) => ctx.logger.error(e));
		else if (groupRequest.request_type === "group") handleGroupRequest(ctx, groupRequest, quickAction).then().catch((e) => ctx.logger.error(e));
	}
}
async function handleMsg(ctx, msg, quickAction) {
	const reply = quickAction.reply;
	let contextMode = CreatePeerMode.Normal;
	if (msg.message_type === "group") contextMode = CreatePeerMode.Group;
	else if (msg.message_type === "private") contextMode = CreatePeerMode.Private;
	const peer = await createPeer(ctx, msg, contextMode);
	if (reply) {
		let replyMessage = [];
		replyMessage.push({
			type: OB11MessageDataType.Reply,
			data: { id: msg.message_id.toString() }
		});
		if (msg.message_type == "group") {
			if (quickAction.at_sender) replyMessage.push({
				type: OB11MessageDataType.At,
				data: { qq: msg.user_id.toString() }
			});
		}
		replyMessage = replyMessage.concat(message2List(reply, quickAction.auto_escape));
		const { sendElements, deleteAfterSentFiles } = await transformOutgoingSegments(ctx, replyMessage, peer, false);
		ctx.app.sendMessage(ctx, peer, sendElements, deleteAfterSentFiles).catch((e) => ctx.logger.error(e));
	}
	if (msg.message_type === "group") {
		const groupMsgQuickAction = quickAction;
		const info = await ctx.store.getMsgInfoByShortId(msg.message_id);
		if (!info) return;
		if (groupMsgQuickAction.delete) ctx.ntMsgApi.recallMsg(peer, info.msgSeq).catch((e) => ctx.logger.error(e));
		if (groupMsgQuickAction.kick) {
			let msg = ctx.store.getMsgByMsgId(info.msgId);
			if (!msg) msg = (await ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq)).msgList[0];
			ctx.ntGroupApi.kickGroupMember(+peer.peerUid, [msg.senderUid]).catch((e) => ctx.logger.error(e));
		}
		if (groupMsgQuickAction.ban) {
			let msg = ctx.store.getMsgByMsgId(info.msgId);
			if (!msg) msg = (await ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq)).msgList[0];
			ctx.ntGroupApi.muteGroupMember(+peer.peerUid, [{
				uid: msg.senderUid,
				duration: groupMsgQuickAction.ban_duration || 1800
			}]).catch((e) => ctx.logger.error(e));
		}
	}
}
async function handleFriendRequest$1(ctx, request, quickAction) {
	if (!isNullable(quickAction.approve)) {
		await ctx.ntFriendApi.approvalFriendRequest(request.flag, quickAction.approve).catch((e) => ctx.logger.error(e));
		if (!isNullable(quickAction.remark)) await ctx.ntFriendApi.setFriendRemark(request.flag, quickAction.remark).catch((e) => ctx.logger.error(e));
	}
}
async function handleGroupRequest(ctx, request, quickAction) {
	if (!isNullable(quickAction.approve)) {
		const decoded = decodeGroupRequestFlag$2(request.flag);
		ctx.ntGroupApi.setGroupRequest(decoded.doubt, decoded.groupCode, decoded.seq, decoded.type, quickAction.approve, quickAction.reason).catch((e) => ctx.logger.error(e));
	}
}
//#endregion
//#region src/onebot11/helper/eventForHttp.ts
var curentSeq = 0;
var eventList = [];
var httpUser = {};
function postHttpEvent(event) {
	curentSeq += 1;
	eventList.push({
		seq: curentSeq,
		event
	});
	while (eventList.length > 100) eventList.shift();
}
async function getHttpEvent(userKey, timeout = 0) {
	if (typeof userKey !== "string" || userKey === "__proto__" || userKey === "constructor" || userKey === "prototype") throw new Error("Invalid user key");
	const toRetEvent = [];
	const now = Date.now();
	for (const key in httpUser) if (now - httpUser[key].lastAccessTime > 3e5) delete httpUser[key];
	const userKeys = Object.keys(httpUser);
	if (userKeys.length > 100) {
		const oldestKey = userKeys.reduce((oldest, current) => httpUser[current].lastAccessTime < httpUser[oldest].lastAccessTime ? current : oldest);
		delete httpUser[oldestKey];
	}
	if (!httpUser[userKey]) httpUser[userKey] = {
		lastAccessTime: now,
		userSeq: curentSeq
	};
	const user = httpUser[userKey];
	while (curentSeq == user.userSeq && Date.now() - now < timeout) await new Promise((resolve) => setTimeout(resolve, 10));
	for (let i = 0; i < eventList.length; i++) {
		const evt = eventList[i];
		if (evt.seq > user.userSeq) toRetEvent.push(evt.event);
	}
	user.lastAccessTime = Date.now();
	user.userSeq = curentSeq;
	return toRetEvent;
}
//#endregion
//#region node_modules/hono/dist/compose.js
var compose = (middleware, onError, onNotFound) => {
	return (context, next) => {
		let index = -1;
		return dispatch(0);
		async function dispatch(i) {
			if (i <= index) throw new Error("next() called multiple times");
			index = i;
			let res;
			let isError = false;
			let handler;
			if (middleware[i]) {
				handler = middleware[i][0][0];
				context.req.routeIndex = i;
			} else handler = i === middleware.length && next || void 0;
			if (handler) try {
				res = await handler(context, () => dispatch(i + 1));
			} catch (err) {
				if (err instanceof Error && onError) {
					context.error = err;
					res = await onError(err, context);
					isError = true;
				} else throw err;
			}
			else if (context.finalized === false && onNotFound) res = await onNotFound(context);
			if (res && (context.finalized === false || isError)) context.res = res;
			return context;
		}
	};
};
//#endregion
//#region node_modules/hono/dist/request/constants.js
var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
//#endregion
//#region node_modules/hono/dist/utils/buffer.js
var bufferToFormData = (arrayBuffer, contentType) => {
	return new Response(arrayBuffer, { headers: { "Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase()) } }).formData();
};
//#endregion
//#region node_modules/hono/dist/utils/body.js
var isRawRequest = (request) => "headers" in request;
var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
	const { all = false, dot = false } = options;
	const mediaType = (isRawRequest(request) ? request.headers : request.raw.headers).get("Content-Type")?.split(";")[0].trim().toLowerCase();
	if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") return parseFormData(request, {
		all,
		dot
	});
	return {};
};
async function parseFormData(request, options) {
	if (!isRawRequest(request) && request.bodyCache.formData) return convertFormDataToBodyData(await request.bodyCache.formData, options);
	const headers = isRawRequest(request) ? request.headers : request.raw.headers;
	const formDataPromise = bufferToFormData(await request.arrayBuffer(), headers.get("Content-Type") || "");
	if (!isRawRequest(request)) request.bodyCache.formData = formDataPromise;
	const formData = await formDataPromise;
	if (formData) return convertFormDataToBodyData(formData, options);
	return {};
}
function convertFormDataToBodyData(formData, options) {
	const form = /* @__PURE__ */ Object.create(null);
	formData.forEach((value, key) => {
		if (!(options.all || key.endsWith("[]"))) form[key] = value;
		else handleParsingAllValues(form, key, value);
	});
	if (options.dot) Object.entries(form).forEach(([key, value]) => {
		if (key.includes(".")) {
			handleParsingNestedValues(form, key, value);
			delete form[key];
		}
	});
	return form;
}
var handleParsingAllValues = (form, key, value) => {
	if (form[key] !== void 0) if (Array.isArray(form[key])) form[key].push(value);
	else form[key] = [form[key], value];
	else if (!key.endsWith("[]")) form[key] = value;
	else form[key] = [value];
};
var handleParsingNestedValues = (form, key, value) => {
	if (/(?:^|\.)__proto__\./.test(key)) return;
	let nestedForm = form;
	const keys = key.split(".");
	keys.forEach((key2, index) => {
		if (index === keys.length - 1) nestedForm[key2] = value;
		else {
			if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) nestedForm[key2] = /* @__PURE__ */ Object.create(null);
			nestedForm = nestedForm[key2];
		}
	});
};
//#endregion
//#region node_modules/hono/dist/utils/url.js
var splitPath = (path) => {
	const paths = path.split("/");
	if (paths[0] === "") paths.shift();
	return paths;
};
var splitRoutingPath = (routePath) => {
	const { groups, path } = extractGroupsFromPath(routePath);
	return replaceGroupMarks(splitPath(path), groups);
};
var extractGroupsFromPath = (path) => {
	const groups = [];
	path = path.replace(/\{[^}]+\}/g, (match, index) => {
		const mark = `@${index}`;
		groups.push([mark, match]);
		return mark;
	});
	return {
		groups,
		path
	};
};
var replaceGroupMarks = (paths, groups) => {
	for (let i = groups.length - 1; i >= 0; i--) {
		const [mark] = groups[i];
		for (let j = paths.length - 1; j >= 0; j--) if (paths[j].includes(mark)) {
			paths[j] = paths[j].replace(mark, groups[i][1]);
			break;
		}
	}
	return paths;
};
var patternCache = {};
var getPattern = (label, next) => {
	if (label === "*") return "*";
	const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
	if (match) {
		const cacheKey = `${label}#${next}`;
		if (!patternCache[cacheKey]) if (match[2]) patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [
			cacheKey,
			match[1],
			new RegExp(`^${match[2]}(?=/${next})`)
		] : [
			label,
			match[1],
			new RegExp(`^${match[2]}$`)
		];
		else patternCache[cacheKey] = [
			label,
			match[1],
			true
		];
		return patternCache[cacheKey];
	}
	return null;
};
var tryDecode$1 = (str, decoder) => {
	try {
		return decoder(str);
	} catch {
		return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
			try {
				return decoder(match);
			} catch {
				return match;
			}
		});
	}
};
var tryDecodeURI$1 = (str) => tryDecode$1(str, decodeURI);
var getPath = (request) => {
	const url = request.url;
	const start = url.indexOf("/", url.indexOf(":") + 4);
	let i = start;
	for (; i < url.length; i++) {
		const charCode = url.charCodeAt(i);
		if (charCode === 37) {
			const queryIndex = url.indexOf("?", i);
			const hashIndex = url.indexOf("#", i);
			const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
			const path = url.slice(start, end);
			return tryDecodeURI$1(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
		} else if (charCode === 63 || charCode === 35) break;
	}
	return url.slice(start, i);
};
var getPathNoStrict = (request) => {
	const result = getPath(request);
	return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
};
var mergePath = (base, sub, ...rest) => {
	if (rest.length) sub = mergePath(sub, ...rest);
	return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
};
var checkOptionalParameter = (path) => {
	if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) return null;
	const segments = path.split("/");
	const results = [];
	let basePath = "";
	segments.forEach((segment) => {
		if (segment !== "" && !/\:/.test(segment)) basePath += "/" + segment;
		else if (/\:/.test(segment)) if (/\?/.test(segment)) {
			if (results.length === 0 && basePath === "") results.push("/");
			else results.push(basePath);
			const optionalSegment = segment.replace("?", "");
			basePath += "/" + optionalSegment;
			results.push(basePath);
		} else basePath += "/" + segment;
	});
	return results.filter((v, i, a) => a.indexOf(v) === i);
};
var _decodeURI = (value) => {
	if (!/[%+]/.test(value)) return value;
	if (value.indexOf("+") !== -1) value = value.replace(/\+/g, " ");
	return value.indexOf("%") !== -1 ? tryDecode$1(value, decodeURIComponent_) : value;
};
var _getQueryParam = (url, key, multiple) => {
	let encoded;
	if (!multiple && key && !/[%+]/.test(key)) {
		let keyIndex2 = url.indexOf("?", 8);
		if (keyIndex2 === -1) return;
		if (!url.startsWith(key, keyIndex2 + 1)) keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
		while (keyIndex2 !== -1) {
			const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
			if (trailingKeyCode === 61) {
				const valueIndex = keyIndex2 + key.length + 2;
				const endIndex = url.indexOf("&", valueIndex);
				return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
			} else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) return "";
			keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
		}
		encoded = /[%+]/.test(url);
		if (!encoded) return;
	}
	const results = /* @__PURE__ */ Object.create(null);
	encoded ??= /[%+]/.test(url);
	let keyIndex = url.indexOf("?", 8);
	while (keyIndex !== -1) {
		const nextKeyIndex = url.indexOf("&", keyIndex + 1);
		let valueIndex = url.indexOf("=", keyIndex);
		if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) valueIndex = -1;
		let name = url.slice(keyIndex + 1, valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex);
		if (encoded) name = _decodeURI(name);
		keyIndex = nextKeyIndex;
		if (name === "") continue;
		let value;
		if (valueIndex === -1) value = "";
		else {
			value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
			if (encoded) value = _decodeURI(value);
		}
		if (multiple) {
			if (!(results[name] && Array.isArray(results[name]))) results[name] = [];
			results[name].push(value);
		} else results[name] ??= value;
	}
	return key ? results[key] : results;
};
var getQueryParam = _getQueryParam;
var getQueryParams = (url, key) => {
	return _getQueryParam(url, key, true);
};
var decodeURIComponent_ = decodeURIComponent;
//#endregion
//#region node_modules/hono/dist/request.js
var tryDecodeURIComponent = (str) => tryDecode$1(str, decodeURIComponent_);
var HonoRequest = class {
	/**
	* `.raw` can get the raw Request object.
	*
	* @see {@link https://hono.dev/docs/api/request#raw}
	*
	* @example
	* ```ts
	* // For Cloudflare Workers
	* app.post('/', async (c) => {
	*   const metadata = c.req.raw.cf?.hostMetadata?
	*   ...
	* })
	* ```
	*/
	raw;
	#validatedData;
	#matchResult;
	routeIndex = 0;
	/**
	* `.path` can get the pathname of the request.
	*
	* @see {@link https://hono.dev/docs/api/request#path}
	*
	* @example
	* ```ts
	* app.get('/about/me', (c) => {
	*   const pathname = c.req.path // `/about/me`
	* })
	* ```
	*/
	path;
	bodyCache = {};
	constructor(request, path = "/", matchResult = [[]]) {
		this.raw = request;
		this.path = path;
		this.#matchResult = matchResult;
		this.#validatedData = {};
	}
	param(key) {
		return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
	}
	#getDecodedParam(key) {
		const paramKey = this.#matchResult[0][this.routeIndex][1][key];
		const param = this.#getParamValue(paramKey);
		return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
	}
	#getAllDecodedParams() {
		const decoded = {};
		const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
		for (const key of keys) {
			const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
			if (value !== void 0) decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
		}
		return decoded;
	}
	#getParamValue(paramKey) {
		return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
	}
	query(key) {
		return getQueryParam(this.url, key);
	}
	queries(key) {
		return getQueryParams(this.url, key);
	}
	header(name) {
		if (name) return this.raw.headers.get(name) ?? void 0;
		const headerData = /* @__PURE__ */ Object.create(null);
		this.raw.headers.forEach((value, key) => {
			headerData[key] = value;
		});
		return headerData;
	}
	async parseBody(options) {
		return parseBody(this, options);
	}
	#cachedBody = (key) => {
		const { bodyCache, raw } = this;
		const cachedBody = bodyCache[key];
		if (cachedBody) return cachedBody;
		const anyCachedKey = Object.keys(bodyCache)[0];
		if (anyCachedKey) return bodyCache[anyCachedKey].then((body) => {
			if (anyCachedKey === "json") body = JSON.stringify(body);
			return new Response(body)[key]();
		});
		return bodyCache[key] = raw[key]();
	};
	/**
	* `.json()` can parse Request body of type `application/json`
	*
	* @see {@link https://hono.dev/docs/api/request#json}
	*
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.json()
	* })
	* ```
	*/
	json() {
		return this.#cachedBody("text").then((text) => JSON.parse(text));
	}
	/**
	* `.text()` can parse Request body of type `text/plain`
	*
	* @see {@link https://hono.dev/docs/api/request#text}
	*
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.text()
	* })
	* ```
	*/
	text() {
		return this.#cachedBody("text");
	}
	/**
	* `.arrayBuffer()` parse Request body as an `ArrayBuffer`
	*
	* @see {@link https://hono.dev/docs/api/request#arraybuffer}
	*
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.arrayBuffer()
	* })
	* ```
	*/
	arrayBuffer() {
		return this.#cachedBody("arrayBuffer");
	}
	/**
	* `.bytes()` parses the request body as a `Uint8Array`.
	*
	* @see {@link https://hono.dev/docs/api/request#bytes}
	*
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.bytes()
	* })
	* ```
	*/
	bytes() {
		return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
	}
	/**
	* Parses the request body as a `Blob`.
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.blob();
	* });
	* ```
	* @see https://hono.dev/docs/api/request#blob
	*/
	blob() {
		return this.#cachedBody("blob");
	}
	/**
	* Parses the request body as `FormData`.
	* @example
	* ```ts
	* app.post('/entry', async (c) => {
	*   const body = await c.req.formData();
	* });
	* ```
	* @see https://hono.dev/docs/api/request#formdata
	*/
	formData() {
		return this.#cachedBody("formData");
	}
	/**
	* Adds validated data to the request.
	*
	* @param target - The target of the validation.
	* @param data - The validated data to add.
	*/
	addValidatedData(target, data) {
		this.#validatedData[target] = data;
	}
	valid(target) {
		return this.#validatedData[target];
	}
	/**
	* `.url()` can get the request url strings.
	*
	* @see {@link https://hono.dev/docs/api/request#url}
	*
	* @example
	* ```ts
	* app.get('/about/me', (c) => {
	*   const url = c.req.url // `http://localhost:8787/about/me`
	*   ...
	* })
	* ```
	*/
	get url() {
		return this.raw.url;
	}
	/**
	* `.method()` can get the method name of the request.
	*
	* @see {@link https://hono.dev/docs/api/request#method}
	*
	* @example
	* ```ts
	* app.get('/about/me', (c) => {
	*   const method = c.req.method // `GET`
	* })
	* ```
	*/
	get method() {
		return this.raw.method;
	}
	get [GET_MATCH_RESULT]() {
		return this.#matchResult;
	}
	/**
	* `.matchedRoutes()` can return a matched route in the handler
	*
	* @deprecated
	*
	* Use matchedRoutes helper defined in "hono/route" instead.
	*
	* @see {@link https://hono.dev/docs/api/request#matchedroutes}
	*
	* @example
	* ```ts
	* app.use('*', async function logger(c, next) {
	*   await next()
	*   c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
	*     const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
	*     console.log(
	*       method,
	*       ' ',
	*       path,
	*       ' '.repeat(Math.max(10 - path.length, 0)),
	*       name,
	*       i === c.req.routeIndex ? '<- respond from here' : ''
	*     )
	*   })
	* })
	* ```
	*/
	get matchedRoutes() {
		return this.#matchResult[0].map(([[, route]]) => route);
	}
	/**
	* `routePath()` can retrieve the path registered within the handler
	*
	* @deprecated
	*
	* Use routePath helper defined in "hono/route" instead.
	*
	* @see {@link https://hono.dev/docs/api/request#routepath}
	*
	* @example
	* ```ts
	* app.get('/posts/:id', (c) => {
	*   return c.json({ path: c.req.routePath })
	* })
	* ```
	*/
	get routePath() {
		return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
	}
};
//#endregion
//#region node_modules/hono/dist/utils/html.js
var HtmlEscapedCallbackPhase = {
	Stringify: 1,
	BeforeStream: 2,
	Stream: 3
};
var raw = (value, callbacks) => {
	const escapedString = new String(value);
	escapedString.isEscaped = true;
	escapedString.callbacks = callbacks;
	return escapedString;
};
var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
	if (typeof str === "object" && !(str instanceof String)) {
		if (!(str instanceof Promise)) str = str.toString();
		if (str instanceof Promise) str = await str;
	}
	const callbacks = str.callbacks;
	if (!callbacks?.length) return Promise.resolve(str);
	if (buffer) buffer[0] += str;
	else buffer = [str];
	const resStr = Promise.all(callbacks.map((c) => c({
		phase,
		buffer,
		context
	}))).then((res) => Promise.all(res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))).then(() => buffer[0]));
	if (preserveCallbacks) return raw(await resStr, callbacks);
	else return resStr;
};
//#endregion
//#region node_modules/hono/dist/context.js
var TEXT_PLAIN = "text/plain; charset=UTF-8";
var setDefaultContentType = (contentType, headers) => {
	return {
		"Content-Type": contentType,
		...headers
	};
};
var createResponseInstance = (body, init) => new Response(body, init);
var Context = class {
	#rawRequest;
	#req;
	/**
	* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
	*
	* @see {@link https://hono.dev/docs/api/context#env}
	*
	* @example
	* ```ts
	* // Environment object for Cloudflare Workers
	* app.get('*', async c => {
	*   const counter = c.env.COUNTER
	* })
	* ```
	*/
	env = {};
	#var;
	finalized = false;
	/**
	* `.error` can get the error object from the middleware if the Handler throws an error.
	*
	* @see {@link https://hono.dev/docs/api/context#error}
	*
	* @example
	* ```ts
	* app.use('*', async (c, next) => {
	*   await next()
	*   if (c.error) {
	*     // do something...
	*   }
	* })
	* ```
	*/
	error;
	#status;
	#executionCtx;
	#res;
	#layout;
	#renderer;
	#notFoundHandler;
	#preparedHeaders;
	#matchResult;
	#path;
	/**
	* Creates an instance of the Context class.
	*
	* @param req - The Request object.
	* @param options - Optional configuration options for the context.
	*/
	constructor(req, options) {
		this.#rawRequest = req;
		if (options) {
			this.#executionCtx = options.executionCtx;
			this.env = options.env;
			this.#notFoundHandler = options.notFoundHandler;
			this.#path = options.path;
			this.#matchResult = options.matchResult;
		}
	}
	/**
	* `.req` is the instance of {@link HonoRequest}.
	*/
	get req() {
		this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
		return this.#req;
	}
	/**
	* @see {@link https://hono.dev/docs/api/context#event}
	* The FetchEvent associated with the current request.
	*
	* @throws Will throw an error if the context does not have a FetchEvent.
	*/
	get event() {
		if (this.#executionCtx && "respondWith" in this.#executionCtx) return this.#executionCtx;
		else throw Error("This context has no FetchEvent");
	}
	/**
	* @see {@link https://hono.dev/docs/api/context#executionctx}
	* The ExecutionContext associated with the current request.
	*
	* @throws Will throw an error if the context does not have an ExecutionContext.
	*/
	get executionCtx() {
		if (this.#executionCtx) return this.#executionCtx;
		else throw Error("This context has no ExecutionContext");
	}
	/**
	* @see {@link https://hono.dev/docs/api/context#res}
	* The Response object for the current request.
	*/
	get res() {
		return this.#res ||= createResponseInstance(null, { headers: this.#preparedHeaders ??= new Headers() });
	}
	/**
	* Sets the Response object for the current request.
	*
	* @param _res - The Response object to set.
	*/
	set res(_res) {
		if (this.#res && _res) {
			_res = createResponseInstance(_res.body, _res);
			for (const [k, v] of this.#res.headers.entries()) {
				if (k === "content-type") continue;
				if (k === "set-cookie") {
					const cookies = this.#res.headers.getSetCookie();
					_res.headers.delete("set-cookie");
					for (const cookie of cookies) _res.headers.append("set-cookie", cookie);
				} else _res.headers.set(k, v);
			}
		}
		this.#res = _res;
		this.finalized = true;
	}
	/**
	* `.render()` can create a response within a layout.
	*
	* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
	*
	* @example
	* ```ts
	* app.get('/', (c) => {
	*   return c.render('Hello!')
	* })
	* ```
	*/
	render = (...args) => {
		this.#renderer ??= (content) => this.html(content);
		return this.#renderer(...args);
	};
	/**
	* Sets the layout for the response.
	*
	* @param layout - The layout to set.
	* @returns The layout function.
	*/
	setLayout = (layout) => this.#layout = layout;
	/**
	* Gets the current layout for the response.
	*
	* @returns The current layout function.
	*/
	getLayout = () => this.#layout;
	/**
	* `.setRenderer()` can set the layout in the custom middleware.
	*
	* @see {@link https://hono.dev/docs/api/context#render-setrenderer}
	*
	* @example
	* ```tsx
	* app.use('*', async (c, next) => {
	*   c.setRenderer((content) => {
	*     return c.html(
	*       <html>
	*         <body>
	*           <p>{content}</p>
	*         </body>
	*       </html>
	*     )
	*   })
	*   await next()
	* })
	* ```
	*/
	setRenderer = (renderer) => {
		this.#renderer = renderer;
	};
	/**
	* `.header()` can set headers.
	*
	* @see {@link https://hono.dev/docs/api/context#header}
	*
	* @example
	* ```ts
	* app.get('/welcome', (c) => {
	*   // Set headers
	*   c.header('X-Message', 'Hello!')
	*   c.header('Content-Type', 'text/plain')
	*
	*   return c.body('Thank you for coming')
	* })
	* ```
	*/
	header = (name, value, options) => {
		if (this.finalized) this.#res = createResponseInstance(this.#res.body, this.#res);
		const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
		if (value === void 0) headers.delete(name);
		else if (options?.append) headers.append(name, value);
		else headers.set(name, value);
	};
	status = (status) => {
		this.#status = status;
	};
	/**
	* `.set()` can set the value specified by the key.
	*
	* @see {@link https://hono.dev/docs/api/context#set-get}
	*
	* @example
	* ```ts
	* app.use('*', async (c, next) => {
	*   c.set('message', 'Hono is hot!!')
	*   await next()
	* })
	* ```
	*/
	set = (key, value) => {
		this.#var ??= /* @__PURE__ */ new Map();
		this.#var.set(key, value);
	};
	/**
	* `.get()` can use the value specified by the key.
	*
	* @see {@link https://hono.dev/docs/api/context#set-get}
	*
	* @example
	* ```ts
	* app.get('/', (c) => {
	*   const message = c.get('message')
	*   return c.text(`The message is "${message}"`)
	* })
	* ```
	*/
	get = (key) => {
		return this.#var ? this.#var.get(key) : void 0;
	};
	/**
	* `.var` can access the value of a variable.
	*
	* @see {@link https://hono.dev/docs/api/context#var}
	*
	* @example
	* ```ts
	* const result = c.var.client.oneMethod()
	* ```
	*/
	get var() {
		if (!this.#var) return {};
		return Object.fromEntries(this.#var);
	}
	#newResponse(data, arg, headers) {
		const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
		if (typeof arg === "object" && "headers" in arg) {
			const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
			for (const [key, value] of argHeaders) if (key.toLowerCase() === "set-cookie") responseHeaders.append(key, value);
			else responseHeaders.set(key, value);
		}
		if (headers) for (const [k, v] of Object.entries(headers)) if (typeof v === "string") responseHeaders.set(k, v);
		else {
			responseHeaders.delete(k);
			for (const v2 of v) responseHeaders.append(k, v2);
		}
		return createResponseInstance(data, {
			status: typeof arg === "number" ? arg : arg?.status ?? this.#status,
			headers: responseHeaders
		});
	}
	newResponse = (...args) => this.#newResponse(...args);
	/**
	* `.body()` can return the HTTP response.
	* You can set headers with `.header()` and set HTTP status code with `.status`.
	* This can also be set in `.text()`, `.json()` and so on.
	*
	* @see {@link https://hono.dev/docs/api/context#body}
	*
	* @example
	* ```ts
	* app.get('/welcome', (c) => {
	*   // Set headers
	*   c.header('X-Message', 'Hello!')
	*   c.header('Content-Type', 'text/plain')
	*   // Set HTTP status code
	*   c.status(201)
	*
	*   // Return the response body
	*   return c.body('Thank you for coming')
	* })
	* ```
	*/
	body = (data, arg, headers) => this.#newResponse(data, arg, headers);
	/**
	* `.text()` can render text as `Content-Type:text/plain`.
	*
	* @see {@link https://hono.dev/docs/api/context#text}
	*
	* @example
	* ```ts
	* app.get('/say', (c) => {
	*   return c.text('Hello!')
	* })
	* ```
	*/
	text = (text, arg, headers) => {
		return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(text, arg, setDefaultContentType(TEXT_PLAIN, headers));
	};
	/**
	* `.json()` can render JSON as `Content-Type:application/json`.
	*
	* @see {@link https://hono.dev/docs/api/context#json}
	*
	* @example
	* ```ts
	* app.get('/api', (c) => {
	*   return c.json({ message: 'Hello!' })
	* })
	* ```
	*/
	json = (object, arg, headers) => {
		return this.#newResponse(JSON.stringify(object), arg, setDefaultContentType("application/json", headers));
	};
	html = (html, arg, headers) => {
		const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
		return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
	};
	/**
	* `.redirect()` can Redirect, default status code is 302.
	*
	* @see {@link https://hono.dev/docs/api/context#redirect}
	*
	* @example
	* ```ts
	* app.get('/redirect', (c) => {
	*   return c.redirect('/')
	* })
	* app.get('/redirect-permanently', (c) => {
	*   return c.redirect('/', 301)
	* })
	* ```
	*/
	redirect = (location, status) => {
		const locationString = String(location);
		this.header("Location", !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString));
		return this.newResponse(null, status ?? 302);
	};
	/**
	* `.notFound()` can return the Not Found Response.
	*
	* @see {@link https://hono.dev/docs/api/context#notfound}
	*
	* @example
	* ```ts
	* app.get('/notfound', (c) => {
	*   return c.notFound()
	* })
	* ```
	*/
	notFound = () => {
		this.#notFoundHandler ??= () => createResponseInstance();
		return this.#notFoundHandler(this);
	};
};
//#endregion
//#region node_modules/hono/dist/router.js
var METHODS = [
	"get",
	"post",
	"put",
	"delete",
	"options",
	"patch"
];
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
var UnsupportedPathError = class extends Error {};
//#endregion
//#region node_modules/hono/dist/utils/constants.js
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
//#endregion
//#region node_modules/hono/dist/hono-base.js
var notFoundHandler = (c) => {
	return c.text("404 Not Found", 404);
};
var errorHandler = (err, c) => {
	if ("getResponse" in err) {
		const res = err.getResponse();
		return c.newResponse(res.body, res);
	}
	console.error(err);
	return c.text("Internal Server Error", 500);
};
var Hono$1 = class _Hono {
	get;
	post;
	put;
	delete;
	options;
	patch;
	all;
	on;
	use;
	router;
	getPath;
	_basePath = "/";
	#path = "/";
	routes = [];
	constructor(options = {}) {
		[...METHODS, "all"].forEach((method) => {
			this[method] = (args1, ...args) => {
				if (typeof args1 === "string") this.#path = args1;
				else this.#addRoute(method, this.#path, args1);
				args.forEach((handler) => {
					this.#addRoute(method, this.#path, handler);
				});
				return this;
			};
		});
		this.on = (method, path, ...handlers) => {
			for (const p of [path].flat()) {
				this.#path = p;
				for (const m of [method].flat()) handlers.map((handler) => {
					this.#addRoute(m.toUpperCase(), this.#path, handler);
				});
			}
			return this;
		};
		this.use = (arg1, ...handlers) => {
			if (typeof arg1 === "string") this.#path = arg1;
			else {
				this.#path = "*";
				handlers.unshift(arg1);
			}
			handlers.forEach((handler) => {
				this.#addRoute("ALL", this.#path, handler);
			});
			return this;
		};
		const { strict, ...optionsWithoutStrict } = options;
		Object.assign(this, optionsWithoutStrict);
		this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
	}
	#clone() {
		const clone = new _Hono({
			router: this.router,
			getPath: this.getPath
		});
		clone.errorHandler = this.errorHandler;
		clone.#notFoundHandler = this.#notFoundHandler;
		clone.routes = this.routes;
		return clone;
	}
	#notFoundHandler = notFoundHandler;
	errorHandler = errorHandler;
	/**
	* `.route()` allows grouping other Hono instance in routes.
	*
	* @see {@link https://hono.dev/docs/api/routing#grouping}
	*
	* @param {string} path - base Path
	* @param {Hono} app - other Hono instance
	* @returns {Hono} routed Hono instance
	*
	* @example
	* ```ts
	* const app = new Hono()
	* const app2 = new Hono()
	*
	* app2.get("/user", (c) => c.text("user"))
	* app.route("/api", app2) // GET /api/user
	* ```
	*/
	route(path, app) {
		const subApp = this.basePath(path);
		app.routes.map((r) => {
			let handler;
			if (app.errorHandler === errorHandler) handler = r.handler;
			else {
				handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
				handler[COMPOSED_HANDLER] = r.handler;
			}
			subApp.#addRoute(r.method, r.path, handler, r.basePath);
		});
		return this;
	}
	/**
	* `.basePath()` allows base paths to be specified.
	*
	* @see {@link https://hono.dev/docs/api/routing#base-path}
	*
	* @param {string} path - base Path
	* @returns {Hono} changed Hono instance
	*
	* @example
	* ```ts
	* const api = new Hono().basePath('/api')
	* ```
	*/
	basePath(path) {
		const subApp = this.#clone();
		subApp._basePath = mergePath(this._basePath, path);
		return subApp;
	}
	/**
	* `.onError()` handles an error and returns a customized Response.
	*
	* @see {@link https://hono.dev/docs/api/hono#error-handling}
	*
	* @param {ErrorHandler} handler - request Handler for error
	* @returns {Hono} changed Hono instance
	*
	* @example
	* ```ts
	* app.onError((err, c) => {
	*   console.error(`${err}`)
	*   return c.text('Custom Error Message', 500)
	* })
	* ```
	*/
	onError = (handler) => {
		this.errorHandler = handler;
		return this;
	};
	/**
	* `.notFound()` allows you to customize a Not Found Response.
	*
	* @see {@link https://hono.dev/docs/api/hono#not-found}
	*
	* @param {NotFoundHandler} handler - request handler for not-found
	* @returns {Hono} changed Hono instance
	*
	* @example
	* ```ts
	* app.notFound((c) => {
	*   return c.text('Custom 404 Message', 404)
	* })
	* ```
	*/
	notFound = (handler) => {
		this.#notFoundHandler = handler;
		return this;
	};
	/**
	* `.mount()` allows you to mount applications built with other frameworks into your Hono application.
	*
	* @see {@link https://hono.dev/docs/api/hono#mount}
	*
	* @param {string} path - base Path
	* @param {Function} applicationHandler - other Request Handler
	* @param {MountOptions} [options] - options of `.mount()`
	* @returns {Hono} mounted Hono instance
	*
	* @example
	* ```ts
	* import { Router as IttyRouter } from 'itty-router'
	* import { Hono } from 'hono'
	* // Create itty-router application
	* const ittyRouter = IttyRouter()
	* // GET /itty-router/hello
	* ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
	*
	* const app = new Hono()
	* app.mount('/itty-router', ittyRouter.handle)
	* ```
	*
	* @example
	* ```ts
	* const app = new Hono()
	* // Send the request to another application without modification.
	* app.mount('/app', anotherApp, {
	*   replaceRequest: (req) => req,
	* })
	* ```
	*/
	mount(path, applicationHandler, options) {
		let replaceRequest;
		let optionHandler;
		if (options) if (typeof options === "function") optionHandler = options;
		else {
			optionHandler = options.optionHandler;
			if (options.replaceRequest === false) replaceRequest = (request) => request;
			else replaceRequest = options.replaceRequest;
		}
		const getOptions = optionHandler ? (c) => {
			const options2 = optionHandler(c);
			return Array.isArray(options2) ? options2 : [options2];
		} : (c) => {
			let executionContext = void 0;
			try {
				executionContext = c.executionCtx;
			} catch {}
			return [c.env, executionContext];
		};
		replaceRequest ||= (() => {
			const mergedPath = mergePath(this._basePath, path);
			const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
			return (request) => {
				const url = new URL(request.url);
				url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
				return new Request(url, request);
			};
		})();
		const handler = async (c, next) => {
			const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
			if (res) return res;
			await next();
		};
		this.#addRoute("ALL", mergePath(path, "*"), handler);
		return this;
	}
	#addRoute(method, path, handler, baseRoutePath) {
		method = method.toUpperCase();
		path = mergePath(this._basePath, path);
		const r = {
			basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
			path,
			method,
			handler
		};
		this.router.add(method, path, [handler, r]);
		this.routes.push(r);
	}
	#handleError(err, c) {
		if (err instanceof Error) return this.errorHandler(err, c);
		throw err;
	}
	#dispatch(request, executionCtx, env, method) {
		if (method === "HEAD") return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
		const path = this.getPath(request, { env });
		const matchResult = this.router.match(method, path);
		const c = new Context(request, {
			path,
			matchResult,
			env,
			executionCtx,
			notFoundHandler: this.#notFoundHandler
		});
		if (matchResult[0].length === 1) {
			let res;
			try {
				res = matchResult[0][0][0][0](c, async () => {
					c.res = await this.#notFoundHandler(c);
				});
			} catch (err) {
				return this.#handleError(err, c);
			}
			return res instanceof Promise ? res.then((resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
		}
		const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
		return (async () => {
			try {
				const context = await composed(c);
				if (!context.finalized) throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");
				return context.res;
			} catch (err) {
				return this.#handleError(err, c);
			}
		})();
	}
	/**
	* `.fetch()` will be entry point of your app.
	*
	* @see {@link https://hono.dev/docs/api/hono#fetch}
	*
	* @param {Request} request - request Object of request
	* @param {Env} Env - env Object
	* @param {ExecutionContext} - context of execution
	* @returns {Response | Promise<Response>} response of request
	*
	*/
	fetch = (request, ...rest) => {
		return this.#dispatch(request, rest[1], rest[0], request.method);
	};
	/**
	* `.request()` is a useful method for testing.
	* You can pass a URL or pathname to send a GET request.
	* app will return a Response object.
	* ```ts
	* test('GET /hello is ok', async () => {
	*   const res = await app.request('/hello')
	*   expect(res.status).toBe(200)
	* })
	* ```
	* @see https://hono.dev/docs/api/hono#request
	*/
	request = (input, requestInit, Env, executionCtx) => {
		if (input instanceof Request) return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
		input = input.toString();
		return this.fetch(new Request(/^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`, requestInit), Env, executionCtx);
	};
	/**
	* `.fire()` automatically adds a global fetch event listener.
	* This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
	* @deprecated
	* Use `fire` from `hono/service-worker` instead.
	* ```ts
	* import { Hono } from 'hono'
	* import { fire } from 'hono/service-worker'
	*
	* const app = new Hono()
	* // ...
	* fire(app)
	* ```
	* @see https://hono.dev/docs/api/hono#fire
	* @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
	* @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
	*/
	fire = () => {
		addEventListener("fetch", (event) => {
			event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
		});
	};
};
//#endregion
//#region node_modules/hono/dist/router/reg-exp-router/matcher.js
var emptyParam = [];
function match(method, path) {
	const matchers = this.buildAllMatchers();
	const match2 = ((method2, path2) => {
		const matcher = matchers[method2] || matchers["ALL"];
		const staticMatch = matcher[2][path2];
		if (staticMatch) return staticMatch;
		const match3 = path2.match(matcher[0]);
		if (!match3) return [[], emptyParam];
		const index = match3.indexOf("", 1);
		return [matcher[1][index], match3];
	});
	this.match = match2;
	return match2(method, path);
}
//#endregion
//#region node_modules/hono/dist/router/reg-exp-router/node.js
var LABEL_REG_EXP_STR = "[^/]+";
var ONLY_WILDCARD_REG_EXP_STR = ".*";
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
var PATH_ERROR = /* @__PURE__ */ Symbol();
var regExpMetaChars = /* @__PURE__ */ new Set(".\\+*[^]$()");
function compareKey(a, b) {
	if (a.length === 1) return b.length === 1 ? a < b ? -1 : 1 : -1;
	if (b.length === 1) return 1;
	if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) return 1;
	else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) return -1;
	if (a === LABEL_REG_EXP_STR) return 1;
	else if (b === LABEL_REG_EXP_STR) return -1;
	return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
}
var Node$1 = class _Node {
	#index;
	#varIndex;
	#children = /* @__PURE__ */ Object.create(null);
	insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
		if (tokens.length === 0) {
			if (this.#index !== void 0) throw PATH_ERROR;
			if (pathErrorCheckOnly) return;
			this.#index = index;
			return;
		}
		const [token, ...restTokens] = tokens;
		const pattern = token === "*" ? restTokens.length === 0 ? [
			"",
			"",
			ONLY_WILDCARD_REG_EXP_STR
		] : [
			"",
			"",
			LABEL_REG_EXP_STR
		] : token === "/*" ? [
			"",
			"",
			TAIL_WILDCARD_REG_EXP_STR
		] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
		let node;
		if (pattern) {
			const name = pattern[1];
			let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
			if (name && pattern[2]) {
				if (regexpStr === ".*") throw PATH_ERROR;
				regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
				if (/\((?!\?:)/.test(regexpStr)) throw PATH_ERROR;
			}
			node = this.#children[regexpStr];
			if (!node) {
				if (Object.keys(this.#children).some((k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR)) throw PATH_ERROR;
				if (pathErrorCheckOnly) return;
				node = this.#children[regexpStr] = new _Node();
				if (name !== "") node.#varIndex = context.varIndex++;
			}
			if (!pathErrorCheckOnly && name !== "") paramMap.push([name, node.#varIndex]);
		} else {
			node = this.#children[token];
			if (!node) {
				if (Object.keys(this.#children).some((k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR)) throw PATH_ERROR;
				if (pathErrorCheckOnly) return;
				node = this.#children[token] = new _Node();
			}
		}
		node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
	}
	buildRegExpStr() {
		const strList = Object.keys(this.#children).sort(compareKey).map((k) => {
			const c = this.#children[k];
			return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
		});
		if (typeof this.#index === "number") strList.unshift(`#${this.#index}`);
		if (strList.length === 0) return "";
		if (strList.length === 1) return strList[0];
		return "(?:" + strList.join("|") + ")";
	}
};
//#endregion
//#region node_modules/hono/dist/router/reg-exp-router/trie.js
var Trie = class {
	#context = { varIndex: 0 };
	#root = new Node$1();
	insert(path, index, pathErrorCheckOnly) {
		const paramAssoc = [];
		const groups = [];
		for (let i = 0;;) {
			let replaced = false;
			path = path.replace(/\{[^}]+\}/g, (m) => {
				const mark = `@\\${i}`;
				groups[i] = [mark, m];
				i++;
				replaced = true;
				return mark;
			});
			if (!replaced) break;
		}
		const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
		for (let i = groups.length - 1; i >= 0; i--) {
			const [mark] = groups[i];
			for (let j = tokens.length - 1; j >= 0; j--) if (tokens[j].indexOf(mark) !== -1) {
				tokens[j] = tokens[j].replace(mark, groups[i][1]);
				break;
			}
		}
		this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
		return paramAssoc;
	}
	buildRegExp() {
		let regexp = this.#root.buildRegExpStr();
		if (regexp === "") return [
			/^$/,
			[],
			[]
		];
		let captureIndex = 0;
		const indexReplacementMap = [];
		const paramReplacementMap = [];
		regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
			if (handlerIndex !== void 0) {
				indexReplacementMap[++captureIndex] = Number(handlerIndex);
				return "$()";
			}
			if (paramIndex !== void 0) {
				paramReplacementMap[Number(paramIndex)] = ++captureIndex;
				return "";
			}
			return "";
		});
		return [
			new RegExp(`^${regexp}`),
			indexReplacementMap,
			paramReplacementMap
		];
	}
};
//#endregion
//#region node_modules/hono/dist/router/reg-exp-router/router.js
var nullMatcher = [
	/^$/,
	[],
	/* @__PURE__ */ Object.create(null)
];
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
function buildWildcardRegExp(path) {
	return wildcardRegExpCache[path] ??= new RegExp(path === "*" ? "" : `^${path.replace(/\/\*$|([.\\+*[^\]$()])/g, (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)")}$`);
}
function clearWildcardRegExpCache() {
	wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
}
function buildMatcherFromPreprocessedRoutes(routes) {
	const trie = new Trie();
	const handlerData = [];
	if (routes.length === 0) return nullMatcher;
	const routesWithStaticPathFlag = routes.map((route) => [!/\*|\/:/.test(route[0]), ...route]).sort(([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length);
	const staticMap = /* @__PURE__ */ Object.create(null);
	for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
		const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
		if (pathErrorCheckOnly) staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
		else j++;
		let paramAssoc;
		try {
			paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
		} catch (e) {
			throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
		}
		if (pathErrorCheckOnly) continue;
		handlerData[j] = handlers.map(([h, paramCount]) => {
			const paramIndexMap = /* @__PURE__ */ Object.create(null);
			paramCount -= 1;
			for (; paramCount >= 0; paramCount--) {
				const [key, value] = paramAssoc[paramCount];
				paramIndexMap[key] = value;
			}
			return [h, paramIndexMap];
		});
	}
	const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
	for (let i = 0, len = handlerData.length; i < len; i++) for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
		const map = handlerData[i][j]?.[1];
		if (!map) continue;
		const keys = Object.keys(map);
		for (let k = 0, len3 = keys.length; k < len3; k++) map[keys[k]] = paramReplacementMap[map[keys[k]]];
	}
	const handlerMap = [];
	for (const i in indexReplacementMap) handlerMap[i] = handlerData[indexReplacementMap[i]];
	return [
		regexp,
		handlerMap,
		staticMap
	];
}
function findMiddleware(middleware, path) {
	if (!middleware) return;
	for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) if (buildWildcardRegExp(k).test(path)) return [...middleware[k]];
}
var RegExpRouter = class {
	name = "RegExpRouter";
	#middleware;
	#routes;
	constructor() {
		this.#middleware = { ["ALL"]: /* @__PURE__ */ Object.create(null) };
		this.#routes = { ["ALL"]: /* @__PURE__ */ Object.create(null) };
	}
	add(method, path, handler) {
		const middleware = this.#middleware;
		const routes = this.#routes;
		if (!middleware || !routes) throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
		if (!middleware[method]) [middleware, routes].forEach((handlerMap) => {
			handlerMap[method] = /* @__PURE__ */ Object.create(null);
			Object.keys(handlerMap["ALL"]).forEach((p) => {
				handlerMap[method][p] = [...handlerMap["ALL"][p]];
			});
		});
		if (path === "/*") path = "*";
		const paramCount = (path.match(/\/:/g) || []).length;
		if (/\*$/.test(path)) {
			const re = buildWildcardRegExp(path);
			if (method === "ALL") Object.keys(middleware).forEach((m) => {
				middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware["ALL"], path) || [];
			});
			else middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware["ALL"], path) || [];
			Object.keys(middleware).forEach((m) => {
				if (method === "ALL" || method === m) Object.keys(middleware[m]).forEach((p) => {
					re.test(p) && middleware[m][p].push([handler, paramCount]);
				});
			});
			Object.keys(routes).forEach((m) => {
				if (method === "ALL" || method === m) Object.keys(routes[m]).forEach((p) => re.test(p) && routes[m][p].push([handler, paramCount]));
			});
			return;
		}
		const paths = checkOptionalParameter(path) || [path];
		for (let i = 0, len = paths.length; i < len; i++) {
			const path2 = paths[i];
			Object.keys(routes).forEach((m) => {
				if (method === "ALL" || method === m) {
					routes[m][path2] ||= [...findMiddleware(middleware[m], path2) || findMiddleware(middleware["ALL"], path2) || []];
					routes[m][path2].push([handler, paramCount - len + i + 1]);
				}
			});
		}
	}
	match = match;
	buildAllMatchers() {
		const matchers = /* @__PURE__ */ Object.create(null);
		Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
			matchers[method] ||= this.#buildMatcher(method);
		});
		this.#middleware = this.#routes = void 0;
		clearWildcardRegExpCache();
		return matchers;
	}
	#buildMatcher(method) {
		const routes = [];
		let hasOwnRoute = method === "ALL";
		[this.#middleware, this.#routes].forEach((r) => {
			const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];
			if (ownRoute.length !== 0) {
				hasOwnRoute ||= true;
				routes.push(...ownRoute);
			} else if (method !== "ALL") routes.push(...Object.keys(r["ALL"]).map((path) => [path, r["ALL"][path]]));
		});
		if (!hasOwnRoute) return null;
		else return buildMatcherFromPreprocessedRoutes(routes);
	}
};
//#endregion
//#region node_modules/hono/dist/router/smart-router/router.js
var SmartRouter = class {
	name = "SmartRouter";
	#routers = [];
	#routes = [];
	constructor(init) {
		this.#routers = init.routers;
	}
	add(method, path, handler) {
		if (!this.#routes) throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
		this.#routes.push([
			method,
			path,
			handler
		]);
	}
	match(method, path) {
		if (!this.#routes) throw new Error("Fatal error");
		const routers = this.#routers;
		const routes = this.#routes;
		const len = routers.length;
		let i = 0;
		let res;
		for (; i < len; i++) {
			const router = routers[i];
			try {
				for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) router.add(...routes[i2]);
				res = router.match(method, path);
			} catch (e) {
				if (e instanceof UnsupportedPathError) continue;
				throw e;
			}
			this.match = router.match.bind(router);
			this.#routers = [router];
			this.#routes = void 0;
			break;
		}
		if (i === len) throw new Error("Fatal error");
		this.name = `SmartRouter + ${this.activeRouter.name}`;
		return res;
	}
	get activeRouter() {
		if (this.#routes || this.#routers.length !== 1) throw new Error("No active router has been determined yet.");
		return this.#routers[0];
	}
};
//#endregion
//#region node_modules/hono/dist/router/trie-router/node.js
var emptyParams = /* @__PURE__ */ Object.create(null);
var hasChildren = (children) => {
	for (const _ in children) return true;
	return false;
};
var Node = class _Node {
	#methods;
	#children;
	#patterns;
	#order = 0;
	#params = emptyParams;
	constructor(method, handler, children) {
		this.#children = children || /* @__PURE__ */ Object.create(null);
		this.#methods = [];
		if (method && handler) {
			const m = /* @__PURE__ */ Object.create(null);
			m[method] = {
				handler,
				possibleKeys: [],
				score: 0
			};
			this.#methods = [m];
		}
		this.#patterns = [];
	}
	insert(method, path, handler) {
		this.#order = ++this.#order;
		let curNode = this;
		const parts = splitRoutingPath(path);
		const possibleKeys = [];
		for (let i = 0, len = parts.length; i < len; i++) {
			const p = parts[i];
			const nextP = parts[i + 1];
			const pattern = getPattern(p, nextP);
			const key = Array.isArray(pattern) ? pattern[0] : p;
			if (key in curNode.#children) {
				curNode = curNode.#children[key];
				if (pattern) possibleKeys.push(pattern[1]);
				continue;
			}
			curNode.#children[key] = new _Node();
			if (pattern) {
				curNode.#patterns.push(pattern);
				possibleKeys.push(pattern[1]);
			}
			curNode = curNode.#children[key];
		}
		curNode.#methods.push({ [method]: {
			handler,
			possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
			score: this.#order
		} });
		return curNode;
	}
	#pushHandlerSets(handlerSets, node, method, nodeParams, params) {
		for (let i = 0, len = node.#methods.length; i < len; i++) {
			const m = node.#methods[i];
			const handlerSet = m[method] || m["ALL"];
			const processedSet = {};
			if (handlerSet !== void 0) {
				handlerSet.params = /* @__PURE__ */ Object.create(null);
				handlerSets.push(handlerSet);
				if (nodeParams !== emptyParams || params && params !== emptyParams) for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
					const key = handlerSet.possibleKeys[i2];
					const processed = processedSet[handlerSet.score];
					handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
					processedSet[handlerSet.score] = true;
				}
			}
		}
	}
	search(method, path) {
		const handlerSets = [];
		this.#params = emptyParams;
		let curNodes = [this];
		const parts = splitPath(path);
		const curNodesQueue = [];
		const len = parts.length;
		let partOffsets = null;
		for (let i = 0; i < len; i++) {
			const part = parts[i];
			const isLast = i === len - 1;
			const tempNodes = [];
			for (let j = 0, len2 = curNodes.length; j < len2; j++) {
				const node = curNodes[j];
				const nextNode = node.#children[part];
				if (nextNode) {
					nextNode.#params = node.#params;
					if (isLast) {
						if (nextNode.#children["*"]) this.#pushHandlerSets(handlerSets, nextNode.#children["*"], method, node.#params);
						this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);
					} else tempNodes.push(nextNode);
				}
				for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {
					const pattern = node.#patterns[k];
					const params = node.#params === emptyParams ? {} : { ...node.#params };
					if (pattern === "*") {
						const astNode = node.#children["*"];
						if (astNode) {
							this.#pushHandlerSets(handlerSets, astNode, method, node.#params);
							astNode.#params = params;
							tempNodes.push(astNode);
						}
						continue;
					}
					const [key, name, matcher] = pattern;
					if (!part && !(matcher instanceof RegExp)) continue;
					const child = node.#children[key];
					if (matcher instanceof RegExp) {
						if (partOffsets === null) {
							partOffsets = new Array(len);
							let offset = path[0] === "/" ? 1 : 0;
							for (let p = 0; p < len; p++) {
								partOffsets[p] = offset;
								offset += parts[p].length + 1;
							}
						}
						const restPathString = path.substring(partOffsets[i]);
						const m = matcher.exec(restPathString);
						if (m) {
							params[name] = m[0];
							this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
							if (m[0].length === restPathString.length && child.#children["*"]) this.#pushHandlerSets(handlerSets, child.#children["*"], method, node.#params, params);
							if (hasChildren(child.#children)) {
								child.#params = params;
								const componentCount = m[0].match(/\//)?.length ?? 0;
								(curNodesQueue[componentCount] ||= []).push(child);
							}
							continue;
						}
					}
					if (matcher === true || matcher.test(part)) {
						params[name] = part;
						if (isLast) {
							this.#pushHandlerSets(handlerSets, child, method, params, node.#params);
							if (child.#children["*"]) this.#pushHandlerSets(handlerSets, child.#children["*"], method, params, node.#params);
						} else {
							child.#params = params;
							tempNodes.push(child);
						}
					}
				}
			}
			const shifted = curNodesQueue.shift();
			curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
		}
		if (handlerSets.length > 1) handlerSets.sort((a, b) => {
			return a.score - b.score;
		});
		return [handlerSets.map(({ handler, params }) => [handler, params])];
	}
};
//#endregion
//#region node_modules/hono/dist/router/trie-router/router.js
var TrieRouter = class {
	name = "TrieRouter";
	#node;
	constructor() {
		this.#node = new Node();
	}
	add(method, path, handler) {
		const results = checkOptionalParameter(path);
		if (results) {
			for (let i = 0, len = results.length; i < len; i++) this.#node.insert(method, results[i], handler);
			return;
		}
		this.#node.insert(method, path, handler);
	}
	match(method, path) {
		return this.#node.search(method, path);
	}
};
//#endregion
//#region node_modules/hono/dist/hono.js
var Hono = class extends Hono$1 {
	/**
	* Creates an instance of the Hono class.
	*
	* @param options - Optional configuration options for the Hono instance.
	*/
	constructor(options = {}) {
		super(options);
		this.router = options.router ?? new SmartRouter({ routers: [new RegExpRouter(), new TrieRouter()] });
	}
};
//#endregion
//#region node_modules/hono/dist/middleware/cors/index.js
var cors = (options) => {
	const opts = {
		origin: "*",
		allowMethods: [
			"GET",
			"HEAD",
			"PUT",
			"POST",
			"DELETE",
			"PATCH"
		],
		allowHeaders: [],
		exposeHeaders: [],
		...options
	};
	const findAllowOrigin = ((optsOrigin) => {
		if (typeof optsOrigin === "string") if (optsOrigin === "*") return () => optsOrigin;
		else return (origin) => optsOrigin === origin ? origin : null;
		else if (typeof optsOrigin === "function") return optsOrigin;
		else return (origin) => optsOrigin.includes(origin) ? origin : null;
	})(opts.origin);
	const findAllowMethods = ((optsAllowMethods) => {
		if (typeof optsAllowMethods === "function") return optsAllowMethods;
		else if (Array.isArray(optsAllowMethods)) return () => optsAllowMethods;
		else return () => [];
	})(opts.allowMethods);
	return async function cors2(c, next) {
		function set(key, value) {
			c.res.headers.set(key, value);
		}
		const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
		if (allowOrigin) set("Access-Control-Allow-Origin", allowOrigin);
		if (opts.credentials) set("Access-Control-Allow-Credentials", "true");
		if (opts.exposeHeaders?.length) set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
		if (c.req.method === "OPTIONS") {
			if (opts.origin !== "*") set("Vary", "Origin");
			if (opts.maxAge != null) set("Access-Control-Max-Age", opts.maxAge.toString());
			const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
			if (allowMethods.length) set("Access-Control-Allow-Methods", allowMethods.join(","));
			let headers = opts.allowHeaders;
			if (!headers?.length) {
				const requestHeaders = c.req.header("Access-Control-Request-Headers");
				if (requestHeaders) headers = requestHeaders.split(",").map((h) => h.trim());
			}
			if (headers?.length) {
				set("Access-Control-Allow-Headers", headers.join(","));
				c.res.headers.append("Vary", "Access-Control-Request-Headers");
			}
			c.res.headers.delete("Content-Length");
			c.res.headers.delete("Content-Type");
			return new Response(null, {
				headers: c.res.headers,
				status: 204,
				statusText: "No Content"
			});
		}
		await next();
		if (opts.origin !== "*") c.header("Vary", "Origin", { append: true });
	};
};
//#endregion
//#region node_modules/hono/dist/utils/stream.js
var StreamingApi = class {
	writer;
	encoder;
	writable;
	abortSubscribers = [];
	responseReadable;
	/**
	* Whether the stream has been aborted.
	*/
	aborted = false;
	/**
	* Whether the stream has been closed normally.
	*/
	closed = false;
	constructor(writable, _readable) {
		this.writable = writable;
		this.writer = writable.getWriter();
		this.encoder = new TextEncoder();
		const reader = _readable.getReader();
		this.abortSubscribers.push(async () => {
			await reader.cancel();
		});
		this.responseReadable = new ReadableStream({
			async pull(controller) {
				const { done, value } = await reader.read();
				done ? controller.close() : controller.enqueue(value);
			},
			cancel: () => {
				if (!this.closed) this.abort();
			}
		});
	}
	async write(input) {
		try {
			if (typeof input === "string") input = this.encoder.encode(input);
			await this.writer.write(input);
		} catch {}
		return this;
	}
	async writeln(input) {
		await this.write(input + "\n");
		return this;
	}
	sleep(ms) {
		return new Promise((res) => setTimeout(res, ms));
	}
	async close() {
		this.closed = true;
		try {
			await this.writer.close();
		} catch {}
	}
	async pipe(body) {
		this.writer.releaseLock();
		await body.pipeTo(this.writable, { preventClose: true });
		this.writer = this.writable.getWriter();
	}
	onAbort(listener) {
		this.abortSubscribers.push(listener);
	}
	/**
	* Abort the stream.
	* You can call this method when stream is aborted by external event.
	*/
	abort() {
		if (!this.aborted) {
			this.aborted = true;
			this.abortSubscribers.forEach((subscriber) => subscriber());
		}
	}
};
//#endregion
//#region node_modules/hono/dist/helper/streaming/utils.js
var isOldBunVersion = () => {
	const version = typeof Bun !== "undefined" ? Bun.version : void 0;
	if (version === void 0) return false;
	const result = version.startsWith("1.1") || version.startsWith("1.0") || version.startsWith("0.");
	isOldBunVersion = () => result;
	return result;
};
//#endregion
//#region node_modules/hono/dist/helper/streaming/sse.js
var SSEStreamingApi = class extends StreamingApi {
	constructor(writable, readable) {
		super(writable, readable);
	}
	async writeSSE(message) {
		const dataLines = (await resolveCallback(message.data, HtmlEscapedCallbackPhase.Stringify, false, {})).split(/\r\n|\r|\n/).map((line) => {
			return `data: ${line}`;
		}).join("\n");
		for (const key of ["event", "id"]) {
			const value = message[key];
			if (value && /[\r\n]/.test(value)) throw new Error(`${key} must not contain "\\r" or "\\n"`);
		}
		const sseData = [
			message.event && `event: ${message.event}`,
			dataLines,
			message.id !== void 0 && `id: ${message.id}`,
			message.retry !== void 0 && `retry: ${message.retry}`
		].filter(Boolean).join("\n") + "\n\n";
		await this.write(sseData);
	}
};
var run = async (stream, cb, onError) => {
	try {
		await cb(stream);
	} catch (e) {
		if (e instanceof Error && onError) {
			await onError(e, stream);
			await stream.writeSSE({
				event: "error",
				data: e.message
			});
		} else console.error(e);
	} finally {
		stream.close();
	}
};
var contextStash = /* @__PURE__ */ new WeakMap();
var streamSSE = (c, cb, onError) => {
	const { readable, writable } = new TransformStream();
	const stream = new SSEStreamingApi(writable, readable);
	if (isOldBunVersion()) c.req.raw.signal.addEventListener("abort", () => {
		if (!stream.closed) stream.abort();
	});
	contextStash.set(stream.responseReadable, c);
	c.header("Transfer-Encoding", "chunked");
	c.header("Content-Type", "text/event-stream");
	c.header("Cache-Control", "no-cache");
	c.header("Connection", "keep-alive");
	run(stream, cb, onError);
	return c.newResponse(stream.responseReadable);
};
//#endregion
//#region node_modules/hono/dist/helper/websocket/index.js
var defineWebSocketHelper = (handler) => {
	return ((...args) => {
		if (typeof args[0] === "function") {
			const [createEvents, options] = args;
			return async function upgradeWebSocket(c, next) {
				const result = await handler(c, await createEvents(c), options);
				if (result) return result;
				await next();
			};
		} else {
			const [c, events, options] = args;
			return (async () => {
				const upgraded = await handler(c, events, options);
				if (!upgraded) throw new Error("Failed to upgrade WebSocket");
				return upgraded;
			})();
		}
	});
};
//#endregion
//#region node_modules/@hono/node-server/dist/index.mjs
var RequestError = class extends Error {
	constructor(message, options) {
		super(message, options);
		this.name = "RequestError";
	}
};
var reValidRequestUrl = /^\/[!#$&-;=?-\[\]_a-z~]*$/;
var reDotSegment = /\/\.\.?(?:[/?#]|$)/;
var reValidHost = /^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/;
var buildUrl = (scheme, host, incomingUrl) => {
	const url = `${scheme}://${host}${incomingUrl}`;
	if (!reValidHost.test(host)) {
		const urlObj = new URL(url);
		if (urlObj.hostname.length !== host.length && urlObj.hostname !== (host.includes(":") ? host.replace(/:\d+$/, "") : host).toLowerCase()) throw new RequestError("Invalid host header");
		return urlObj.href;
	} else if (incomingUrl.length === 0) return url + "/";
	else {
		if (incomingUrl.charCodeAt(0) !== 47) throw new RequestError("Invalid URL");
		if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) return new URL(url).href;
		return url;
	}
};
var toRequestError = (e) => {
	if (e instanceof RequestError) return e;
	return new RequestError(e.message, { cause: e });
};
var GlobalRequest = global.Request;
var Request$1 = class extends GlobalRequest {
	constructor(input, options) {
		if (typeof input === "object" && getRequestCache in input) {
			const hasReplacementBody = options !== void 0 && "body" in options && options.body != null;
			if (input[bodyConsumedDirectlyKey] && !hasReplacementBody) throw new TypeError("Cannot construct a Request with a Request object that has already been used.");
			input = input[getRequestCache]();
		}
		if (typeof (options?.body)?.getReader !== "undefined") options.duplex ??= "half";
		super(input, options);
	}
};
var newHeadersFromIncoming = (incoming) => {
	const headerRecord = [];
	const rawHeaders = incoming.rawHeaders;
	for (let i = 0, len = rawHeaders.length; i < len; i += 2) {
		const key = rawHeaders[i];
		if (key.charCodeAt(0) !== 58) headerRecord.push([key, rawHeaders[i + 1]]);
	}
	return new Headers(headerRecord);
};
var wrapBodyStream = Symbol("wrapBodyStream");
var byteExactEncodings = /* @__PURE__ */ new Set([
	"latin1",
	"binary",
	"hex",
	"base64",
	"base64url"
]);
var isByteExactEncoding = (encoding) => encoding === null || byteExactEncodings.has(encoding);
var bodyBufferedBeforeDisconnectKey = Symbol("bodyBufferedBeforeDisconnect");
var bodyBufferedLengthBeforeDisconnectKey = Symbol("bodyBufferedLengthBeforeDisconnect");
var toBufferChunk = (chunk, encoding) => Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding ?? "utf8");
var isRecoverableDisconnectedIncoming = (incoming) => !(incoming instanceof Http2ServerRequest) && !!incoming.complete && !!incoming.readableAborted && typeof incoming.read === "function" && isByteExactEncoding(incoming.readableEncoding);
var recordBodyBufferedBeforeDisconnect = (incoming) => {
	if (incoming.readableDidRead || !isRecoverableDisconnectedIncoming(incoming)) return;
	const incomingWithRecovery = incoming;
	incomingWithRecovery[bodyBufferedLengthBeforeDisconnectKey] ??= incoming.readableLength;
};
var readBodyBufferedBeforeDisconnect = (incoming, chunks) => {
	if (incoming.readableDidRead && !chunks || !isRecoverableDisconnectedIncoming(incoming)) return;
	const incomingWithRecovery = incoming;
	if (incomingWithRecovery[bodyBufferedBeforeDisconnectKey] !== void 0) return incomingWithRecovery[bodyBufferedBeforeDisconnectKey];
	let result;
	const errored = incoming.errored;
	if (errored && errored.code !== "ECONNRESET") result = errored;
	else if (incomingWithRecovery[bodyBufferedLengthBeforeDisconnectKey] !== void 0 && incoming.readableLength !== incomingWithRecovery[bodyBufferedLengthBeforeDisconnectKey]) result = newBodyUnusableError();
	else {
		const bodyChunks = chunks ?? [];
		const chunk = incoming.read();
		if (chunk !== null) bodyChunks.push(toBufferChunk(chunk, incoming.readableEncoding));
		const buffer = bodyChunks.length === 1 ? bodyChunks[0] : Buffer.concat(bodyChunks);
		result = buffer;
		const contentLength = incoming.headers["content-length"];
		if (typeof contentLength === "string" && /^\d+$/.test(contentLength)) {
			const expectedLength = Number(contentLength);
			if (Number.isSafeInteger(expectedLength) && buffer.length !== expectedLength) result = newBodyUnusableError();
		}
	}
	incomingWithRecovery[bodyBufferedBeforeDisconnectKey] = result;
	return result;
};
var enqueueBufferedBody = (controller, buffered) => {
	if (buffered instanceof Error) {
		controller.error(buffered);
		return;
	}
	if (buffered.length > 0) controller.enqueue(buffered);
	controller.close();
};
var newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
	const init = {
		method,
		headers,
		signal: abortController.signal
	};
	if (method === "TRACE") {
		init.method = "GET";
		const req = new Request$1(url, init);
		Object.defineProperty(req, "method", { get() {
			return "TRACE";
		} });
		return req;
	}
	if (!(method === "GET" || method === "HEAD")) if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) init.body = new ReadableStream({ start(controller) {
		controller.enqueue(incoming.rawBody);
		controller.close();
	} });
	else if (incoming[wrapBodyStream]) {
		let reader;
		init.body = new ReadableStream({ async pull(controller) {
			try {
				if (!reader) {
					const buffered = readBodyBufferedBeforeDisconnect(incoming);
					if (buffered !== void 0) {
						enqueueBufferedBody(controller, buffered);
						return;
					}
				}
				reader ||= Readable.toWeb(incoming).getReader();
				const { done, value } = await reader.read();
				if (done) controller.close();
				else controller.enqueue(value);
			} catch (error) {
				controller.error(error);
			}
		} });
	} else {
		const buffered = readBodyBufferedBeforeDisconnect(incoming);
		if (buffered !== void 0) init.body = new ReadableStream({ start(controller) {
			enqueueBufferedBody(controller, buffered);
		} });
		else init.body = Readable.toWeb(incoming);
	}
	return new Request$1(url, init);
};
var getRequestCache = Symbol("getRequestCache");
var requestCache = Symbol("requestCache");
var incomingKey = Symbol("incomingKey");
var urlKey = Symbol("urlKey");
var methodKey = Symbol("methodKey");
var headersKey = Symbol("headersKey");
var abortControllerKey = Symbol("abortControllerKey");
var getAbortController = Symbol("getAbortController");
var abortRequest = Symbol("abortRequest");
var bodyBufferKey = Symbol("bodyBuffer");
var bodyReadPromiseKey = Symbol("bodyReadPromise");
var bodyConsumedDirectlyKey = Symbol("bodyConsumedDirectly");
var bodyLockReaderKey = Symbol("bodyLockReader");
var abortReasonKey = Symbol("abortReason");
var newBodyUnusableError = () => {
	return /* @__PURE__ */ new TypeError("Body is unusable");
};
var rejectBodyUnusable = () => {
	return Promise.reject(newBodyUnusableError());
};
var textDecoder = new TextDecoder();
var consumeBodyDirectOnce = (request) => {
	if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
	request[bodyConsumedDirectlyKey] = true;
};
var toArrayBuffer = (buf) => {
	return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
};
var contentType = (request) => {
	return (request[headersKey] ||= newHeadersFromIncoming(request[incomingKey])).get("content-type") || "";
};
var methodTokenRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
var normalizeIncomingMethod = (method) => {
	if (typeof method !== "string" || method.length === 0) return "GET";
	switch (method) {
		case "DELETE":
		case "GET":
		case "HEAD":
		case "OPTIONS":
		case "PATCH":
		case "POST":
		case "PUT":
		case "QUERY": return method;
	}
	const upper = method.toUpperCase();
	switch (upper) {
		case "DELETE":
		case "GET":
		case "HEAD":
		case "OPTIONS":
		case "POST":
		case "PUT": return upper;
		default: return method;
	}
};
var validateDirectReadMethod = (method) => {
	if (!methodTokenRegExp.test(method)) return /* @__PURE__ */ new TypeError(`'${method}' is not a valid HTTP method.`);
	const normalized = method.toUpperCase();
	if (normalized === "CONNECT" || normalized === "TRACK" || normalized === "TRACE" && method !== "TRACE") return /* @__PURE__ */ new TypeError(`'${method}' HTTP method is unsupported.`);
};
var readBodyWithFastPath = (request, method, fromBuffer) => {
	if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
	const methodName = request.method;
	if (methodName === "GET" || methodName === "HEAD") return request[getRequestCache]()[method]();
	const methodValidationError = validateDirectReadMethod(methodName);
	if (methodValidationError) return Promise.reject(methodValidationError);
	if (request[requestCache]) {
		if (methodName !== "TRACE") return request[requestCache][method]();
	}
	const alreadyUsedError = consumeBodyDirectOnce(request);
	if (alreadyUsedError) return alreadyUsedError;
	const raw = readRawBodyIfAvailable(request);
	if (raw) {
		const result = Promise.resolve(fromBuffer(raw, request));
		request[bodyBufferKey] = void 0;
		return result;
	}
	return readBodyDirect(request).then((buf) => {
		const result = fromBuffer(buf, request);
		request[bodyBufferKey] = void 0;
		return result;
	});
};
var readRawBodyIfAvailable = (request) => {
	const incoming = request[incomingKey];
	if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) return incoming.rawBody;
};
var normalizeAbortError = (request, incoming) => {
	if (incoming.errored) return incoming.errored;
	const reason = request[abortReasonKey];
	if (reason !== void 0) return reason instanceof Error ? reason : new Error(String(reason));
	return /* @__PURE__ */ new Error("Client connection prematurely closed.");
};
var readBodyDirect = (request) => {
	if (request[bodyBufferKey]) return Promise.resolve(request[bodyBufferKey]);
	if (request[bodyReadPromiseKey]) return request[bodyReadPromiseKey];
	const incoming = request[incomingKey];
	if (incoming.readableDidRead) return rejectBodyUnusable();
	const buffered = readBodyBufferedBeforeDisconnect(incoming);
	if (buffered !== void 0) {
		if (buffered instanceof Error) return Promise.reject(buffered);
		request[bodyBufferKey] = buffered;
		return Promise.resolve(buffered);
	}
	const promise = new Promise((resolve, reject) => {
		const chunks = [];
		let settled = false;
		const finish = (callback) => {
			if (settled) return;
			settled = true;
			cleanup();
			callback();
		};
		const recoverCompleteBodyAfterDisconnect = (error) => {
			const streamError = incoming.errored ?? error;
			if (!isRecoverableDisconnectedIncoming(incoming) || streamError && streamError.code !== "ECONNRESET") return false;
			finish(() => {
				const recovered = readBodyBufferedBeforeDisconnect(incoming, chunks);
				if (recovered instanceof Error) reject(recovered);
				else if (recovered === void 0) reject(error ?? normalizeAbortError(request, incoming));
				else {
					request[bodyBufferKey] = recovered;
					resolve(recovered);
				}
			});
			return true;
		};
		const onData = (chunk) => {
			chunks.push(toBufferChunk(chunk, incoming.readableEncoding));
		};
		const onEnd = () => {
			finish(() => {
				const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
				request[bodyBufferKey] = buffer;
				resolve(buffer);
			});
		};
		const onError = (error) => {
			if (recoverCompleteBodyAfterDisconnect(error)) return;
			finish(() => {
				reject(error);
			});
		};
		const onClose = () => {
			if (incoming.readableEnded) {
				onEnd();
				return;
			}
			if (recoverCompleteBodyAfterDisconnect()) return;
			finish(() => {
				reject(normalizeAbortError(request, incoming));
			});
		};
		const cleanup = () => {
			incoming.off("data", onData);
			incoming.off("end", onEnd);
			incoming.off("error", onError);
			incoming.off("close", onClose);
			request[bodyReadPromiseKey] = void 0;
		};
		incoming.on("data", onData);
		incoming.on("end", onEnd);
		incoming.on("error", onError);
		incoming.on("close", onClose);
		queueMicrotask(() => {
			if (settled) return;
			if (incoming.readableEnded) onEnd();
			else if (incoming.errored) onError(incoming.errored);
			else if (incoming.destroyed) onClose();
		});
	});
	request[bodyReadPromiseKey] = promise;
	return promise;
};
var requestPrototype = {
	get method() {
		return this[methodKey];
	},
	get url() {
		return this[urlKey];
	},
	get headers() {
		return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
	},
	[abortRequest](reason) {
		if (this[abortReasonKey] === void 0) this[abortReasonKey] = reason;
		const abortController = this[abortControllerKey];
		if (abortController && !abortController.signal.aborted) abortController.abort(reason);
	},
	[getAbortController]() {
		this[abortControllerKey] ||= new AbortController();
		if (this[abortReasonKey] !== void 0 && !this[abortControllerKey].signal.aborted) this[abortControllerKey].abort(this[abortReasonKey]);
		return this[abortControllerKey];
	},
	[getRequestCache]() {
		const abortController = this[getAbortController]();
		if (this[requestCache]) return this[requestCache];
		const method = this.method;
		if (this[bodyConsumedDirectlyKey] && !(method === "GET" || method === "HEAD")) {
			this[bodyBufferKey] = void 0;
			const init = {
				method: method === "TRACE" ? "GET" : method,
				headers: this.headers,
				signal: abortController.signal
			};
			if (method !== "TRACE") {
				init.body = new ReadableStream({ start(c) {
					c.close();
				} });
				init.duplex = "half";
			}
			const req = new Request$1(this[urlKey], init);
			if (method === "TRACE") Object.defineProperty(req, "method", { get() {
				return "TRACE";
			} });
			return this[requestCache] = req;
		}
		return this[requestCache] = newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], abortController);
	},
	get body() {
		if (!this[bodyConsumedDirectlyKey]) return this[getRequestCache]().body;
		const request = this[getRequestCache]();
		if (!this[bodyLockReaderKey] && request.body) this[bodyLockReaderKey] = request.body.getReader();
		return request.body;
	},
	get bodyUsed() {
		if (this[bodyConsumedDirectlyKey]) return true;
		if (this[requestCache]) return this[requestCache].bodyUsed;
		return false;
	}
};
Object.defineProperty(requestPrototype, "signal", { get() {
	return this[getAbortController]().signal;
} });
[
	"cache",
	"credentials",
	"destination",
	"integrity",
	"mode",
	"redirect",
	"referrer",
	"referrerPolicy",
	"keepalive"
].forEach((k) => {
	Object.defineProperty(requestPrototype, k, { get() {
		return this[getRequestCache]()[k];
	} });
});
["clone", "formData"].forEach((k) => {
	Object.defineProperty(requestPrototype, k, { value: function() {
		if (this[bodyConsumedDirectlyKey]) {
			if (k === "clone") throw newBodyUnusableError();
			return rejectBodyUnusable();
		}
		return this[getRequestCache]()[k]();
	} });
});
Object.defineProperty(requestPrototype, "text", { value: function() {
	return readBodyWithFastPath(this, "text", (buf) => textDecoder.decode(buf));
} });
Object.defineProperty(requestPrototype, "arrayBuffer", { value: function() {
	return readBodyWithFastPath(this, "arrayBuffer", (buf) => toArrayBuffer(buf));
} });
Object.defineProperty(requestPrototype, "blob", { value: function() {
	return readBodyWithFastPath(this, "blob", (buf, request) => {
		const type = contentType(request);
		return new Response(buf, type ? { headers: { "content-type": type } } : void 0).blob();
	});
} });
Object.defineProperty(requestPrototype, "json", { value: function() {
	if (this[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
	return this.text().then(JSON.parse);
} });
Object.defineProperty(requestPrototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
	return `Request (lightweight) ${inspectFn({
		method: this.method,
		url: this.url,
		headers: this.headers,
		nativeRequest: this[requestCache]
	}, {
		...options,
		depth: depth == null ? null : depth - 1
	})}`;
} });
Object.setPrototypeOf(requestPrototype, Request$1.prototype);
var newRequest = (incoming, defaultHostname) => {
	const req = Object.create(requestPrototype);
	req[incomingKey] = incoming;
	req[methodKey] = normalizeIncomingMethod(incoming.method);
	const incomingUrl = incoming.url || "";
	if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
		if (incoming instanceof Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
		try {
			req[urlKey] = new URL(incomingUrl).href;
		} catch (e) {
			throw new RequestError("Invalid absolute URL", { cause: e });
		}
		return req;
	}
	const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
	if (!host) throw new RequestError("Missing host header");
	let scheme;
	if (incoming instanceof Http2ServerRequest) {
		scheme = incoming.scheme;
		if (!(scheme === "http" || scheme === "https")) throw new RequestError("Unsupported scheme");
	} else scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
	try {
		req[urlKey] = buildUrl(scheme, host, incomingUrl);
	} catch (e) {
		if (e instanceof RequestError) throw e;
		else throw new RequestError("Invalid URL", { cause: e });
	}
	return req;
};
var defaultContentType = "text/plain; charset=UTF-8";
var responseCache = Symbol("responseCache");
var getResponseCache = Symbol("getResponseCache");
var cacheKey = Symbol("cache");
var GlobalResponse = global.Response;
var Response$1 = class Response$1 {
	#body;
	#init;
	[getResponseCache]() {
		const cache = this[cacheKey];
		const liveHeaders = cache && cache[2] instanceof Headers ? cache[2] : void 0;
		delete this[cacheKey];
		return this[responseCache] ||= new GlobalResponse(this.#body, liveHeaders ? {
			status: this.#init?.status,
			statusText: this.#init?.statusText,
			headers: liveHeaders
		} : this.#init);
	}
	constructor(body, init) {
		let headers;
		this.#body = body;
		if (init instanceof GlobalResponse) {
			const cachedGlobalResponse = init[responseCache];
			if (cachedGlobalResponse) {
				this.#init = cachedGlobalResponse;
				this[getResponseCache]();
				return;
			}
			this.#init = init instanceof Response$1 ? init.#init : init;
			headers = new Headers(init.headers);
		} else this.#init = init;
		if (body == null || typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) this[cacheKey] = [
			init?.status || 200,
			body ?? null,
			headers || init?.headers
		];
	}
	get headers() {
		const cache = this[cacheKey];
		if (cache) {
			if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2] || (cache[1] === null ? void 0 : { "content-type": defaultContentType }));
			return cache[2];
		}
		return this[getResponseCache]().headers;
	}
	get status() {
		return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
	}
	get ok() {
		const status = this.status;
		return status >= 200 && status < 300;
	}
};
[
	"body",
	"bodyUsed",
	"redirected",
	"statusText",
	"trailers",
	"type",
	"url"
].forEach((k) => {
	Object.defineProperty(Response$1.prototype, k, { get() {
		return this[getResponseCache]()[k];
	} });
});
[
	"arrayBuffer",
	"blob",
	"clone",
	"formData",
	"json",
	"text"
].forEach((k) => {
	Object.defineProperty(Response$1.prototype, k, { value: function() {
		return this[getResponseCache]()[k]();
	} });
});
Object.defineProperty(Response$1.prototype, Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
	return `Response (lightweight) ${inspectFn({
		status: this.status,
		headers: this.headers,
		ok: this.ok,
		nativeResponse: this[responseCache]
	}, {
		...options,
		depth: depth == null ? null : depth - 1
	})}`;
} });
Object.setPrototypeOf(Response$1, GlobalResponse);
Object.setPrototypeOf(Response$1.prototype, GlobalResponse.prototype);
var validRedirectUrl = /^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/;
var parseRedirectUrl = (url) => {
	if (url instanceof URL) return url.href;
	if (validRedirectUrl.test(url)) return url;
	return new URL(url).href;
};
var validRedirectStatuses = /* @__PURE__ */ new Set([
	301,
	302,
	303,
	307,
	308
]);
Object.defineProperty(Response$1, "redirect", {
	value: function redirect(url, status = 302) {
		if (!validRedirectStatuses.has(status)) throw new RangeError("Invalid status code");
		return new Response$1(null, {
			status,
			headers: { location: parseRedirectUrl(url) }
		});
	},
	writable: true,
	configurable: true
});
Object.defineProperty(Response$1, "json", {
	value: function json(data, init) {
		const body = JSON.stringify(data);
		if (body === void 0) throw new TypeError("The data is not JSON serializable");
		const initHeaders = init?.headers;
		let headers;
		if (initHeaders) {
			headers = new Headers(initHeaders);
			if (!headers.has("content-type")) headers.set("content-type", "application/json");
		} else headers = { "content-type": "application/json" };
		return new Response$1(body, {
			status: init?.status ?? 200,
			statusText: init?.statusText,
			headers
		});
	},
	writable: true,
	configurable: true
});
async function readWithoutBlocking(readPromise) {
	return Promise.race([readPromise, Promise.resolve().then(() => Promise.resolve(void 0))]);
}
function writeFromReadableStreamDefaultReader(reader, writable, currentReadPromise) {
	const cancel = (error) => {
		reader.cancel(error).catch(() => {});
	};
	writable.on("close", cancel);
	writable.on("error", cancel);
	(currentReadPromise ?? reader.read()).then(flow, handleStreamError);
	return reader.closed.finally(() => {
		writable.off("close", cancel);
		writable.off("error", cancel);
	});
	function handleStreamError(error) {
		if (error) writable.destroy(error);
	}
	function onDrain() {
		reader.read().then(flow, handleStreamError);
	}
	function flow({ done, value }) {
		try {
			if (done) writable.end();
			else if (!writable.write(value)) writable.once("drain", onDrain);
			else return reader.read().then(flow, handleStreamError);
		} catch (e) {
			handleStreamError(e);
		}
	}
}
function writeFromReadableStream(stream, writable) {
	if (stream.locked) throw new TypeError("ReadableStream is locked.");
	else if (writable.destroyed) return;
	return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
}
var buildOutgoingHttpHeaders = (headers, defaultContentType) => {
	const res = {};
	if (!(headers instanceof Headers)) headers = new Headers(headers ?? void 0);
	if (headers.has("set-cookie")) {
		const cookies = [];
		for (const [k, v] of headers) if (k === "set-cookie") cookies.push(v);
		else res[k] = v;
		if (cookies.length > 0) res["set-cookie"] = cookies;
	} else for (const [k, v] of headers) res[k] = v;
	if (defaultContentType) res["content-type"] ??= defaultContentType;
	return res;
};
var outgoingEnded = Symbol("outgoingEnded");
var incomingDraining = Symbol("incomingDraining");
var DRAIN_TIMEOUT_MS = 500;
var MAX_DRAIN_BYTES = 67108864;
var drainIncoming = (incoming) => {
	const incomingWithDrainState = incoming;
	if (incoming.destroyed || incomingWithDrainState[incomingDraining]) return;
	incomingWithDrainState[incomingDraining] = true;
	if (incoming instanceof Http2ServerRequest) {
		try {
			incoming.stream?.close?.(constants.NGHTTP2_NO_ERROR);
		} catch {}
		return;
	}
	let bytesRead = 0;
	const cleanup = () => {
		clearTimeout(timer);
		incoming.off("data", onData);
		incoming.off("end", cleanup);
		incoming.off("error", cleanup);
	};
	const forceClose = () => {
		cleanup();
		const socket = incoming.socket;
		if (socket && !socket.destroyed) socket.destroySoon();
	};
	const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
	timer.unref?.();
	const onData = (chunk) => {
		bytesRead += chunk.length;
		if (bytesRead > MAX_DRAIN_BYTES) forceClose();
	};
	incoming.on("data", onData);
	incoming.on("end", cleanup);
	incoming.on("error", cleanup);
	incoming.resume();
};
var makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
	if (incoming.errored) {
		recordBodyBufferedBeforeDisconnect(incoming);
		req[abortRequest](incoming.errored.toString());
	} else if (!outgoing.writableFinished) {
		recordBodyBufferedBeforeDisconnect(incoming);
		req[abortRequest]("Client connection prematurely closed.");
	}
	if (needsBodyCleanup && !incoming.readableEnded) setTimeout(() => {
		if (!incoming.readableEnded) setTimeout(() => {
			drainIncoming(incoming);
		});
	});
};
var isImmediateCacheableResponse = (res) => {
	if (!(cacheKey in res)) return false;
	const body = res[cacheKey][1];
	return body === null || typeof body === "string" || body instanceof Uint8Array;
};
var handleRequestError = () => new Response(null, { status: 400 });
var handleFetchError = (e) => new Response(null, { status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 });
var handleResponseError = (e, outgoing) => {
	const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
	if (err.code === "ERR_STREAM_PREMATURE_CLOSE") console.info("The user aborted a request.");
	else {
		console.error(e);
		if (!outgoing.headersSent) outgoing.writeHead(500, { "Content-Type": "text/plain" });
		outgoing.end(`Error: ${err.message}`);
		outgoing.destroy(err);
	}
};
var flushHeaders = (outgoing) => {
	if ("flushHeaders" in outgoing && outgoing.writable) outgoing.flushHeaders();
};
var responseViaCache = async (res, outgoing) => {
	let [status, body, header] = res[cacheKey];
	if (!header) {
		if (body === null) {
			outgoing.writeHead(status);
			outgoing.end();
		} else if (typeof body === "string") {
			outgoing.writeHead(status, {
				"Content-Type": defaultContentType,
				"Content-Length": Buffer.byteLength(body)
			});
			outgoing.end(body);
		} else if (body instanceof Uint8Array) {
			outgoing.writeHead(status, {
				"Content-Type": defaultContentType,
				"Content-Length": body.byteLength
			});
			outgoing.end(body);
		} else if (body instanceof Blob) {
			outgoing.writeHead(status, {
				"Content-Type": defaultContentType,
				"Content-Length": body.size
			});
			outgoing.end(new Uint8Array(await body.arrayBuffer()));
		} else {
			outgoing.writeHead(status, { "Content-Type": defaultContentType });
			flushHeaders(outgoing);
			await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
		}
		outgoing[outgoingEnded]?.();
		return;
	}
	let hasContentLength = false;
	if (header instanceof Headers) {
		hasContentLength = header.has("content-length");
		header = buildOutgoingHttpHeaders(header, body === null ? void 0 : defaultContentType);
	} else if (Array.isArray(header)) {
		const headerObj = new Headers(header);
		hasContentLength = headerObj.has("content-length");
		header = buildOutgoingHttpHeaders(headerObj, body === null ? void 0 : defaultContentType);
	} else for (const key in header) if (key.length === 14 && key.toLowerCase() === "content-length") {
		hasContentLength = true;
		break;
	}
	if (!hasContentLength) {
		if (typeof body === "string") header["Content-Length"] = Buffer.byteLength(body);
		else if (body instanceof Uint8Array) header["Content-Length"] = body.byteLength;
		else if (body instanceof Blob) header["Content-Length"] = body.size;
	}
	outgoing.writeHead(status, header);
	if (body == null) outgoing.end();
	else if (typeof body === "string" || body instanceof Uint8Array) outgoing.end(body);
	else if (body instanceof Blob) outgoing.end(new Uint8Array(await body.arrayBuffer()));
	else {
		flushHeaders(outgoing);
		await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
	}
	outgoing[outgoingEnded]?.();
};
var isPromise = (res) => typeof res.then === "function";
var responseViaResponseObject = async (res, outgoing, options = {}) => {
	if (isPromise(res)) if (options.errorHandler) try {
		res = await res;
	} catch (err) {
		const errRes = await options.errorHandler(err);
		if (!errRes) return;
		res = errRes;
	}
	else res = await res.catch(handleFetchError);
	if (cacheKey in res) return responseViaCache(res, outgoing);
	const resHeaderRecord = buildOutgoingHttpHeaders(res.headers, res.body === null ? void 0 : defaultContentType);
	if (res.body) {
		const reader = res.body.getReader();
		const values = [];
		let done = false;
		let currentReadPromise = void 0;
		if (resHeaderRecord["transfer-encoding"] !== "chunked") {
			let maxReadCount = 2;
			for (let i = 0; i < maxReadCount; i++) {
				currentReadPromise ||= reader.read();
				const chunk = await readWithoutBlocking(currentReadPromise).catch((e) => {
					console.error(e);
					done = true;
				});
				if (!chunk) {
					if (i === 1) {
						await new Promise((resolve) => setTimeout(resolve));
						maxReadCount = 3;
						continue;
					}
					break;
				}
				currentReadPromise = void 0;
				if (chunk.value) values.push(chunk.value);
				if (chunk.done) {
					done = true;
					break;
				}
			}
			if (done && !("content-length" in resHeaderRecord)) resHeaderRecord["content-length"] = values.reduce((acc, value) => acc + value.length, 0);
		}
		outgoing.writeHead(res.status, resHeaderRecord);
		values.forEach((value) => {
			outgoing.write(value);
		});
		if (done) outgoing.end();
		else {
			if (values.length === 0) flushHeaders(outgoing);
			await writeFromReadableStreamDefaultReader(reader, outgoing, currentReadPromise);
		}
	} else if (resHeaderRecord["x-hono-already-sent"]) {} else {
		outgoing.writeHead(res.status, resHeaderRecord);
		outgoing.end();
	}
	outgoing[outgoingEnded]?.();
};
var getRequestListener = (fetchCallback, options = {}) => {
	const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
	if (options.overrideGlobalObjects !== false && global.Request !== Request$1) {
		Object.defineProperty(global, "Request", { value: Request$1 });
		Object.defineProperty(global, "Response", { value: Response$1 });
	}
	return async (incoming, outgoing) => {
		let res, req;
		let needsBodyCleanup = false;
		let closeHandlerAttached = false;
		const ensureCloseHandler = () => {
			if (!req || closeHandlerAttached) return;
			closeHandlerAttached = true;
			outgoing.on("close", makeCloseHandler(req, incoming, outgoing, needsBodyCleanup));
		};
		try {
			req = newRequest(incoming, options.hostname);
			needsBodyCleanup = autoCleanupIncoming && !(incoming.method === "GET" || incoming.method === "HEAD");
			if (needsBodyCleanup) {
				incoming[wrapBodyStream] = true;
				if (incoming instanceof Http2ServerRequest) outgoing[outgoingEnded] = () => {
					if (!incoming.readableEnded) setTimeout(() => {
						if (!incoming.readableEnded) setTimeout(() => {
							incoming.destroy();
							outgoing.destroy();
						});
					});
				};
			}
			res = fetchCallback(req, {
				incoming,
				outgoing
			});
			if (!isPromise(res) && isImmediateCacheableResponse(res)) {
				if (needsBodyCleanup && !incoming.readableEnded) outgoing.once("finish", () => {
					if (!incoming.readableEnded) drainIncoming(incoming);
				});
				return responseViaCache(res, outgoing);
			}
			ensureCloseHandler();
		} catch (e) {
			if (!res) if (options.errorHandler) {
				ensureCloseHandler();
				res = await options.errorHandler(req ? e : toRequestError(e));
				if (!res) return;
			} else if (!req) res = handleRequestError();
			else res = handleFetchError(e);
			else return handleResponseError(e, outgoing);
		}
		try {
			return await responseViaResponseObject(res, outgoing, options);
		} catch (e) {
			return handleResponseError(e, outgoing);
		}
	};
};
/**
* @link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
*/
var CloseEvent = globalThis.CloseEvent ?? class extends Event {
	#eventInitDict;
	constructor(type, eventInitDict = {}) {
		super(type, eventInitDict);
		this.#eventInitDict = eventInitDict;
	}
	get wasClean() {
		return this.#eventInitDict.wasClean ?? false;
	}
	get code() {
		return this.#eventInitDict.code ?? 0;
	}
	get reason() {
		return this.#eventInitDict.reason ?? "";
	}
};
/**
* Node.js has no global `ErrorEvent`, unlike `Event`/`MessageEvent`/`CloseEvent`.
* @link https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent
*/
var ErrorEvent = globalThis.ErrorEvent ?? class extends Event {
	#eventInitDict;
	constructor(type, eventInitDict = {}) {
		super(type, eventInitDict);
		this.#eventInitDict = eventInitDict;
	}
	get message() {
		return this.#eventInitDict.message ?? "";
	}
	get filename() {
		return this.#eventInitDict.filename ?? "";
	}
	get lineno() {
		return this.#eventInitDict.lineno ?? 0;
	}
	get colno() {
		return this.#eventInitDict.colno ?? 0;
	}
	get error() {
		return this.#eventInitDict.error ?? null;
	}
};
var generateConnectionSymbol = () => Symbol("connection");
var CONNECTION_SYMBOL_KEY = Symbol("CONNECTION_SYMBOL_KEY");
var WAIT_FOR_WEBSOCKET_SYMBOL = Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
var responseHeadersToSkip = /* @__PURE__ */ new Set([
	"connection",
	"content-length",
	"keep-alive",
	"proxy-authenticate",
	"proxy-authorization",
	"te",
	"trailer",
	"transfer-encoding",
	"upgrade",
	"sec-websocket-accept",
	"sec-websocket-extensions",
	"sec-websocket-protocol"
]);
var appendResponseHeaders = (headers, responseHeaders) => {
	if (!responseHeaders) return;
	responseHeaders.forEach((value, key) => {
		if (responseHeadersToSkip.has(key.toLowerCase())) return;
		headers.push(`${key}: ${value}`);
	});
};
var rejectUpgradeRequest = (socket, status, responseHeaders) => {
	const responseLines = ["Connection: close", "Content-Length: 0"];
	appendResponseHeaders(responseLines, responseHeaders);
	socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r\n${responseLines.join("\r\n")}\r\n\r
`);
};
var createUpgradeRequest = (request) => {
	const protocol = request.socket.encrypted ? "https" : "http";
	const url = new URL(request.url ?? "/", `${protocol}://${request.headers.host ?? "localhost"}`);
	const headers = new Headers();
	for (const key in request.headers) {
		const value = request.headers[key];
		if (!value) continue;
		headers.append(key, Array.isArray(value) ? value[0] : value);
	}
	return new Request(url, { headers });
};
var setupWebSocket = (options) => {
	const { server, fetchCallback, wss } = options;
	const waiterMap = /* @__PURE__ */ new Map();
	wss.on("connection", (ws, request) => {
		const waiter = waiterMap.get(request);
		if (waiter) {
			waiter.resolve(ws);
			waiterMap.delete(request);
		}
	});
	const rejectWaiter = (request) => {
		const waiter = waiterMap.get(request);
		if (waiter) {
			waiterMap.delete(request);
			waiter.reject(/* @__PURE__ */ new Error("WebSocket handshake aborted"));
		}
	};
	const waitForWebSocket = (request, connectionSymbol) => {
		return new Promise((resolve, reject) => {
			waiterMap.set(request, {
				resolve,
				reject,
				connectionSymbol
			});
		});
	};
	server.on("upgrade", async (request, socket, head) => {
		if (request.headers.upgrade?.toLowerCase() !== "websocket") return;
		const env = {
			incoming: request,
			outgoing: void 0,
			wss,
			[WAIT_FOR_WEBSOCKET_SYMBOL]: waitForWebSocket
		};
		let status = 400;
		let responseHeaders;
		try {
			const response = await fetchCallback(createUpgradeRequest(request), env);
			if (response instanceof Response) {
				status = response.status;
				responseHeaders = response.headers;
			}
		} catch {
			if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
			return;
		}
		const waiter = waiterMap.get(request);
		if (!waiter || waiter.connectionSymbol !== env[CONNECTION_SYMBOL_KEY]) {
			rejectWaiter(request);
			if (server.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, status, responseHeaders);
			return;
		}
		const addResponseHeaders = (headers) => {
			appendResponseHeaders(headers, responseHeaders);
		};
		const reclaimWaiterOnClose = () => rejectWaiter(request);
		socket.once("close", reclaimWaiterOnClose);
		wss.on("headers", addResponseHeaders);
		try {
			wss.handleUpgrade(request, socket, head, (ws) => {
				socket.off("close", reclaimWaiterOnClose);
				wss.emit("connection", ws, request);
			});
		} finally {
			wss.off("headers", addResponseHeaders);
		}
	});
	server.on("close", () => {
		wss.close();
	});
};
var upgradeWebSocket = defineWebSocketHelper(async (c, events, options) => {
	if (c.req.header("upgrade")?.toLowerCase() !== "websocket") return;
	const env = c.env;
	const waitForWebSocket = env[WAIT_FOR_WEBSOCKET_SYMBOL];
	if (!waitForWebSocket || !env.incoming) return new Response(null, { status: 500 });
	const connectionSymbol = generateConnectionSymbol();
	env[CONNECTION_SYMBOL_KEY] = connectionSymbol;
	(async () => {
		let ws;
		try {
			ws = await waitForWebSocket(env.incoming, connectionSymbol);
		} catch {
			return;
		}
		const messagesReceivedInStarting = [];
		const bufferMessage = (data, isBinary) => {
			messagesReceivedInStarting.push([data, isBinary]);
		};
		ws.on("message", bufferMessage);
		const ctx = {
			binaryType: "arraybuffer",
			close(code, reason) {
				ws.close(code, reason);
			},
			protocol: ws.protocol,
			raw: ws,
			get readyState() {
				return ws.readyState;
			},
			send(source, opts) {
				ws.send(source, { compress: opts?.compress });
			},
			url: new URL(c.req.url)
		};
		try {
			events?.onOpen?.(new Event("open"), ctx);
		} catch (e) {
			(options?.onError ?? console.error)(e);
		}
		const handleMessage = (data, isBinary) => {
			const datas = Array.isArray(data) ? data : [data];
			for (const data of datas) try {
				events?.onMessage?.(new MessageEvent("message", { data: isBinary ? data instanceof ArrayBuffer ? data : data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) : typeof data === "string" ? data : Buffer.from(data).toString("utf-8") }), ctx);
			} catch (e) {
				(options?.onError ?? console.error)(e);
			}
		};
		ws.off("message", bufferMessage);
		for (const message of messagesReceivedInStarting) handleMessage(...message);
		ws.on("message", (data, isBinary) => {
			handleMessage(data, isBinary);
		});
		ws.on("close", (code, reason) => {
			try {
				events?.onClose?.(new CloseEvent("close", {
					code,
					reason: reason.toString()
				}), ctx);
			} catch (e) {
				(options?.onError ?? console.error)(e);
			}
		});
		ws.on("error", (error) => {
			try {
				events?.onError?.(new ErrorEvent("error", { error }), ctx);
			} catch (e) {
				(options?.onError ?? console.error)(e);
			}
		});
	})();
	return new Response();
});
var createAdaptorServer = (options) => {
	const fetchCallback = options.fetch;
	const requestListener = getRequestListener(fetchCallback, {
		hostname: options.hostname,
		overrideGlobalObjects: options.overrideGlobalObjects,
		autoCleanupIncoming: options.autoCleanupIncoming
	});
	const server = (options.createServer || createServer)(options.serverOptions || {}, requestListener);
	if (options.websocket && options.websocket.server) {
		if (options.websocket.server.options.noServer !== true) throw new Error("WebSocket server must be created with { noServer: true } option");
		setupWebSocket({
			server,
			fetchCallback,
			wss: options.websocket.server
		});
	}
	return server;
};
var serve = (options, listeningListener) => {
	const server = createAdaptorServer(options);
	server.listen(options?.port ?? 3e3, options.hostname, () => {
		const serverInfo = server.address();
		listeningListener && listeningListener(serverInfo);
	});
	return server;
};
//#endregion
//#region src/onebot11/connect/http.ts
var OB11Http = class {
	ctx;
	config;
	app;
	server;
	sseClients = /* @__PURE__ */ new Set();
	activated = false;
	disposeHeartbeat;
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		if (this.server || !this.config.enable) return;
		this.app = new Hono();
		this.app.use(`/*`, cors());
		this.app.use("/*", this.authorize.bind(this));
		this.app.get("/_events", async (c) => {
			const res = await streamSSE(c, async (stream) => {
				this.sseClients.add(stream);
				stream.onAbort(() => {
					this.sseClients.delete(stream);
				});
				return new Promise((resolve) => {
					stream.onAbort(resolve);
				});
			});
			res.headers.set("Content-Type", "text/event-stream; charset=utf-8");
			return res;
		});
		this.app.use("/:endpoint", this.handleRequest.bind(this));
		const HEARTBEAT_INTERVAL = 5e3;
		this.disposeHeartbeat = this.ctx.interval(() => {
			if (this.sseClients.size === 0) return;
			this.emitEvent(new OB11HeartbeatEvent(selfInfo.online, true, HEARTBEAT_INTERVAL));
		}, HEARTBEAT_INTERVAL);
		const displayHost = this.config.host || "0.0.0.0";
		this.server = serve({
			fetch: this.app.fetch,
			port: this.config.port,
			hostname: this.config.host
		}, () => {
			this.ctx.logger.info(`OneBot V11 HTTP server started ${displayHost}:${this.config.port}`);
			this.ctx.logger.info(`OneBot V11 HTTP SSE started ${displayHost}:${this.config.port}/_events`);
		});
		this.activated = true;
	}
	stop() {
		return new Promise((resolve) => {
			this.disposeHeartbeat?.();
			this.disposeHeartbeat = void 0;
			if (this.server) {
				this.ctx.logger.info("OneBot V11 HTTP Server closing...");
				const server = this.server;
				server.closeAllConnections();
				server.close((err) => {
					if (err) this.ctx.logger.error(`OneBot V11 HTTP Server closing ${err}`);
					else this.ctx.logger.info("OneBot V11 HTTP Server closed");
					this.server = void 0;
					resolve(!err);
				});
			} else resolve(true);
			this.app = void 0;
			this.activated = false;
		});
	}
	async emitEvent(event) {
		if (!this.activated) return;
		if (!matchEventFilter(this.config.filter, event)) return;
		postHttpEvent(event);
		if (this.sseClients.size === 0) return;
		const data = JSON.stringify(event);
		for (const client of this.sseClients) if (!client.closed) {
			client.writeSSE({ data });
			if ("post_type" in event) {
				const eventName = event.getSummaryEventName();
				this.ctx.logger.info("OneBot V11 HTTP SSE 事件上报", eventName);
			}
		}
	}
	async emitMessageLikeEvent(event, self, offline) {
		if (self && !this.config.reportSelfMessage) return;
		if (offline && !this.config.reportOfflineMessage) return;
		if (event.post_type === "message" || event.post_type === "message_sent") {
			const msg = event;
			if (!this.config.debug && msg.message.length === 0) return;
			if (!this.config.debug) {
				delete msg.raw;
				delete msg.raw_pb;
			}
			if (this.config.messageFormat === "string") {
				msg.message = msg.raw_message;
				msg.message_format = "string";
			}
		}
		await this.emitEvent(event);
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
	async authorize(c, next) {
		const serverToken = this.config.token;
		if (!serverToken) return await next();
		let clientToken = "";
		const authHeader = c.req.header("Authorization");
		const authQuery = c.req.query("access_token");
		if (authHeader) {
			clientToken = authHeader.split("Bearer ").pop();
			this.ctx.logger.info("receive http header token", clientToken);
		} else if (authQuery) {
			clientToken = authQuery;
			this.ctx.logger.info("receive http url token", clientToken);
		}
		if (clientToken !== serverToken) return c.json({ message: "token verify failed" }, 403);
		else await next();
	}
	async handleRequest(c) {
		let payload;
		try {
			if (c.req.method === "POST") if (c.req.header("Content-Type")?.includes("application/x-www-form-urlencoded")) payload = await c.req.parseBody();
			else {
				const text = await c.req.text();
				payload = text ? JSON.parse(text) : {};
			}
			else payload = c.req.query();
		} catch (error) {
			const { message } = error;
			return c.json(OB11Response.error(`请求体解析失败: ${message}`, 400));
		}
		this.ctx.logger.info("收到 HTTP 请求", c.req.url, payload);
		const actionName = c.req.param("endpoint");
		const action = this.config.actionMap.get(actionName);
		if (action) return c.json(await action.handle(payload, {
			messageFormat: this.config.messageFormat,
			debug: this.config.debug
		}));
		else return c.json(OB11Response.error(`${actionName} API 不存在`, 404), 404);
	}
};
var OB11HttpPost = class {
	ctx;
	config;
	disposeInterval;
	activated = false;
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		this.activated = this.config.enable;
		if (this.config.enableHeart && !this.disposeInterval) this.disposeInterval = this.ctx.interval(() => {
			this.emitEvent(new OB11HeartbeatEvent(selfInfo.online, true, this.config.heartInterval));
		}, this.config.heartInterval);
	}
	stop() {
		this.activated = false;
		this.disposeInterval?.();
	}
	async emitEvent(event) {
		if (!matchEventFilter(this.config.filter, event)) return;
		if (!this.activated || !this.config.url) return;
		const msgStr = JSON.stringify(event);
		const headers = {
			"Content-Type": "application/json",
			"x-self-id": selfInfo.uin
		};
		if (this.config.token) {
			const hmac = crypto$1.createHmac("sha1", this.config.token);
			hmac.update(msgStr);
			headers["x-signature"] = "sha1=" + hmac.digest("hex");
		}
		const host = this.config.url;
		fetch(host, {
			method: "POST",
			headers,
			body: msgStr
		}).then(async (res) => {
			if (event.post_type) {
				const eventName = event.post_type + "." + event[event.post_type + "_type"];
				this.ctx.logger.info(`HTTP 事件上报: ${host}`, eventName, res.status);
			}
			if (res.status === 204 || res.headers.get("Content-Length") === "0") return;
			try {
				const resJson = await res.json();
				this.ctx.logger.info(`HTTP 事件上报后返回快速操作:`, resJson);
				handleQuickOperation(this.ctx, event, resJson).catch((e) => this.ctx.logger.error(e));
			} catch (e) {}
		}, (err) => {
			this.ctx.logger.error(`HTTP 事件上报失败: ${host}`, err, event);
		}).catch((e) => {
			this.ctx.logger.error(`HTTP 事件上报过程中发生异常: ${host}`, e);
		});
	}
	async emitMessageLikeEvent(event, self, offline) {
		if (self && !this.config.reportSelfMessage) return;
		if (offline && !this.config.reportOfflineMessage) return;
		if (event.post_type === "message" || event.post_type === "message_sent") {
			const msg = event;
			if (!this.config.debug && msg.message.length === 0) return;
			if (!this.config.debug) {
				delete msg.raw;
				delete msg.raw_pb;
			}
			if (this.config.messageFormat === "string") {
				msg.message = msg.raw_message;
				msg.message_format = "string";
			}
		}
		await this.emitEvent(event);
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
};
//#endregion
//#region node_modules/schemastery/lib/index.mjs
var __defProp$6 = Object.defineProperty;
var __getOwnPropNames$1 = Object.getOwnPropertyNames;
var __name$6 = (target, value) => __defProp$6(target, "name", {
	value,
	configurable: true
});
var __commonJS$1 = (cb, mod) => function __require() {
	return mod || (0, cb[__getOwnPropNames$1(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var lib_default$1 = __commonJS$1({ "src/index.ts"(exports, module) {
	var kSchema = Symbol.for("schemastery");
	var kValidationError = Symbol.for("ValidationError");
	globalThis.__schemastery_index__ ??= 0;
	globalThis.__schemastery_refs__ = void 0;
	var ValidationError = class extends TypeError {
		constructor(message, options) {
			let prefix = "$";
			for (const segment of options.path || []) if (typeof segment === "string") prefix += "." + segment;
			else if (typeof segment === "number") prefix += "[" + segment + "]";
			else if (typeof segment === "symbol") prefix += `[Symbol(${segment.toString()})]`;
			if (prefix.startsWith(".")) prefix = prefix.slice(1);
			super((prefix === "$" ? "" : `${prefix} `) + message);
			this.options = options;
		}
		static {
			__name$6(this, "ValidationError");
		}
		name = "ValidationError";
		static is(error) {
			return !!error?.[kValidationError];
		}
	};
	Object.defineProperty(ValidationError.prototype, kValidationError, { value: true });
	var Schema = /* @__PURE__ */ __name$6(function(options) {
		const schema = /* @__PURE__ */ __name$6(function(data, options2 = {}) {
			return Schema.resolve(data, schema, options2)[0];
		}, "schema");
		if (options.refs) {
			const refs = mapValues(options.refs, (options2) => new Schema(options2));
			const getRef = /* @__PURE__ */ __name$6((uid) => refs[uid], "getRef");
			for (const key in refs) {
				const options2 = refs[key];
				options2.sKey = getRef(options2.sKey);
				options2.inner = getRef(options2.inner);
				options2.list = options2.list && options2.list.map(getRef);
				options2.dict = options2.dict && mapValues(options2.dict, getRef);
			}
			return refs[options.uid];
		}
		Object.assign(schema, options);
		if (typeof schema.callback === "string") try {
			schema.callback = new Function("return " + schema.callback)();
		} catch {}
		Object.defineProperty(schema, "uid", { value: globalThis.__schemastery_index__++ });
		Object.setPrototypeOf(schema, Schema.prototype);
		schema.meta ||= {};
		schema.toString = schema.toString.bind(schema);
		return schema;
	}, "Schema");
	Schema.prototype = Object.create(Function.prototype);
	Schema.prototype[kSchema] = true;
	Object.defineProperty(Schema.prototype, "~standard", { get() {
		return {
			version: 1,
			vendor: "schemastery",
			validate: /* @__PURE__ */ __name$6((value) => {
				try {
					return { value: Schema.resolve(value, this, {})[0] };
				} catch (error) {
					if (ValidationError.is(error)) return { issues: [{
						message: error.message,
						path: error.options.path
					}] };
					throw error;
				}
			}, "validate")
		};
	} });
	Schema.ValidationError = ValidationError;
	Schema.prototype.toJSON = /* @__PURE__ */ __name$6(function toJSON() {
		if (globalThis.__schemastery_refs__) {
			globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));
			return this.uid;
		}
		globalThis.__schemastery_refs__ = { [this.uid]: { ...this } };
		globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));
		const result = {
			uid: this.uid,
			refs: globalThis.__schemastery_refs__
		};
		globalThis.__schemastery_refs__ = void 0;
		return result;
	}, "toJSON");
	Schema.prototype.set = /* @__PURE__ */ __name$6(function set(key, value) {
		this.dict[key] = value;
		return this;
	}, "set");
	Schema.prototype.push = /* @__PURE__ */ __name$6(function push(value) {
		this.list.push(value);
		return this;
	}, "push");
	function mergeDesc(original, messages) {
		const result = typeof original === "string" ? { "": original } : { ...original };
		for (const locale in messages) {
			const value = messages[locale];
			if (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;
			else if (typeof value === "string") result[locale] = value;
		}
		return result;
	}
	__name$6(mergeDesc, "mergeDesc");
	function getInner(value) {
		return value?.$value ?? value?.$inner;
	}
	__name$6(getInner, "getInner");
	function extractKeys(data) {
		return filterKeys(data ?? {}, (key) => !key.startsWith("$"));
	}
	__name$6(extractKeys, "extractKeys");
	Schema.prototype.i18n = /* @__PURE__ */ __name$6(function i18n(messages) {
		const schema = Schema(this);
		const desc = mergeDesc(schema.meta.description, messages);
		if (Object.keys(desc).length) schema.meta.description = desc;
		if (schema.dict) schema.dict = mapValues(schema.dict, (inner, key) => {
			return inner.i18n(mapValues(messages, (data) => getInner(data)?.[key] ?? data?.[key]));
		});
		if (schema.list) schema.list = schema.list.map((inner, index) => {
			return inner.i18n(mapValues(messages, (data = {}) => {
				if (Array.isArray(getInner(data))) return getInner(data)[index];
				if (Array.isArray(data)) return data[index];
				return extractKeys(data);
			}));
		});
		if (schema.inner) schema.inner = schema.inner.i18n(mapValues(messages, (data) => {
			if (getInner(data)) return getInner(data);
			return extractKeys(data);
		}));
		if (schema.sKey) schema.sKey = schema.sKey.i18n(mapValues(messages, (data) => data?.$key));
		return schema;
	}, "i18n");
	Schema.prototype.extra = /* @__PURE__ */ __name$6(function extra(key, value) {
		const schema = Schema(this);
		schema.meta = {
			...schema.meta,
			[key]: value
		};
		return schema;
	}, "extra");
	for (const key of [
		"required",
		"disabled",
		"collapse",
		"hidden",
		"loose"
	]) Object.assign(Schema.prototype, { [key](value = true) {
		const schema = Schema(this);
		schema.meta = {
			...schema.meta,
			[key]: value
		};
		return schema;
	} });
	Schema.prototype.deprecated = /* @__PURE__ */ __name$6(function deprecated() {
		const schema = Schema(this);
		schema.meta.badges ||= [];
		schema.meta.badges.push({
			text: "deprecated",
			type: "danger"
		});
		return schema;
	}, "deprecated");
	Schema.prototype.experimental = /* @__PURE__ */ __name$6(function experimental() {
		const schema = Schema(this);
		schema.meta.badges ||= [];
		schema.meta.badges.push({
			text: "experimental",
			type: "warning"
		});
		return schema;
	}, "experimental");
	Schema.prototype.pattern = /* @__PURE__ */ __name$6(function pattern(regexp) {
		const schema = Schema(this);
		const pattern2 = pick$1(regexp, ["source", "flags"]);
		schema.meta = {
			...schema.meta,
			pattern: pattern2
		};
		return schema;
	}, "pattern");
	Schema.prototype.simplify = /* @__PURE__ */ __name$6(function simplify(value) {
		if (deepEqual(value, this.meta.default, this.type === "dict")) return null;
		if (isNullable(value)) return value;
		if (this.type === "object" || this.type === "dict") {
			const result = {};
			for (const key in value) {
				const item = (this.type === "object" ? this.dict[key] : this.inner)?.simplify(value[key]);
				if (this.type === "dict" || !isNullable(item)) result[key] = item;
			}
			if (deepEqual(result, this.meta.default, this.type === "dict")) return null;
			return result;
		} else if (this.type === "array" || this.type === "tuple") {
			const result = [];
			value.forEach((value2, index) => {
				const schema = this.type === "array" ? this.inner : this.list[index];
				const item = schema ? schema.simplify(value2) : value2;
				result.push(item);
			});
			return result;
		} else if (this.type === "intersect") {
			const result = {};
			for (const item of this.list) Object.assign(result, item.simplify(value));
			return result;
		} else if (this.type === "union") for (const schema of this.list) try {
			Schema.resolve(value, schema, {});
			return schema.simplify(value);
		} catch {}
		return value;
	}, "simplify");
	Schema.prototype.toString = /* @__PURE__ */ __name$6(function toString(inline) {
		return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;
	}, "toString");
	Schema.prototype.role = /* @__PURE__ */ __name$6(function role(role, extra) {
		const schema = Schema(this);
		schema.meta = {
			...schema.meta,
			role,
			extra
		};
		return schema;
	}, "role");
	for (const key of [
		"default",
		"link",
		"comment",
		"description",
		"max",
		"min",
		"step"
	]) Object.assign(Schema.prototype, { [key](value) {
		const schema = Schema(this);
		schema.meta = {
			...schema.meta,
			[key]: value
		};
		return schema;
	} });
	var resolvers = {};
	Schema.extend = /* @__PURE__ */ __name$6(function extend(type, resolve) {
		resolvers[type] = resolve;
	}, "extend");
	Schema.resolve = /* @__PURE__ */ __name$6(function resolve(data, schema, options = {}, strict = false) {
		if (!schema) return [data];
		if (options.ignore?.(data, schema)) return [data];
		if (isNullable(data) && schema.type !== "lazy") {
			if (schema.meta.required) throw new ValidationError(`missing required value`, options);
			let current = schema;
			let fallback = schema.meta.default;
			while (current?.type === "intersect" && isNullable(fallback)) {
				current = current.list[0];
				fallback = current?.meta.default;
			}
			if (isNullable(fallback)) return [data];
			data = clone$1(fallback);
		}
		const callback = resolvers[schema.type];
		if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options);
		try {
			return callback(data, schema, options, strict);
		} catch (error) {
			if (!schema.meta.loose) throw error;
			return [schema.meta.default];
		}
	}, "resolve");
	Schema.from = /* @__PURE__ */ __name$6(function from(source) {
		if (isNullable(source)) return Schema.any();
		else if ([
			"string",
			"number",
			"boolean"
		].includes(typeof source)) return Schema.const(source).required();
		else if (source[kSchema]) return source;
		else if (typeof source === "function") switch (source) {
			case String: return Schema.string().required();
			case Number: return Schema.number().required();
			case Boolean: return Schema.boolean().required();
			case Function: return Schema.function().required();
			default: return Schema.is(source).required();
		}
		else throw new TypeError(`cannot infer schema from ${source}`);
	}, "from");
	Schema.lazy = /* @__PURE__ */ __name$6(function lazy(builder) {
		const schema = new Schema({
			type: "lazy",
			builder,
			inner: { toJSON: /* @__PURE__ */ __name$6(() => {
				if (!schema.inner[kSchema]) {
					schema.inner = schema.builder();
					schema.inner.meta = {
						...schema.meta,
						...schema.inner.meta
					};
				}
				return schema.inner.toJSON();
			}, "toJSON") }
		});
		return schema;
	}, "lazy");
	Schema.natural = /* @__PURE__ */ __name$6(function natural() {
		return Schema.number().step(1).min(0);
	}, "natural");
	Schema.percent = /* @__PURE__ */ __name$6(function percent() {
		return Schema.number().step(.01).min(0).max(1).role("slider");
	}, "percent");
	Schema.date = /* @__PURE__ */ __name$6(function date() {
		return Schema.union([Schema.is(Date), Schema.transform(Schema.string().role("datetime"), (value, options) => {
			const date2 = new Date(value);
			if (isNaN(+date2)) throw new ValidationError(`invalid date "${value}"`, options);
			return date2;
		}, true)]);
	}, "date");
	Schema.regExp = /* @__PURE__ */ __name$6(function regExp(flag = "") {
		return Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role("regexp", { flag }), (value, options) => {
			try {
				return new RegExp(value, flag);
			} catch (e) {
				throw new ValidationError(e.message, options);
			}
		}, true)]);
	}, "regExp");
	Schema.arrayBuffer = /* @__PURE__ */ __name$6(function arrayBuffer(encoding) {
		return Schema.union([
			Schema.is(ArrayBuffer),
			Schema.is(SharedArrayBuffer),
			Schema.transform(Schema.any(), (value, options) => {
				if (Binary.isSource(value)) return Binary.fromSource(value);
				throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options);
			}, true),
			...encoding ? [Schema.transform(Schema.string(), (value, options) => {
				try {
					return encoding === "base64" ? Binary.fromBase64(value) : Binary.fromHex(value);
				} catch (e) {
					throw new ValidationError(e.message, options);
				}
			}, true)] : []
		]);
	}, "arrayBuffer");
	Schema.extend("lazy", (data, schema, options, strict) => {
		if (!schema.inner[kSchema]) {
			schema.inner = schema.builder();
			schema.inner.meta = {
				...schema.meta,
				...schema.inner.meta
			};
		}
		return Schema.resolve(data, schema.inner, options, strict);
	});
	Schema.extend("any", (data) => {
		return [data];
	});
	Schema.extend("never", (data, _, options) => {
		throw new ValidationError(`expected nullable but got ${data}`, options);
	});
	Schema.extend("const", (data, { value }, options) => {
		if (deepEqual(data, value)) return [value];
		throw new ValidationError(`expected ${value} but got ${data}`, options);
	});
	function checkWithinRange(data, meta, description, options, skipMin = false) {
		const { max = Infinity, min = -Infinity } = meta;
		if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);
		if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);
	}
	__name$6(checkWithinRange, "checkWithinRange");
	Schema.extend("string", (data, { meta }, options) => {
		if (typeof data !== "string") throw new ValidationError(`expected string but got ${data}`, options);
		if (meta.pattern) {
			const regexp = new RegExp(meta.pattern.source, meta.pattern.flags);
			if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);
		}
		checkWithinRange(data.length, meta, "string length", options);
		return [data];
	});
	function decimalShift(data, digits) {
		const str = data.toString();
		if (str.includes("e")) return data * Math.pow(10, digits);
		const index = str.indexOf(".");
		if (index === -1) return data * Math.pow(10, digits);
		const frac = str.slice(index + 1);
		const integer = str.slice(0, index);
		if (frac.length <= digits) return +(integer + frac.padEnd(digits, "0"));
		return +(integer + frac.slice(0, digits) + "." + frac.slice(digits));
	}
	__name$6(decimalShift, "decimalShift");
	function isMultipleOf(data, min, step) {
		step = Math.abs(step);
		if (!/^\d+\.\d+$/.test(step.toString())) return (data - min) % step === 0;
		const index = step.toString().indexOf(".");
		const digits = step.toString().slice(index + 1).length;
		return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;
	}
	__name$6(isMultipleOf, "isMultipleOf");
	Schema.extend("number", (data, { meta }, options) => {
		if (typeof data !== "number") throw new ValidationError(`expected number but got ${data}`, options);
		checkWithinRange(data, meta, "number", options);
		const { step } = meta;
		if (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);
		return [data];
	});
	Schema.extend("boolean", (data, _, options) => {
		if (typeof data === "boolean") return [data];
		throw new ValidationError(`expected boolean but got ${data}`, options);
	});
	Schema.extend("bitset", (data, { bits, meta }, options) => {
		let value = 0, keys = [];
		if (typeof data === "number") {
			value = data;
			for (const key in bits) if (data & bits[key]) keys.push(key);
		} else if (Array.isArray(data)) {
			keys = data;
			for (const key of keys) {
				if (typeof key !== "string") throw new ValidationError(`expected string but got ${key}`, options);
				if (key in bits) value |= bits[key];
			}
		} else throw new ValidationError(`expected number or array but got ${data}`, options);
		if (value === meta.default) return [value];
		return [value, keys];
	});
	Schema.extend("function", (data, _, options) => {
		if (typeof data === "function") return [data];
		throw new ValidationError(`expected function but got ${data}`, options);
	});
	Schema.extend("is", (data, { constructor }, options) => {
		if (typeof constructor === "function") {
			if (data instanceof constructor) return [data];
			throw new ValidationError(`expected ${constructor.name} but got ${data}`, options);
		} else {
			if (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);
			let prototype = Object.getPrototypeOf(data);
			while (prototype) {
				if (prototype.constructor?.name === constructor) return [data];
				prototype = Object.getPrototypeOf(prototype);
			}
			throw new ValidationError(`expected ${constructor} but got ${data}`, options);
		}
	});
	function property(data, key, schema, options) {
		try {
			const [value, adapted] = Schema.resolve(data[key], schema, {
				...options,
				path: [...options.path || [], key]
			});
			if (adapted !== void 0) data[key] = adapted;
			return value;
		} catch (e) {
			if (!options?.autofix) throw e;
			delete data[key];
			return schema.meta.default;
		}
	}
	__name$6(property, "property");
	Schema.extend("array", (data, { inner, meta }, options) => {
		if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
		checkWithinRange(data.length, meta, "array length", options, !isNullable(inner.meta.default));
		return [data.map((_, index) => property(data, index, inner, options))];
	});
	Schema.extend("dict", (data, { inner, sKey }, options, strict) => {
		if (!isPlainObject$1(data)) throw new ValidationError(`expected object but got ${data}`, options);
		const result = {};
		for (const key in data) {
			let rKey;
			try {
				rKey = Schema.resolve(key, sKey, options)[0];
			} catch (error) {
				if (strict) continue;
				throw error;
			}
			result[rKey] = property(data, key, inner, options);
			data[rKey] = data[key];
			if (key !== rKey) delete data[key];
		}
		return [result];
	});
	Schema.extend("tuple", (data, { list }, options, strict) => {
		if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
		const result = list.map((inner, index) => property(data, index, inner, options));
		if (strict) return [result];
		result.push(...data.slice(list.length));
		return [result];
	});
	function merge(result, data) {
		for (const key in data) {
			if (key in result) continue;
			result[key] = data[key];
		}
	}
	__name$6(merge, "merge");
	Schema.extend("object", (data, { dict }, options, strict) => {
		if (!isPlainObject$1(data)) throw new ValidationError(`expected object but got ${data}`, options);
		const result = {};
		for (const key in dict) {
			const value = property(data, key, dict[key], options);
			if (!isNullable(value) || key in data) result[key] = value;
		}
		if (!strict) merge(result, data);
		return [result];
	});
	Schema.extend("union", (data, { list, toString }, options, strict) => {
		const messages = [];
		for (const inner of list) try {
			return Schema.resolve(data, inner, options, strict);
		} catch (error) {
			messages.push(error);
		}
		throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
	});
	Schema.extend("intersect", (data, { list, toString }, options, strict) => {
		if (!list.length) return [data];
		let result;
		for (const inner of list) {
			const value = Schema.resolve(data, inner, options, true)[0];
			if (isNullable(value)) continue;
			if (isNullable(result)) result = value;
			else if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
			else if (typeof value === "object") merge(result ??= {}, value);
			else if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
		}
		if (!strict && isPlainObject$1(data)) merge(result, data);
		return [result];
	});
	Schema.extend("transform", (data, { inner, callback, preserve }, options) => {
		const [result, adapted = data] = Schema.resolve(data, inner, options, true);
		if (preserve) return [callback(result)];
		else return [callback(result), callback(adapted)];
	});
	var formatters = {};
	function defineMethod(name, keys, format) {
		formatters[name] = format;
		Object.assign(Schema, { [name](...args) {
			const schema = new Schema({ type: name });
			keys.forEach((key, index) => {
				switch (key) {
					case "sKey":
						schema.sKey = args[index] ?? Schema.string();
						break;
					case "inner":
						schema.inner = Schema.from(args[index]);
						break;
					case "list":
						schema.list = args[index].map(Schema.from);
						break;
					case "dict":
						schema.dict = mapValues(args[index], Schema.from);
						break;
					case "bits":
						schema.bits = {};
						for (const key2 in args[index]) {
							if (typeof args[index][key2] !== "number") continue;
							schema.bits[key2] = args[index][key2];
						}
						break;
					case "callback": {
						const callback = schema.callback = args[index];
						callback["toJSON"] ||= () => callback.toString();
						break;
					}
					case "constructor": {
						const constructor = schema.constructor = args[index];
						if (typeof constructor === "function") constructor["toJSON"] ||= () => constructor["name"];
						break;
					}
					default: schema[key] = args[index];
				}
			});
			if (name === "object" || name === "dict") schema.meta.default = {};
			else if (name === "array" || name === "tuple") schema.meta.default = [];
			else if (name === "bitset") schema.meta.default = 0;
			return schema;
		} });
	}
	__name$6(defineMethod, "defineMethod");
	defineMethod("is", ["constructor"], ({ constructor }) => {
		if (typeof constructor === "function") return constructor.name;
		else return constructor;
	});
	defineMethod("any", [], () => "any");
	defineMethod("never", [], () => "never");
	defineMethod("const", ["value"], ({ value }) => typeof value === "string" ? JSON.stringify(value) : value);
	defineMethod("string", [], () => "string");
	defineMethod("number", [], () => "number");
	defineMethod("boolean", [], () => "boolean");
	defineMethod("bitset", ["bits"], () => "bitset");
	defineMethod("function", [], () => "function");
	defineMethod("array", ["inner"], ({ inner }) => `${inner.toString(true)}[]`);
	defineMethod("dict", ["inner", "sKey"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);
	defineMethod("tuple", ["list"], ({ list }) => `[${list.map((inner) => inner.toString()).join(", ")}]`);
	defineMethod("object", ["dict"], ({ dict }) => {
		if (Object.keys(dict).length === 0) return "{}";
		return `{ ${Object.entries(dict).map(([key, inner]) => {
			return `${key}${inner.meta.required ? "" : "?"}: ${inner.toString()}`;
		}).join(", ")} }`;
	});
	defineMethod("union", ["list"], ({ list }, inline) => {
		const result = list.map(({ toString: format }) => format()).join(" | ");
		return inline ? `(${result})` : result;
	});
	defineMethod("intersect", ["list"], ({ list }) => {
		return `${list.map((inner) => inner.toString(true)).join(" & ")}`;
	});
	defineMethod("transform", [
		"inner",
		"callback",
		"preserve"
	], ({ inner }, isInner) => inner.toString(isInner));
	module.exports = Schema;
} })();
//#endregion
//#region src/onebot11/action/BaseAction.ts
var BaseAction = class {
	adapter;
	ctx;
	payloadSchema;
	constructor(adapter) {
		this.adapter = adapter;
		this.ctx = adapter.ctx;
	}
	async handle(payload, config) {
		let params;
		try {
			params = this.payloadSchema ? new this.payloadSchema(payload) : payload;
		} catch (e) {
			this.ctx.logger.error("发生错误", e);
			return OB11Response.error(e.message, 400);
		}
		try {
			const resData = await this._handle(params, config);
			return OB11Response.ok(resData);
		} catch (e) {
			this.ctx.logger.error("发生错误", e);
			return OB11Response.error(e.message, 200);
		}
	}
	async websocketHandle(payload, echo, config) {
		let params;
		try {
			params = this.payloadSchema ? new this.payloadSchema(payload) : payload;
		} catch (e) {
			this.ctx.logger.error("发生错误", e);
			return OB11Response.error(e.message, 1400, echo);
		}
		try {
			const resData = await this._handle(params, config);
			return OB11Response.ok(resData, echo);
		} catch (e) {
			this.ctx.logger.error("发生错误", e);
			return OB11Response.error(e.message, 1200, echo);
		}
	}
};
//#endregion
//#region src/onebot11/action/types.ts
var ActionName = /* @__PURE__ */ function(ActionName) {
	ActionName["ScanQRCode"] = "scan_qrcode";
	ActionName["GetGroupAlbumList"] = "get_group_album_list";
	ActionName["CreateGroupAlbum"] = "create_group_album";
	ActionName["DeleteGroupAlbum"] = "delete_group_album";
	ActionName["UploadGroupAlbum"] = "upload_group_album";
	ActionName["BatchDeleteGroupMember"] = "batch_delete_group_member";
	ActionName["GetFlashFileInfo"] = "get_flash_file_info";
	ActionName["DownloadFlashFile"] = "download_flash_file";
	ActionName["GetFlashFileDownloadUrls"] = "get_flash_file_download_urls";
	ActionName["UploadFlashFile"] = "upload_flash_file";
	ActionName["ReShareFlashFile"] = "reshare_flash_file";
	ActionName["GetRKey"] = "get_rkey";
	ActionName["SendPB"] = "send_pb";
	ActionName["VoiceMsg2Text"] = "voice_msg_to_text";
	ActionName["GetGroupIgnoreAddRequest"] = "get_group_ignore_add_request";
	ActionName["SetQQAvatar"] = "set_qq_avatar";
	ActionName["GetQQAvatar"] = "get_qq_avatar";
	ActionName["GetConfig"] = "get_config";
	ActionName["SetConfig"] = "set_config";
	ActionName["Debug"] = "llonebot_debug";
	ActionName["GetFile"] = "get_file";
	ActionName["GetFriendsWithCategory"] = "get_friends_with_category";
	ActionName["GetEvent"] = "get_event";
	ActionName["SetOnlineStatus"] = "set_online_status";
	ActionName["GetProfileLike"] = "get_profile_like";
	ActionName["GetProfileLikeMe"] = "get_profile_like_me";
	ActionName["FetchEmojiLike"] = "fetch_emoji_like";
	ActionName["FetchCustomFace"] = "fetch_custom_face";
	ActionName["GetFriendMsgHistory"] = "get_friend_msg_history";
	ActionName["SendForwardMsg"] = "send_forward_msg";
	ActionName["SetMsgEmojiLike"] = "set_msg_emoji_like";
	ActionName["UnSetMsgEmojiLike"] = "unset_msg_emoji_like";
	ActionName["GetRobotUinRange"] = "get_robot_uin_range";
	ActionName["GroupPoke"] = "group_poke";
	ActionName["FriendPoke"] = "friend_poke";
	ActionName["SetFriendRemark"] = "set_friend_remark";
	ActionName["SetFriendCategory"] = "set_friend_category";
	ActionName["SetGroupMsgMask"] = "set_group_msg_mask";
	ActionName["SetGroupRemark"] = "set_group_remark";
	ActionName["MoveGroupFile"] = "move_group_file";
	ActionName["RenameGroupFile"] = "rename_group_file";
	ActionName["SetGroupFileForever"] = "set_group_file_forever";
	ActionName["GetGroupShutList"] = "get_group_shut_list";
	ActionName["RenameGroupFileFolder"] = "rename_group_file_folder";
	ActionName["GetRecommendFace"] = "get_recommend_face";
	ActionName["GetAiCharacters"] = "get_ai_characters";
	ActionName["SendGroupAiRecord"] = "send_group_ai_record";
	ActionName["GetPrivateFileUrl"] = "get_private_file_url";
	ActionName["GetDoubtFriendsAddRequest"] = "get_doubt_friends_add_request";
	ActionName["SetDoubtFriendsAddRequest"] = "set_doubt_friends_add_request";
	ActionName["DeleteGroupNotice"] = "_delete_group_notice";
	ActionName["SendPoke"] = "send_poke";
	ActionName["SetInputStatus"] = "set_input_status";
	ActionName["GetGroupAlbumMediaList"] = "get_group_album_media_list";
	ActionName["GetGroupSignedList"] = "get_group_signed_list";
	ActionName["GetProfileLikeCount"] = "get_profile_like_count";
	ActionName["SendLike"] = "send_like";
	ActionName["GetLoginInfo"] = "get_login_info";
	ActionName["GetFriendList"] = "get_friend_list";
	ActionName["GetGroupInfo"] = "get_group_info";
	ActionName["GetGroupList"] = "get_group_list";
	ActionName["GetGroupMemberInfo"] = "get_group_member_info";
	ActionName["GetGroupMemberList"] = "get_group_member_list";
	ActionName["GetMsg"] = "get_msg";
	ActionName["SendMsg"] = "send_msg";
	ActionName["SendGroupMsg"] = "send_group_msg";
	ActionName["SendPrivateMsg"] = "send_private_msg";
	ActionName["DeleteMsg"] = "delete_msg";
	ActionName["SetGroupAddRequest"] = "set_group_add_request";
	ActionName["SetFriendAddRequest"] = "set_friend_add_request";
	ActionName["SetGroupLeave"] = "set_group_leave";
	ActionName["GetVersionInfo"] = "get_version_info";
	ActionName["GetStatus"] = "get_status";
	ActionName["SetRestart"] = "set_restart";
	ActionName["CanSendRecord"] = "can_send_record";
	ActionName["CanSendImage"] = "can_send_image";
	ActionName["SetGroupKick"] = "set_group_kick";
	ActionName["SetGroupBan"] = "set_group_ban";
	ActionName["SetGroupWholeBan"] = "set_group_whole_ban";
	ActionName["SetGroupAdmin"] = "set_group_admin";
	ActionName["SetGroupCard"] = "set_group_card";
	ActionName["SetGroupName"] = "set_group_name";
	ActionName["GetImage"] = "get_image";
	ActionName["GetRecord"] = "get_record";
	ActionName["CleanCache"] = "clean_cache";
	ActionName["GetCookies"] = "get_cookies";
	ActionName["ForwardFriendSingleMsg"] = "forward_friend_single_msg";
	ActionName["ForwardGroupSingleMsg"] = "forward_group_single_msg";
	ActionName["GetCredentials"] = "get_credentials";
	ActionName["GetCsrfToken"] = "get_csrf_token";
	ActionName["GoCQHTTP_SendGroupForwardMsg"] = "send_group_forward_msg";
	ActionName["GoCQHTTP_SendPrivateForwardMsg"] = "send_private_forward_msg";
	ActionName["GoCQHTTP_GetStrangerInfo"] = "get_stranger_info";
	ActionName["GetGuildList"] = "get_guild_list";
	ActionName["GoCQHTTP_MarkMsgAsRead"] = "mark_msg_as_read";
	ActionName["GoCQHTTP_UploadGroupFile"] = "upload_group_file";
	ActionName["GoCQHTTP_UploadPrivateFile"] = "upload_private_file";
	ActionName["GoCQHTTP_DownloadFile"] = "download_file";
	ActionName["GoCQHTTP_GetGroupMsgHistory"] = "get_group_msg_history";
	ActionName["GoCQHTTP_GetForwardMsg"] = "get_forward_msg";
	ActionName["GoCQHTTP_GetEssenceMsgList"] = "get_essence_msg_list";
	ActionName["GoCQHTTP_HandleQuickOperation"] = ".handle_quick_operation";
	ActionName["GetGroupHonorInfo"] = "get_group_honor_info";
	ActionName["GoCQHTTP_SetEssenceMsg"] = "set_essence_msg";
	ActionName["GoCQHTTP_DeleteEssenceMsg"] = "delete_essence_msg";
	ActionName["GoCQHTTP_DeleteGroupFile"] = "delete_group_file";
	ActionName["GoCQHTTP_GetGroupSystemMsg"] = "get_group_system_msg";
	ActionName["GoCQHTTP_CreateGroupFileFolder"] = "create_group_file_folder";
	ActionName["GoCQHTTP_DeleteGroupFolder"] = "delete_group_folder";
	ActionName["GoCQHTTP_GetGroupAtAllRemain"] = "get_group_at_all_remain";
	ActionName["GoCQHTTP_GetGroupRootFiles"] = "get_group_root_files";
	ActionName["GoCQHTTP_SendGroupNotice"] = "_send_group_notice";
	ActionName["GoCQHTTP_GetGroupFilesByFolder"] = "get_group_files_by_folder";
	ActionName["GoCQHTTP_GetGroupFileUrl"] = "get_group_file_url";
	ActionName["GoCQHTTP_GetGroupNotice"] = "_get_group_notice";
	ActionName["GoCQHTTP_DeleteFriend"] = "delete_friend";
	ActionName["GoCQHTTP_OCRImage"] = "ocr_image";
	ActionName["GoCQHTTP_GetGroupFileSystemInfo"] = "get_group_file_system_info";
	ActionName["GoCQHTTP_SetGroupSpecialTitle"] = "set_group_special_title";
	ActionName["GoCQHTTP_SendGroupSign"] = "send_group_sign";
	ActionName["GoCQHTTP_SetQQProfile"] = "set_qq_profile";
	ActionName["GoCQHTTP_SetGroupPortrait"] = "set_group_portrait";
	return ActionName;
}({});
//#endregion
//#region src/onebot11/action/msg/GetMsg.ts
var GetMsg = class extends BaseAction {
	actionName = ActionName.GetMsg;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload, config) {
		const msgInfo = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!msgInfo) throw new Error("消息不存在");
		let status = "normal";
		let msg;
		const res = await this.ctx.ntMsgApi.getSingleMsg(msgInfo.peer, msgInfo.msgSeq);
		if (res.msgList.length === 0) {
			const msgCache = this.ctx.store.getMsgByMsgId(msgInfo.msgId);
			if (msgCache) {
				msg = msgCache;
				status = "deleted";
			} else if (res.msgList.length === 0) throw new Error("无法获取该消息");
			else {
				msg = res.msgList[0];
				status = "deleted";
			}
		} else msg = res.msgList[0];
		const retMsg = await OB11Entities.message(this.ctx, msg, config);
		if (!retMsg) throw new Error("消息为空");
		retMsg.real_id = retMsg.message_seq;
		retMsg.status = status;
		return retMsg;
	}
};
//#endregion
//#region src/onebot11/action/system/GetLoginInfo.ts
var GetLoginInfo$1 = class extends BaseAction {
	actionName = ActionName.GetLoginInfo;
	async _handle() {
		for (let i = 0; i < 5; i++) try {
			await this.ctx.ntUserApi.getSelfNick(true);
			break;
		} catch {
			await sleep(500);
		}
		return {
			user_id: +selfInfo.uin,
			nickname: selfInfo.nick
		};
	}
};
//#endregion
//#region src/onebot11/action/user/GetFriendList.ts
var GetFriendList$1 = class extends BaseAction {
	actionName = ActionName.GetFriendList;
	async _handle() {
		const result = await this.ctx.ntFriendApi.getFriends(true);
		return OB11Entities.friends(result.friends);
	}
};
//#endregion
//#region src/onebot11/action/group/GetGroupList.ts
var GetGroupList$1 = class extends BaseAction {
	actionName = ActionName.GetGroupList;
	payloadSchema = lib_default$1.object({ no_cache: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false) });
	async _handle(payload) {
		return (await this.ctx.ntGroupApi.getGroups(payload.no_cache)).map((group) => ({
			group_id: group.groupCode,
			group_name: group.groupName,
			group_memo: group.description,
			group_create_time: group.createdAt,
			member_count: group.memberCount,
			max_member_count: group.maxMemberCount,
			remark_name: group.remark,
			avatar_url: `https://p.qlogo.cn/gh/${group.groupCode}/${group.groupCode}/0`,
			owner_id: 0,
			is_top: group.isPin,
			shut_up_all_timestamp: group.groupShutupExpireTime,
			shut_up_me_timestamp: group.personShutupExpireTime
		}));
	}
};
//#endregion
//#region src/onebot11/action/group/GetGroupInfo.ts
var GetGroupInfo$1 = class extends BaseAction {
	actionName = ActionName.GetGroupInfo;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		no_cache: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	async _handle(payload) {
		const group = await this.ctx.ntGroupApi.getGroup(+payload.group_id, payload.no_cache);
		return {
			group_id: group.groupCode,
			group_name: group.groupName,
			group_memo: group.description,
			group_create_time: group.createdAt,
			member_count: group.memberCount,
			max_member_count: group.maxMemberCount,
			remark_name: group.remark,
			avatar_url: `https://p.qlogo.cn/gh/${group.groupCode}/${group.groupCode}/0`,
			owner_id: Number(await this.ctx.ntUserApi.getUinByUid(group.ownerUid)),
			is_top: group.isPin,
			shut_up_all_timestamp: group.groupShutupExpireTime,
			shut_up_me_timestamp: group.personShutupExpireTime
		};
	}
};
//#endregion
//#region src/onebot11/action/group/GetGroupMemberList.ts
var GetGroupMemberList$1 = class extends BaseAction {
	actionName = ActionName.GetGroupMemberList;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		no_cache: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async _handle(payload) {
		const groupId = +payload.group_id;
		return (await this.ctx.ntGroupApi.getGroupMembers(groupId, payload.no_cache)).map((e) => OB11Entities.groupMember(groupId, e));
	}
};
//#endregion
//#region src/onebot11/action/group/GetGroupMemberInfo.ts
var GetGroupMemberInfo$1 = class extends BaseAction {
	actionName = ActionName.GetGroupMemberInfo;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		no_cache: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async _handle(payload) {
		const member = await this.ctx.ntGroupApi.getGroupMemberByUin(+payload.group_id, +payload.user_id, payload.no_cache);
		if (!member) throw new Error("群成员未找到");
		const ret = OB11Entities.groupMember(+payload.group_id, member);
		const info = await this.ctx.ntUserApi.getUserByUin(+payload.user_id);
		ret.sex = OB11Entities.sex(info.gender);
		ret.qq_level = info.level;
		ret.age = info.age;
		return ret;
	}
};
//#endregion
//#region src/onebot11/action/msg/SendMsg.ts
var SendMsg = class extends BaseAction {
	actionName = ActionName.SendMsg;
	payloadSchema = lib_default$1.object({
		message_type: lib_default$1.union(["private", "group"]),
		user_id: lib_default$1.union([Number, String]),
		group_id: lib_default$1.union([Number, String]),
		message: lib_default$1.any().required(),
		auto_escape: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async _handle(payload) {
		let contextMode = CreatePeerMode.Normal;
		if (payload.message_type === "group") contextMode = CreatePeerMode.Group;
		else if (payload.message_type === "private") contextMode = CreatePeerMode.Private;
		const peer = await createPeer(this.ctx, payload, contextMode);
		const messages = message2List(payload.message, payload.auto_escape);
		if (messages.some((e) => e.type === OB11MessageDataType.Node)) throw new Error("请使用 /send_group_forward_msg 或 /send_private_forward_msg 进行合并转发");
		const { sendElements, deleteAfterSentFiles } = await transformOutgoingSegments(this.ctx, messages, peer, false);
		const returnMsg = await this.ctx.app.sendMessage(this.ctx, peer, sendElements, deleteAfterSentFiles);
		return { message_id: this.ctx.store.createMsgShortId(returnMsg) };
	}
};
//#endregion
//#region src/onebot11/action/group/SendGroupMsg.ts
var SendGroupMsg = class extends SendMsg {
	actionName = ActionName.SendGroupMsg;
	_handle(payload) {
		payload.message_type = "group";
		return super._handle(payload);
	}
};
//#endregion
//#region src/onebot11/action/msg/SendPrivateMsg.ts
var SendPrivateMsg = class extends SendMsg {
	actionName = ActionName.SendPrivateMsg;
	_handle(payload) {
		payload.message_type = "private";
		return super._handle(payload);
	}
};
//#endregion
//#region src/onebot11/action/msg/DeleteMsg.ts
var DeleteMsg = class extends BaseAction {
	actionName = ActionName.DeleteMsg;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const info = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!info) throw new Error(`消息${payload.message_id}不存在`);
		if (info.peer.chatType === ChatType.Group) await this.ctx.ntMsgApi.recallMsg(info.peer, info.msgSeq);
		else {
			let msg = this.ctx.store.getMsgBySeq(info.peer.peerUid, info.msgSeq);
			if (!msg) {
				const { msgList } = await this.ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq);
				msg = msgList[0];
			}
			await this.ctx.ntMsgApi.recallMsg(info.peer, msg.msgSeq, msg.clientSeq, msg.msgRandom, msg.msgTime);
		}
		return null;
	}
};
//#endregion
//#region src/onebot11/action/system/GetVersionInfo.ts
var GetVersionInfo = class extends BaseAction {
	actionName = ActionName.GetVersionInfo;
	async _handle() {
		return {
			app_name: "LLOneBot",
			protocol_version: "v11",
			app_version: version$3
		};
	}
};
//#endregion
//#region src/onebot11/action/system/CanSendRecord.ts
var CanSendRecord = class extends BaseAction {
	actionName = ActionName.CanSendRecord;
	async _handle() {
		return { yes: true };
	}
};
//#endregion
//#region src/onebot11/action/system/CanSendImage.ts
var CanSendImage = class extends CanSendRecord {
	actionName = ActionName.CanSendImage;
};
//#endregion
//#region src/onebot11/action/system/GetStatus.ts
var GetStatus = class extends BaseAction {
	actionName = ActionName.GetStatus;
	async _handle() {
		return {
			online: selfInfo.online,
			good: true,
			stat: {
				message_received: this.ctx.app.messageReceivedCount,
				message_sent: this.ctx.app.messageSentCount,
				last_message_time: this.ctx.app.lastMessageTime,
				startup_time: this.ctx.app.startupTime
			}
		};
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SendForwardMsg.ts
var SendForwardMsg = class extends BaseAction {
	actionName = ActionName.SendForwardMsg;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]),
		group_id: lib_default$1.union([Number, String]),
		messages: lib_default$1.array(lib_default$1.any()),
		message: lib_default$1.array(lib_default$1.any()),
		message_type: lib_default$1.union(["group", "private"]),
		source: lib_default$1.string(),
		news: lib_default$1.array(lib_default$1.object({ text: lib_default$1.string() })),
		summary: lib_default$1.string(),
		prompt: lib_default$1.string()
	});
	async _handle(payload) {
		const messages = (payload.messages?.length ? payload.messages : null) ?? payload.message;
		if (!messages || messages.length === 0) throw new Error("未指定消息内容");
		let contextMode = CreatePeerMode.Normal;
		if (payload.message_type === "group") contextMode = CreatePeerMode.Group;
		else if (payload.message_type === "private") contextMode = CreatePeerMode.Private;
		const peer = await createPeer(this.ctx, payload, contextMode);
		let nodes = this.parseNodeContent(messages);
		if (nodes.some((e) => e.data.id)) {
			const processedIds = /* @__PURE__ */ new Set();
			const convertedNodes = [];
			for (const item of nodes) if (item.data.id) {
				const idStr = item.data.id.toString();
				if (processedIds.has(idStr)) continue;
				processedIds.add(idStr);
				const msgInfo = await this.ctx.store.getMsgInfoByShortId(+item.data.id);
				if (!msgInfo) {
					this.ctx.logger.warn(`消息 ${item.data.id} 未找到`);
					continue;
				}
				const node = await this.getMessageNode(msgInfo, +item.data.id);
				convertedNodes.push(node);
			} else convertedNodes.push(item);
			nodes = convertedNodes;
		}
		if (nodes.some((e) => e.data.seq)) this.sortNodesWithSeq(nodes);
		this.assignSequentialSeqs(nodes);
		this.assignMissingTimes(nodes);
		const { sendElements, deleteAfterSentFiles } = await transformOutgoingSegments(this.ctx, nodes, peer, true);
		const returnMsg = await this.ctx.app.sendMessage(this.ctx, peer, sendElements, deleteAfterSentFiles);
		const msgShortId = this.ctx.store.createMsgShortId(returnMsg);
		let forwardId;
		if (returnMsg.elements[0].multiForwardMsgElement) forwardId = returnMsg.elements[0].multiForwardMsgElement.resId;
		else forwardId = JSON.parse(returnMsg.elements[0].arkElement.bytesData).meta.detail.resid;
		return {
			message_id: msgShortId,
			forward_id: forwardId
		};
	}
	async getMessageNode(msgInfo, shortId) {
		let msg = this.ctx.store.getMsgByMsgId(msgInfo.msgId);
		if (!msg) {
			const res = await this.ctx.ntMsgApi.getSingleMsg(msgInfo.peer, msgInfo.msgSeq);
			if (res.msgList.length === 0) throw new Error(`无法获取消息 ${shortId}`);
			msg = res.msgList[0];
		}
		const obMsg = await OB11Entities.message(this.ctx, msg);
		if (!obMsg) {
			const shortId = this.ctx.store.createMsgShortId(msg);
			throw new Error(`消息 ${shortId} 解析失败`);
		}
		return {
			type: OB11MessageDataType.Node,
			data: {
				name: obMsg.sender.nickname,
				uin: obMsg.sender.user_id,
				content: obMsg.message,
				seq: obMsg.message_seq,
				time: obMsg.time,
				message_style: msg.msgStyle ? {
					bubble_id: msg.msgStyle.bubbleId,
					pendant_id: msg.msgStyle.pendantId,
					font_id: msg.msgStyle.fontId,
					font_effect_id: msg.msgStyle.fontEffectId,
					is_cs_font_effect_enabled: msg.msgStyle.isCsFontEffectEnabled,
					bubble_diy_text_id: msg.msgStyle.bubbleDiyTextId
				} : void 0
			}
		};
	}
	parseNodeContent(nodes) {
		return nodes.map((e) => {
			return {
				type: e.type,
				data: {
					...e.data,
					content: e.data.content ? message2List(e.data.content) : void 0
				}
			};
		});
	}
	sortNodesWithSeq(nodes) {
		const sortedNodes = nodes.filter((node) => !!node.data.seq).sort((a, b) => +a.data.seq - +b.data.seq);
		let sortedIndex = 0;
		for (let index = 0; index < nodes.length; index++) if (nodes[index].data.seq) nodes[index] = sortedNodes[sortedIndex++];
	}
	assignSequentialSeqs(nodes) {
		const firstDefinedIndex = nodes.findIndex((node) => node.data.seq && Number.isFinite(+node.data.seq));
		if (firstDefinedIndex === -1) {
			const initSeq = Math.trunc(Math.random() * 65430);
			nodes.forEach((node, index) => node.data.seq = initSeq + index);
			return;
		}
		const firstDefinedSeq = Math.trunc(+nodes[firstDefinedIndex].data.seq);
		let nextSeq = Math.max(0, firstDefinedSeq - firstDefinedIndex);
		for (const node of nodes) {
			const currentSeq = Number(node.data.seq);
			if (node.data.seq && Number.isFinite(currentSeq)) node.data.seq = Math.max(Math.trunc(currentSeq), nextSeq);
			else node.data.seq = nextSeq;
			nextSeq = Number(node.data.seq) + 1;
		}
	}
	assignMissingTimes(nodes) {
		const isValidTime = (time) => {
			const numericTime = Number(time);
			return time !== void 0 && time !== "" && Number.isFinite(numericTime) && numericTime > 0;
		};
		const firstDefinedIndex = nodes.findIndex((node) => isValidTime(node.data.time));
		if (firstDefinedIndex === -1) {
			const firstTime = Math.floor(Date.now() / 1e3) - nodes.length + 1;
			nodes.forEach((node, index) => node.data.time = firstTime + index);
			return;
		}
		let nextTime = Math.trunc(Number(nodes[firstDefinedIndex].data.time)) - firstDefinedIndex;
		for (const node of nodes) if (isValidTime(node.data.time)) nextTime = Math.trunc(Number(node.data.time)) + 1;
		else {
			node.data.time = nextTime;
			nextTime++;
		}
	}
};
var SendPrivateForwardMsg = class extends SendForwardMsg {
	actionName = ActionName.GoCQHTTP_SendPrivateForwardMsg;
	_handle(payload) {
		payload.message_type = "private";
		return super._handle(payload);
	}
};
var SendGroupForwardMsg = class extends SendForwardMsg {
	actionName = ActionName.GoCQHTTP_SendGroupForwardMsg;
	_handle(payload) {
		payload.message_type = "group";
		return super._handle(payload);
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetStrangerInfo.ts
var GetStrangerInfo = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetStrangerInfo;
	payloadSchema = lib_default$1.object({ user_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const uin = +payload.user_id;
		const info = await this.ctx.ntUserApi.getUserByUin(uin);
		const loginDays = await this.ctx.qqProtocol.fetchUserLoginDays(uin);
		return {
			user_id: info.uin,
			nickname: info.nick,
			sex: OB11Entities.sex(info.gender),
			age: info.age,
			qid: info.qid,
			level: info.level,
			login_days: loginDays,
			reg_time: info.registerTime,
			long_nick: info.bio,
			city: info.city,
			country: info.country,
			birthday_year: info.birthdayYear,
			birthday_month: info.birthdayMonth,
			birthday_day: info.birthdayDay,
			labels: info.labels,
			is_vip: info.isVip,
			is_svip: info.isSvip,
			is_years_vip: info.isYearsVip,
			vip_level: info.vipLevel,
			remark: info.remark
		};
	}
};
//#endregion
//#region src/onebot11/action/user/SendLike.ts
var SendLike = class extends BaseAction {
	actionName = ActionName.SendLike;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		times: lib_default$1.union([Number, String]).default(1)
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取用户信息");
		const result = await this.ctx.ntUserApi.sendProfileLike(uid, +payload.times);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupAddRequest.ts
var SetGroupAddRequest = class extends BaseAction {
	actionName = ActionName.SetGroupAddRequest;
	payloadSchema = lib_default$1.object({
		flag: lib_default$1.string().required(),
		approve: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true),
		reason: lib_default$1.string()
	});
	async _handle(payload) {
		let flag = payload.flag;
		if (isNumeric(flag)) {
			const seq = +flag;
			const res = await this.ctx.ntGroupApi.getGroupNotifications(false, 50);
			for (const v of res.notifications) if (seq === v.sequence) {
				flag = `${v.group.groupCode}|${v.sequence}|${v.type}|0`;
				break;
			}
			if (flag === payload.flag) {
				const res = await this.ctx.ntGroupApi.getGroupNotifications(true, 50);
				for (const v of res.notifications) if (seq === v.sequence) {
					flag = `${v.group.groupCode}|${v.sequence}|${v.type}|1`;
					break;
				}
				if (flag === payload.flag) throw new Error("flag 不存在");
			}
		}
		const decoded = decodeGroupRequestFlag$2(flag);
		const res = await this.ctx.ntGroupApi.setGroupRequest(decoded.doubt, decoded.groupCode, decoded.seq, decoded.type, payload.approve, payload.reason);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupLeave.ts
var SetGroupLeave = class extends BaseAction {
	actionName = ActionName.SetGroupLeave;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.quitGroup(+payload.group_id);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/GetGuildList.ts
var GetGuildList = class extends BaseAction {
	actionName = ActionName.GetGuildList;
	async _handle() {
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/Debug.ts
var Debug = class extends BaseAction {
	actionName = ActionName.Debug;
	payloadSchema = lib_default$1.object({
		apiClass: lib_default$1.string().required(),
		method: lib_default$1.string().required(),
		args: lib_default$1.array(lib_default$1.any()).default([])
	});
	async _handle(payload) {
		this.ctx.logger.info("debug request", payload);
		const res = await this.ctx.get(payload.apiClass)[payload.method](...payload.args);
		this.ctx.logger.info("debug response", res);
		return res;
	}
};
//#endregion
//#region src/onebot11/action/user/SetFriendAddRequest.ts
var SetFriendAddRequest = class extends BaseAction {
	actionName = ActionName.SetFriendAddRequest;
	payloadSchema = lib_default$1.object({
		flag: lib_default$1.string().required(),
		approve: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true),
		remark: lib_default$1.string()
	});
	async _handle(payload) {
		const result = await this.ctx.ntFriendApi.approvalFriendRequest(payload.flag, payload.approve);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		if (payload.remark) {
			const result = await this.ctx.ntFriendApi.setFriendRemark(payload.flag, payload.remark);
			if (result.errorCode !== 0) throw new Error(result.errorMsg);
		}
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupWholeBan.ts
var SetGroupWholeBan = class extends BaseAction {
	actionName = ActionName.SetGroupWholeBan;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		enable: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.muteGroup(+payload.group_id, payload.enable);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupName.ts
var SetGroupName$1 = class extends BaseAction {
	actionName = ActionName.SetGroupName;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		group_name: lib_default$1.string().required()
	});
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.setGroupName(+payload.group_id, payload.group_name);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupBan.ts
var SetGroupBan = class extends BaseAction {
	actionName = ActionName.SetGroupBan;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		duration: lib_default$1.union([Number, String]).default(1800)
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.group_id);
		if (!uid) throw new Error("无法获取用户信息");
		const res = await this.ctx.ntGroupApi.muteGroupMember(+payload.group_id, [{
			uid,
			duration: +payload.duration
		}]);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupKick.ts
var SetGroupKick = class extends BaseAction {
	actionName = ActionName.SetGroupKick;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		reject_add_request: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.group_id);
		if (!uid) throw new Error("无法获取用户信息");
		const res = await this.ctx.ntGroupApi.kickGroupMember(+payload.group_id, [uid], payload.reject_add_request);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupAdmin.ts
var SetGroupAdmin = class extends BaseAction {
	actionName = ActionName.SetGroupAdmin;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		enable: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	async _handle(payload) {
		const groupCode = +payload.group_id;
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id, groupCode);
		if (!uid) throw new Error("无法获取用户信息");
		const res = await this.ctx.ntGroupApi.setGroupMemberAdmin(groupCode, uid, payload.enable);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/group/SetGroupCard.ts
var SetGroupCard = class extends BaseAction {
	actionName = ActionName.SetGroupCard;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		card: lib_default$1.string().default("")
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.group_id);
		if (!uid) throw new Error("无法获取用户信息");
		const res = await this.ctx.ntGroupApi.setGroupMemberCard(+payload.group_id, uid, payload.card);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/file/GetFile.ts
var GetFileBase = class extends BaseAction {
	payloadSchema = lib_default$1.object({
		file: lib_default$1.string().required(),
		download: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	async _handle(payload) {
		const { enableLocalFile2Url } = this.adapter.config;
		let fileCache = await this.ctx.store.getFileCacheById(payload.file);
		if (!fileCache?.length) fileCache = await this.ctx.store.getFileCacheByName(payload.file);
		if (fileCache?.length) {
			let downloadPath = "";
			if (payload.download) {
				const file = await uri2local(this.ctx, fileCache[0].fileUuid, true);
				if (file.errMsg) throw new Error(file.errMsg);
				downloadPath = file.path;
			}
			const res = {
				file: downloadPath,
				url: "",
				file_size: fileCache[0].fileSize,
				file_name: fileCache[0].fileName
			};
			const isGroup = fileCache[0].chatType === ChatType.Group;
			if (fileCache[0].elementType === ElementType.Pic) res.url = await this.ctx.ntFileApi.getImageUrl(fileCache[0].originImageUrl, fileCache[0].md5HexStr);
			else if (fileCache[0].elementType === ElementType.Video) res.url = await this.ctx.ntFileApi.getVideoUrl(fileCache[0].fileUuid, isGroup);
			else if (fileCache[0].elementType === ElementType.Ptt) res.url = await this.ctx.ntFileApi.getPttUrl(fileCache[0].fileUuid, isGroup);
			if (enableLocalFile2Url && downloadPath && (res.file === res.url || res.url === void 0)) try {
				res.base64 = await readFile(downloadPath, "base64");
			} catch (e) {
				throw new Error("文件下载失败. " + e);
			}
			return res;
		}
		throw new Error("file not found");
	}
};
var GetFile = class extends GetFileBase {
	actionName = ActionName.GetFile;
	payloadSchema = lib_default$1.object({
		file: lib_default$1.string(),
		file_id: lib_default$1.string(),
		download: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	async _handle(payload) {
		payload.file = payload.file || payload.file_id;
		return super._handle(payload);
	}
};
//#endregion
//#region src/onebot11/action/file/GetImage.ts
var GetImage = class extends GetFileBase {
	actionName = ActionName.GetImage;
};
//#endregion
//#region src/onebot11/action/file/GetRecord.ts
function ffmpegConvert(inputPath, outputPath) {
	return new Promise((resolve, reject) => {
		(0, import_fluent_ffmpeg.default)(inputPath).output(outputPath).on("end", () => resolve()).on("error", (err) => reject(err)).run();
	});
}
var GetRecord = class extends BaseAction {
	actionName = ActionName.GetRecord;
	payloadSchema = lib_default$1.object({
		file: lib_default$1.string().required(),
		out_format: lib_default$1.union([
			"mp3",
			"amr",
			"wma",
			"m4a",
			"spx",
			"ogg",
			"wav",
			"flac"
		]).default("mp3")
	});
	async _handle(payload) {
		const fileCache = await this.ctx.store.getFileCacheByName(payload.file);
		if (!fileCache?.length) throw new Error("file not found");
		const cached = fileCache[0];
		const isGroup = cached.chatType === ChatType.Group;
		const url = await this.ctx.ntFileApi.getPttUrl(cached.fileUuid, isGroup);
		const resp = await fetch(url);
		if (!resp.ok) throw new Error(`下载语音失败: ${resp.status}`);
		const audioBytes = Buffer.from(await resp.arrayBuffer());
		const tmpBase = path.join(TEMP_DIR, randomUUID());
		const outPath = `${tmpBase}.${payload.out_format}`;
		if (isSilk(audioBytes)) {
			const silkPath = `${tmpBase}.silk`;
			await writeFile(silkPath, audioBytes);
			const decoded = await decodeSilk(this.ctx, silkPath, payload.out_format);
			const res = {
				file: decoded,
				file_name: path.basename(decoded),
				file_size: (await stat$1(decoded)).size.toString()
			};
			if (this.adapter.config.enableLocalFile2Url) res.base64 = await readFile(decoded, "base64");
			return res;
		}
		const inPath = `${tmpBase}.${audioBytes.subarray(0, 4).toString("ascii").startsWith("#!AM") ? "amr" : "audio"}`;
		await writeFile(inPath, audioBytes);
		await ffmpegConvert(inPath, outPath);
		const res = {
			file: outPath,
			file_name: path.basename(outPath),
			file_size: (await stat$1(outPath)).size.toString()
		};
		if (this.adapter.config.enableLocalFile2Url) res.base64 = await readFile(outPath, "base64");
		return res;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/MarkMsgAsRead.ts
var MarkMsgAsRead = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_MarkMsgAsRead;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const info = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!info) throw new Error("msg not found");
		const result = await this.ctx.ntMsgApi.setMsgRead(info.peer, info.msgSeq);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/system/CleanCache.ts
var CleanCache = class extends BaseAction {
	actionName = ActionName.CleanCache;
	async _handle() {
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/Config.ts
var GetConfigAction = class extends BaseAction {
	actionName = ActionName.GetConfig;
	async _handle() {
		return this.ctx.config.get();
	}
};
var SetConfigAction = class extends BaseAction {
	actionName = ActionName.SetConfig;
	payloadSchema = lib_default$1.object({
		milky: lib_default$1.any(),
		satori: lib_default$1.any(),
		ob11: lib_default$1.any(),
		webui: lib_default$1.any(),
		onlyLocalhost: lib_default$1.boolean(),
		enableLocalFile2Url: lib_default$1.boolean(),
		log: lib_default$1.boolean(),
		autoDeleteFile: lib_default$1.boolean(),
		autoDeleteFileSecond: lib_default$1.number(),
		ffmpeg: lib_default$1.string(),
		musicSignUrl: lib_default$1.string(),
		msgCacheExpire: lib_default$1.number()
	});
	async _handle(payload) {
		this.ctx.config.set(payload);
		await this.ctx.parallel("llob/config-updated", payload);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GetGroupAddRequest.ts
var GetGroupAddRequest = class extends BaseAction {
	actionName = ActionName.GetGroupIgnoreAddRequest;
	async _handle() {
		throw new Error("请使用 get_group_system_msg API, 可获取被过滤的加群通知");
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetQQAvatar.ts
var SetQQAvatar = class extends BaseAction {
	actionName = ActionName.SetQQAvatar;
	payloadSchema = lib_default$1.object({ file: lib_default$1.string().required() });
	async _handle(payload) {
		const { path, isLocal, errMsg } = await uri2local(this.ctx, payload.file);
		if (errMsg) throw new Error(errMsg);
		const ret = await this.ctx.ntUserApi.setSelfAvatar(path);
		if (!isLocal) unlink(path).catch(noop);
		if (ret.result !== 0) throw new Error(ret.errMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/DownloadFile.ts
var DownloadFile = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_DownloadFile;
	payloadSchema = lib_default$1.object({
		url: lib_default$1.string(),
		base64: lib_default$1.string(),
		headers: lib_default$1.union([String, lib_default$1.array(String)])
	});
	async _handle(payload) {
		const isRandomName = !payload.name;
		const name = payload.name ? path.basename(payload.name) : randomUUID();
		const filePath = path.join(TEMP_DIR, name);
		if (payload.base64) await fsPromise$1.writeFile(filePath, payload.base64, "base64");
		else if (payload.url) {
			const headers = this.getHeaders(payload.headers);
			const res = await fetchFile(payload.url, headers);
			await fsPromise$1.writeFile(filePath, res.data);
		} else throw new Error("不存在任何文件, 无法下载");
		if (fs$1.existsSync(filePath)) {
			if (isRandomName) {
				const md5 = await getMd5HexFromFile(filePath);
				const newPath = path.join(TEMP_DIR, md5);
				await fsPromise$1.rename(filePath, newPath);
				return { file: newPath };
			}
			return { file: filePath };
		} else throw new Error("文件写入失败, 检查权限");
	}
	getHeaders(headersIn) {
		const headers = {};
		if (typeof headersIn == "string") headersIn = headersIn.split("[\\r\\n]");
		if (Array.isArray(headersIn)) for (const headerItem of headersIn) {
			const spilt = headerItem.indexOf("=");
			if (spilt < 0) headers[headerItem] = "";
			else {
				const key = headerItem.substring(0, spilt);
				headers[key] = headerItem.substring(0, spilt + 1);
			}
		}
		if (!headers["Content-Type"]) headers["Content-Type"] = "application/octet-stream";
		return headers;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupMsgHistory.ts
var GetGroupMsgHistory = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupMsgHistory;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		message_seq: lib_default$1.union([Number, String]),
		count: lib_default$1.union([Number, String]).default(20),
		reverseOrder: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async fetchRangeRaw(peer, startSeq, endSeq) {
		return (await this.ctx.ntMsgApi.getMsgsBySeqAndCount(peer, endSeq, endSeq - startSeq + 1, true)).msgList;
	}
	async _handle(payload, config) {
		const peer = {
			chatType: ChatType.Group,
			peerUid: payload.group_id.toString()
		};
		const count = +payload.count;
		if (count === 0) return { messages: [] };
		const endSeq = payload.message_seq && +payload.message_seq > 0 ? +payload.message_seq : await this.ctx.ntMsgApi.getLatestMsgSeq(peer);
		const overallStartSeq = Math.max(1, endSeq - count + 1);
		const windows = [];
		for (let cur = endSeq; cur >= overallStartSeq; cur -= 30) {
			const start = Math.max(overallStartSeq, cur - 30 + 1);
			windows.push({
				start,
				end: cur
			});
		}
		const rawBatches = await mapWithConcurrency(windows, 5, (w) => this.fetchRangeRaw(peer, w.start, w.end), (r) => r.length === 0);
		const firstEmpty = rawBatches.findIndex((r) => r.length === 0);
		const validBatches = firstEmpty === -1 ? rawBatches : rawBatches.slice(0, firstEmpty);
		validBatches.reverse();
		const flatRaw = validBatches.flat();
		if (firstEmpty === -1 && flatRaw.length < count) {
			let remaining = count - flatRaw.length;
			let nextEndSeq = windows.at(-1).start - 1;
			while (remaining > 0 && nextEndSeq >= 1) {
				const startSeq = Math.max(1, nextEndSeq - Math.min(30, remaining) + 1);
				const batch = await this.fetchRangeRaw(peer, startSeq, nextEndSeq);
				if (batch.length === 0) break;
				flatRaw.unshift(...batch);
				remaining -= batch.length;
				nextEndSeq = startSeq - 1;
			}
		}
		const messages = await Promise.all(flatRaw.map((msg) => OB11Entities.message(this.ctx, msg, config)));
		if (messages.length > 0) {
			const info = await this.ctx.ntGroupApi.getGroup(+payload.group_id, false);
			for (const msg of messages) msg.group_name = info.groupName;
		}
		if (payload.reverseOrder) messages.reverse();
		return { messages };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetForwardMsg.ts
var GetForwardMsg = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetForwardMsg;
	payloadSchema = lib_default$1.object({
		message_id: lib_default$1.string(),
		id: lib_default$1.string()
	});
	async _handle(payload, config) {
		const resId = payload.id || payload.message_id;
		if (!resId) throw new Error("message_id 不能为空");
		const data = await this.ctx.ntMsgApi.getForwardedMsgs(resId);
		return { messages: filterNullable(await Promise.all(data.msgList.map(async (msg) => {
			const res = await OB11Entities.message(this.ctx, msg, config);
			if (res) return {
				content: res.message,
				sender: {
					nickname: res.sender.nickname,
					user_id: res.sender.user_id
				},
				time: res.time,
				message_format: res.message_format,
				message_type: res.message_type
			};
		}))) };
	}
};
//#endregion
//#region src/onebot11/action/user/GetCookie.ts
var GetCookies$1 = class extends BaseAction {
	actionName = ActionName.GetCookies;
	payloadSchema = lib_default$1.object({ domain: lib_default$1.string().required() });
	async _handle(payload) {
		if (["pay.qq.com"].includes(payload.domain)) throw new Error("该域名禁止获取cookie");
		const cookiesObject = await this.ctx.ntWebApi.getCookies(payload.domain);
		if (!cookiesObject.p_skey) {
			const pSkey = (await this.ctx.ntUserApi.getPSkey([payload.domain])).get(payload.domain);
			if (pSkey) cookiesObject.p_skey = pSkey;
		}
		return {
			cookies: Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join("; "),
			bkn: cookiesObject.skey ? this.ctx.ntWebApi.genBkn(cookiesObject.skey) : ""
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/SetMsgEmojiLike.ts
var SetMsgEmojiLike = class extends BaseAction {
	actionName = ActionName.SetMsgEmojiLike;
	payloadSchema = lib_default$1.object({
		message_id: lib_default$1.union([Number, String]).required(),
		emoji_id: lib_default$1.union([Number, String]).required(),
		set: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true)
	});
	set;
	async _handle(payload) {
		const msg = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!msg) throw new Error("msg not found");
		if (msg.peer.chatType !== ChatType.Group) throw new Error("只支持群聊消息");
		const res = await this.ctx.ntMsgApi.setGroupMsgReaction(+msg.peer.peerUid, msg.msgSeq, payload.emoji_id.toString(), this.set ?? payload.set);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
var UnSetMsgEmojiLike = class extends SetMsgEmojiLike {
	actionName = ActionName.UnSetMsgEmojiLike;
	set = false;
};
//#endregion
//#region node_modules/fast-xml-parser/src/util.js
var regexName = /* @__PURE__ */ new RegExp("^[:A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");
function getAllMatches(string, regex) {
	const matches = [];
	let match = regex.exec(string);
	while (match) {
		const allmatches = [];
		allmatches.startIndex = regex.lastIndex - match[0].length;
		const len = match.length;
		for (let index = 0; index < len; index++) allmatches.push(match[index]);
		matches.push(allmatches);
		match = regex.exec(string);
	}
	return matches;
}
var isName = function(string) {
	const match = regexName.exec(string);
	return !(match === null || typeof match === "undefined");
};
function isExist(v) {
	return typeof v !== "undefined";
}
/**
* Dangerous property names that could lead to prototype pollution or security issues
*/
var DANGEROUS_PROPERTY_NAMES = [
	"hasOwnProperty",
	"toString",
	"valueOf",
	"__defineGetter__",
	"__defineSetter__",
	"__lookupGetter__",
	"__lookupSetter__"
];
var criticalProperties = [
	"__proto__",
	"constructor",
	"prototype"
];
//#endregion
//#region node_modules/fast-xml-parser/src/validator.js
var defaultOptions$1 = {
	allowBooleanAttributes: false,
	unpairedTags: []
};
function validate(xmlData, options) {
	options = Object.assign({}, defaultOptions$1, options);
	const tags = [];
	let tagFound = false;
	let reachedRoot = false;
	if (xmlData[0] === "﻿") xmlData = xmlData.substr(1);
	for (let i = 0; i < xmlData.length; i++) if (xmlData[i] === "<" && xmlData[i + 1] === "?") {
		i += 2;
		i = readPI(xmlData, i);
		if (i.err) return i;
	} else if (xmlData[i] === "<") {
		let tagStartPos = i;
		i++;
		if (xmlData[i] === "!") {
			i = readCommentAndCDATA(xmlData, i);
			continue;
		} else {
			let closingTag = false;
			if (xmlData[i] === "/") {
				closingTag = true;
				i++;
			}
			let tagName = "";
			for (; i < xmlData.length && xmlData[i] !== ">" && xmlData[i] !== " " && xmlData[i] !== "	" && xmlData[i] !== "\n" && xmlData[i] !== "\r"; i++) tagName += xmlData[i];
			tagName = tagName.trim();
			if (tagName[tagName.length - 1] === "/") {
				tagName = tagName.substring(0, tagName.length - 1);
				i--;
			}
			if (!validateTagName(tagName)) {
				let msg;
				if (tagName.trim().length === 0) msg = "Invalid space after '<'.";
				else msg = "Tag '" + tagName + "' is an invalid name.";
				return getErrorObject("InvalidTag", msg, getLineNumberForPosition(xmlData, i));
			}
			const result = readAttributeStr(xmlData, i);
			if (result === false) return getErrorObject("InvalidAttr", "Attributes for '" + tagName + "' have open quote.", getLineNumberForPosition(xmlData, i));
			let attrStr = result.value;
			i = result.index;
			if (attrStr[attrStr.length - 1] === "/") {
				const attrStrStart = i - attrStr.length;
				attrStr = attrStr.substring(0, attrStr.length - 1);
				const isValid = validateAttributeString(attrStr, options);
				if (isValid === true) tagFound = true;
				else return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));
			} else if (closingTag) if (!result.tagClosed) return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' doesn't have proper closing.", getLineNumberForPosition(xmlData, i));
			else if (attrStr.trim().length > 0) return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos));
			else if (tags.length === 0) return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos));
			else {
				const otg = tags.pop();
				if (tagName !== otg.tagName) {
					let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);
					return getErrorObject("InvalidTag", "Expected closing tag '" + otg.tagName + "' (opened in line " + openPos.line + ", col " + openPos.col + ") instead of closing tag '" + tagName + "'.", getLineNumberForPosition(xmlData, tagStartPos));
				}
				if (tags.length == 0) reachedRoot = true;
			}
			else {
				const isValid = validateAttributeString(attrStr, options);
				if (isValid !== true) return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));
				if (reachedRoot === true) return getErrorObject("InvalidXml", "Multiple possible root nodes found.", getLineNumberForPosition(xmlData, i));
				else if (options.unpairedTags.indexOf(tagName) !== -1) {} else tags.push({
					tagName,
					tagStartPos
				});
				tagFound = true;
			}
			for (i++; i < xmlData.length; i++) if (xmlData[i] === "<") if (xmlData[i + 1] === "!") {
				i++;
				i = readCommentAndCDATA(xmlData, i);
				continue;
			} else if (xmlData[i + 1] === "?") {
				i = readPI(xmlData, ++i);
				if (i.err) return i;
			} else break;
			else if (xmlData[i] === "&") {
				const afterAmp = validateAmpersand(xmlData, i);
				if (afterAmp == -1) return getErrorObject("InvalidChar", "char '&' is not expected.", getLineNumberForPosition(xmlData, i));
				i = afterAmp;
			} else if (reachedRoot === true && !isWhiteSpace(xmlData[i])) return getErrorObject("InvalidXml", "Extra text at the end", getLineNumberForPosition(xmlData, i));
			if (xmlData[i] === "<") i--;
		}
	} else {
		if (isWhiteSpace(xmlData[i])) continue;
		return getErrorObject("InvalidChar", "char '" + xmlData[i] + "' is not expected.", getLineNumberForPosition(xmlData, i));
	}
	if (!tagFound) return getErrorObject("InvalidXml", "Start tag expected.", 1);
	else if (tags.length == 1) return getErrorObject("InvalidTag", "Unclosed tag '" + tags[0].tagName + "'.", getLineNumberForPosition(xmlData, tags[0].tagStartPos));
	else if (tags.length > 0) return getErrorObject("InvalidXml", "Invalid '" + JSON.stringify(tags.map((t) => t.tagName), null, 4).replace(/\r?\n/g, "") + "' found.", {
		line: 1,
		col: 1
	});
	return true;
}
function isWhiteSpace(char) {
	return char === " " || char === "	" || char === "\n" || char === "\r";
}
/**
* Read Processing insstructions and skip
* @param {*} xmlData
* @param {*} i
*/
function readPI(xmlData, i) {
	const start = i;
	for (; i < xmlData.length; i++) if (xmlData[i] == "?" || xmlData[i] == " ") {
		const tagname = xmlData.substr(start, i - start);
		if (i > 5 && tagname === "xml") return getErrorObject("InvalidXml", "XML declaration allowed only at the start of the document.", getLineNumberForPosition(xmlData, i));
		else if (xmlData[i] == "?" && xmlData[i + 1] == ">") {
			i++;
			break;
		} else continue;
	}
	return i;
}
function readCommentAndCDATA(xmlData, i) {
	if (xmlData.length > i + 5 && xmlData[i + 1] === "-" && xmlData[i + 2] === "-") {
		for (i += 3; i < xmlData.length; i++) if (xmlData[i] === "-" && xmlData[i + 1] === "-" && xmlData[i + 2] === ">") {
			i += 2;
			break;
		}
	} else if (xmlData.length > i + 8 && xmlData[i + 1] === "D" && xmlData[i + 2] === "O" && xmlData[i + 3] === "C" && xmlData[i + 4] === "T" && xmlData[i + 5] === "Y" && xmlData[i + 6] === "P" && xmlData[i + 7] === "E") {
		let angleBracketsCount = 1;
		for (i += 8; i < xmlData.length; i++) if (xmlData[i] === "<") angleBracketsCount++;
		else if (xmlData[i] === ">") {
			angleBracketsCount--;
			if (angleBracketsCount === 0) break;
		}
	} else if (xmlData.length > i + 9 && xmlData[i + 1] === "[" && xmlData[i + 2] === "C" && xmlData[i + 3] === "D" && xmlData[i + 4] === "A" && xmlData[i + 5] === "T" && xmlData[i + 6] === "A" && xmlData[i + 7] === "[") {
		for (i += 8; i < xmlData.length; i++) if (xmlData[i] === "]" && xmlData[i + 1] === "]" && xmlData[i + 2] === ">") {
			i += 2;
			break;
		}
	}
	return i;
}
var doubleQuote = "\"";
var singleQuote = "'";
/**
* Keep reading xmlData until '<' is found outside the attribute value.
* @param {string} xmlData
* @param {number} i
*/
function readAttributeStr(xmlData, i) {
	let attrStr = "";
	let startChar = "";
	let tagClosed = false;
	for (; i < xmlData.length; i++) {
		if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) if (startChar === "") startChar = xmlData[i];
		else if (startChar !== xmlData[i]) {} else startChar = "";
		else if (xmlData[i] === ">") {
			if (startChar === "") {
				tagClosed = true;
				break;
			}
		}
		attrStr += xmlData[i];
	}
	if (startChar !== "") return false;
	return {
		value: attrStr,
		index: i,
		tagClosed
	};
}
/**
* Select all the attributes whether valid or invalid.
*/
var validAttrStrRegxp = /* @__PURE__ */ new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?", "g");
function validateAttributeString(attrStr, options) {
	const matches = getAllMatches(attrStr, validAttrStrRegxp);
	const attrNames = {};
	for (let i = 0; i < matches.length; i++) {
		if (matches[i][1].length === 0) return getErrorObject("InvalidAttr", "Attribute '" + matches[i][2] + "' has no space in starting.", getPositionFromMatch(matches[i]));
		else if (matches[i][3] !== void 0 && matches[i][4] === void 0) return getErrorObject("InvalidAttr", "Attribute '" + matches[i][2] + "' is without value.", getPositionFromMatch(matches[i]));
		else if (matches[i][3] === void 0 && !options.allowBooleanAttributes) return getErrorObject("InvalidAttr", "boolean attribute '" + matches[i][2] + "' is not allowed.", getPositionFromMatch(matches[i]));
		const attrName = matches[i][2];
		if (!validateAttrName(attrName)) return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is an invalid name.", getPositionFromMatch(matches[i]));
		if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) attrNames[attrName] = 1;
		else return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is repeated.", getPositionFromMatch(matches[i]));
	}
	return true;
}
function validateNumberAmpersand(xmlData, i) {
	let re = /\d/;
	if (xmlData[i] === "x") {
		i++;
		re = /[\da-fA-F]/;
	}
	for (; i < xmlData.length; i++) {
		if (xmlData[i] === ";") return i;
		if (!xmlData[i].match(re)) break;
	}
	return -1;
}
function validateAmpersand(xmlData, i) {
	i++;
	if (xmlData[i] === ";") return -1;
	if (xmlData[i] === "#") {
		i++;
		return validateNumberAmpersand(xmlData, i);
	}
	let count = 0;
	for (; i < xmlData.length; i++, count++) {
		if (xmlData[i].match(/\w/) && count < 20) continue;
		if (xmlData[i] === ";") break;
		return -1;
	}
	return i;
}
function getErrorObject(code, message, lineNumber) {
	return { err: {
		code,
		msg: message,
		line: lineNumber.line || lineNumber,
		col: lineNumber.col
	} };
}
function validateAttrName(attrName) {
	return isName(attrName);
}
function validateTagName(tagname) {
	return isName(tagname);
}
function getLineNumberForPosition(xmlData, index) {
	const lines = xmlData.substring(0, index).split(/\r?\n/);
	return {
		line: lines.length,
		col: lines[lines.length - 1].length + 1
	};
}
function getPositionFromMatch(match) {
	return match.startIndex + match[1].length;
}
//#endregion
//#region node_modules/@nodable/entities/src/entities.js
/**
* Currency Symbols
* @type {Record<string, string>}
*/
var CURRENCY = {
	cent: "¢",
	pound: "£",
	curren: "¤",
	yen: "¥",
	euro: "€",
	dollar: "$",
	fnof: "ƒ",
	inr: "₹",
	af: "؋",
	birr: "ብር",
	peso: "₱",
	rub: "₽",
	won: "₩",
	yuan: "¥",
	cedil: "¸"
};
var XML = {
	amp: "&",
	apos: "'",
	gt: ">",
	lt: "<",
	quot: "\""
};
var COMMON_HTML = {
	nbsp: "\xA0",
	copy: "©",
	reg: "®",
	trade: "™",
	mdash: "—",
	ndash: "–",
	hellip: "…",
	laquo: "«",
	raquo: "»",
	lsquo: "‘",
	rsquo: "’",
	ldquo: "“",
	rdquo: "”",
	bull: "•",
	para: "¶",
	sect: "§",
	deg: "°",
	frac12: "½",
	frac14: "¼",
	frac34: "¾"
};
//#endregion
//#region node_modules/@nodable/entities/src/EntityDecoder.js
/**
* Action constants for `onExternalEntity` and `onInputEntity` hooks.
*
* Use these instead of raw strings to avoid typos:
*
* @example
* import EntityDecoder, { ENTITY_ACTION } from './EntityDecoder.js';
* const dec = new EntityDecoder({
*   onInputEntity: (name, value) => ENTITY_ACTION.BLOCK,
* });
*/
var ENTITY_ACTION = Object.freeze({
	/** Resolve and expand the entity normally. */
	ALLOW: "allow",
	/** Silently skip this entity — it will not be registered. */
	BLOCK: "block",
	/** Throw an error, aborting entity registration entirely. */
	THROW: "throw"
});
var SPECIAL_CHARS = /* @__PURE__ */ new Set("!?\\\\/[]$%{}^&*()<>|+");
/**
* Validate that an entity name contains no dangerous characters.
* @param {string} name
* @returns {string} the name, unchanged
* @throws {Error} on invalid characters
*/
function validateEntityName$1(name) {
	if (name[0] === "#") throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${name}"`);
	for (const ch of name) if (SPECIAL_CHARS.has(ch)) throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: "${name}"`);
	return name;
}
/**
* Merge one or more entity maps into a flat name→string map.
* Accepts either:
*   - plain string values:             { amp: '&' }
*   - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } }
*
* Values containing '&' are skipped (recursive expansion risk).
*
* @param {...object} maps
* @returns {Record<string, string>}
*/
function mergeEntityMaps(...maps) {
	const out = Object.create(null);
	for (const map of maps) {
		if (!map) continue;
		for (const key of Object.keys(map)) {
			const raw = map[key];
			if (typeof raw === "string") out[key] = raw;
			else if (raw && typeof raw === "object" && raw.val !== void 0) {
				const val = raw.val;
				if (typeof val === "string") out[key] = val;
			}
		}
	}
	return out;
}
var LIMIT_TIER_EXTERNAL = "external";
var LIMIT_TIER_BASE = "base";
var LIMIT_TIER_ALL = "all";
/**
* Resolve `applyLimitsTo` option into a normalised Set of tier strings.
* Accepted values: 'external' | 'base' | 'all' | string[]
* Default: 'external' (only untrusted injected entities are counted).
* @param {string|string[]|undefined} raw
* @returns {Set<string>}
*/
function parseLimitTiers(raw) {
	if (!raw || raw === LIMIT_TIER_EXTERNAL) return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]);
	if (raw === LIMIT_TIER_ALL) return /* @__PURE__ */ new Set([LIMIT_TIER_ALL]);
	if (raw === LIMIT_TIER_BASE) return /* @__PURE__ */ new Set([LIMIT_TIER_BASE]);
	if (Array.isArray(raw)) return new Set(raw);
	return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]);
}
var NCR_LEVEL = Object.freeze({
	allow: 0,
	leave: 1,
	remove: 2,
	throw: 3
});
var XML10_ALLOWED_C0 = /* @__PURE__ */ new Set([
	9,
	10,
	13
]);
/**
* Parse the `ncr` constructor option into flat, hot-path-friendly fields.
* @param {object|undefined} ncr
* @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }}
*/
function parseNCRConfig(ncr) {
	if (!ncr) return {
		xmlVersion: 1,
		onLevel: NCR_LEVEL.allow,
		nullLevel: NCR_LEVEL.remove
	};
	const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1;
	const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;
	const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;
	return {
		xmlVersion,
		onLevel,
		nullLevel: Math.max(nullLevel, NCR_LEVEL.remove)
	};
}
/**
* Single-pass, zero-regex entity replacer for XML/HTML content.
*
* Algorithm: scan the string once for '&', read to ';', resolve via map
* or direct codepoint conversion, build output chunks, join once at the end.
*
* Entity lookup priority (highest → lowest):
*   1. input / runtime  (DOCTYPE entities for current document)
*   2. persistent external (survive across documents)
*   3. base named map   (DEFAULT_XML_ENTITIES + user-supplied namedEntities)
*
* Both input and external resolve as the 'external' tier for limit purposes.
* Base map entities resolve as the 'base' tier.
*
* Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via
* String.fromCodePoint() — no map needed. They count as 'base' tier.
*
* @example
* const replacer = new EntityReplacer({ namedEntities: COMMON_HTML });
* replacer.setExternalEntities({ brand: 'Acme' });
*
* const instance = replacer.reset();
* instance.addInputEntities({ version: '1.0' });
* instance.encode('&brand; v&version; &lt;'); // 'Acme v1.0 <'
*/
var EntityDecoder = class {
	/**
	* @param {object} [options]
	* @param {object|null}  [options.namedEntities]        — extra named entities merged into base map
	* @param {object}  [options.limit]                 — security limits
	* @param {number}       [options.limit.maxTotalExpansions=0]  — 0 = unlimited
	* @param {number}       [options.limit.maxExpandedLength=0]   — 0 = unlimited
	* @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']
	*   Which entity tiers count against the security limits:
	*   - 'external' (default) — only input/runtime + persistent external entities
	*   - 'base'               — only DEFAULT_XML_ENTITIES + namedEntities
	*   - 'all'                — every entity regardless of tier
	*   - string[]             — explicit combination, e.g. ['external', 'base']
	* @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]
	* @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)
	* @param {string[]} [options.leave=[]]  — entity names to keep as literal (unchanged in output)
	* @param {object}   [options.ncr]       — Numeric Character Reference controls
	* @param {1.0|1.1}  [options.ncr.xmlVersion=1.0]
	*   XML version governing which codepoint ranges are restricted:
	*   - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited
	*   - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is
	* @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']
	*   Base action for numeric references. Severity order: allow < leave < remove < throw.
	*   For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),
	*   the effective action is max(onNCR, rangeMinimum).
	* @param {'remove'|'throw'} [options.ncr.nullNCR='remove']
	*   Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.
	* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onExternalEntity=null]
	*   Hook called when an external entity is registered via `setExternalEntities()` or
	*   `addExternalEntity()`. Return `ENTITY_ACTION.ALLOW` to accept the entity,
	*   `ENTITY_ACTION.BLOCK` to silently skip it, or `ENTITY_ACTION.THROW` to abort with an error.
	* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onInputEntity=null]
	*   Hook called when an input entity is registered via `addInputEntities()`. Return
	*   `ENTITY_ACTION.ALLOW` to accept, `ENTITY_ACTION.BLOCK` to silently skip, or
	*   `ENTITY_ACTION.THROW` to abort with an error.
	*/
	constructor(options = {}) {
		this._limit = options.limit || {};
		this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;
		this._maxExpandedLength = this._limit.maxExpandedLength || 0;
		this._postCheck = typeof options.postCheck === "function" ? options.postCheck : (r) => r;
		this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);
		this._numericAllowed = options.numericAllowed ?? true;
		this._baseMap = mergeEntityMaps(XML, options.namedEntities || null);
		/** @type {Record<string, string>} */
		this._externalMap = Object.create(null);
		/** @type {Record<string, string>} */
		this._inputMap = Object.create(null);
		this._totalExpansions = 0;
		this._expandedLength = 0;
		/** @type {Set<string>} */
		this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);
		/** @type {Set<string>} */
		this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);
		const ncrCfg = parseNCRConfig(options.ncr);
		this._ncrXmlVersion = ncrCfg.xmlVersion;
		this._ncrOnLevel = ncrCfg.onLevel;
		this._ncrNullLevel = ncrCfg.nullLevel;
		/** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */
		this._onExternalEntity = typeof options.onExternalEntity === "function" ? options.onExternalEntity : null;
		/** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */
		this._onInputEntity = typeof options.onInputEntity === "function" ? options.onInputEntity : null;
	}
	/**
	* Invoke a registration hook for a single entity name/value pair.
	* Returns true when the entity should be accepted, false when it should be
	* silently skipped (BLOCK), and throws when the hook returns THROW.
	*
	* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} hook
	* @param {string} name
	* @param {string} value
	* @param {string} context  — used in error messages ('external' | 'input')
	* @returns {boolean}  true = accept, false = skip
	*/
	_applyRegistrationHook(hook, name, value, context) {
		if (!hook) return true;
		const action = hook(name, value);
		if (action === ENTITY_ACTION.BLOCK) return false;
		if (action === ENTITY_ACTION.THROW) throw new Error(`[EntityDecoder] Registration of ${context} entity "&${name};" was rejected by hook`);
		return true;
	}
	/**
	* Replace the full set of persistent external entities.
	* All keys are validated — throws on invalid characters.
	* If `onExternalEntity` is set, it is called once per entry; entries that
	* return `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW`
	* aborts the whole call.
	* @param {Record<string, string | { regex?: RegExp, val: string }>} map
	*/
	setExternalEntities(map) {
		if (map) for (const key of Object.keys(map)) validateEntityName$1(key);
		if (!this._onExternalEntity) {
			this._externalMap = mergeEntityMaps(map);
			return;
		}
		const flat = mergeEntityMaps(map);
		const filtered = Object.create(null);
		for (const [name, value] of Object.entries(flat)) if (this._applyRegistrationHook(this._onExternalEntity, name, value, "external")) filtered[name] = value;
		this._externalMap = filtered;
	}
	/**
	* Add a single persistent external entity.
	* If `onExternalEntity` is set it is called before the entity is stored;
	* `ENTITY_ACTION.BLOCK` silently skips storage, `ENTITY_ACTION.THROW` raises.
	* @param {string} key
	* @param {string} value
	*/
	addExternalEntity(key, value) {
		validateEntityName$1(key);
		if (typeof value === "string" && value.indexOf("&") === -1) {
			if (this._applyRegistrationHook(this._onExternalEntity, key, value, "external")) this._externalMap[key] = value;
		}
	}
	/**
	* Inject DOCTYPE entities for the current document.
	* Also resets per-document expansion counters.
	* If `onInputEntity` is set it is called once per entry; entries returning
	* `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW` aborts.
	* @param {Record<string, string | { regx?: RegExp, regex?: RegExp, val: string }>} map
	*/
	addInputEntities(map) {
		this._totalExpansions = 0;
		this._expandedLength = 0;
		if (!this._onInputEntity) {
			this._inputMap = mergeEntityMaps(map);
			return;
		}
		const flat = mergeEntityMaps(map);
		const filtered = Object.create(null);
		for (const [name, value] of Object.entries(flat)) if (this._applyRegistrationHook(this._onInputEntity, name, value, "input")) filtered[name] = value;
		this._inputMap = filtered;
	}
	/**
	* Wipe input/runtime entities and reset counters.
	* Call this before processing each new document.
	* @returns {this}
	*/
	reset() {
		this._inputMap = Object.create(null);
		this._totalExpansions = 0;
		this._expandedLength = 0;
		return this;
	}
	/**
	* Update the XML version used for NCR classification.
	* Call this as soon as the document's `<?xml version="...">` declaration is parsed.
	* @param {1.0|1.1|number} version
	*/
	setXmlVersion(version) {
		this._ncrXmlVersion = version === 1.1 ? 1.1 : 1;
	}
	/**
	* Replace all entity references in `str` in a single pass.
	*
	* @param {string} str
	* @returns {string}
	*/
	decode(str) {
		if (typeof str !== "string" || str.length === 0) return str;
		if (str.indexOf("&") === -1) return str;
		const original = str;
		const chunks = [];
		const len = str.length;
		let last = 0;
		let i = 0;
		const limitExpansions = this._maxTotalExpansions > 0;
		const limitLength = this._maxExpandedLength > 0;
		const checkLimits = limitExpansions || limitLength;
		while (i < len) {
			if (str.charCodeAt(i) !== 38) {
				i++;
				continue;
			}
			let j = i + 1;
			while (j < len && str.charCodeAt(j) !== 59 && j - i <= 32) j++;
			if (j >= len || str.charCodeAt(j) !== 59) {
				i++;
				continue;
			}
			const token = str.slice(i + 1, j);
			if (token.length === 0) {
				i++;
				continue;
			}
			let replacement;
			let tier;
			if (this._removeSet.has(token)) {
				replacement = "";
				if (tier === void 0) tier = LIMIT_TIER_EXTERNAL;
			} else if (this._leaveSet.has(token)) {
				i++;
				continue;
			} else if (token.charCodeAt(0) === 35) {
				const ncrResult = this._resolveNCR(token);
				if (ncrResult === void 0) {
					i++;
					continue;
				}
				replacement = ncrResult;
				tier = LIMIT_TIER_BASE;
			} else {
				const resolved = this._resolveName(token);
				replacement = resolved?.value;
				tier = resolved?.tier;
			}
			if (replacement === void 0) {
				i++;
				continue;
			}
			if (i > last) chunks.push(str.slice(last, i));
			chunks.push(replacement);
			last = j + 1;
			i = last;
			if (checkLimits && this._tierCounts(tier)) {
				if (limitExpansions) {
					this._totalExpansions++;
					if (this._totalExpansions > this._maxTotalExpansions) throw new Error(`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`);
				}
				if (limitLength) {
					const delta = replacement.length - (token.length + 2);
					if (delta > 0) {
						this._expandedLength += delta;
						if (this._expandedLength > this._maxExpandedLength) throw new Error(`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`);
					}
				}
			}
		}
		if (last < len) chunks.push(str.slice(last));
		const result = chunks.length === 0 ? str : chunks.join("");
		return this._postCheck(result, original);
	}
	/**
	* Returns true if a resolved entity of the given tier should count
	* against the expansion/length limits.
	* @param {string} tier  — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE
	* @returns {boolean}
	*/
	_tierCounts(tier) {
		if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;
		return this._limitTiers.has(tier);
	}
	/**
	* Resolve a named entity token (without & and ;).
	* Priority: inputMap > externalMap > baseMap
	* Returns the resolved value tagged with its limit tier.
	*
	* @param {string} name
	* @returns {{ value: string, tier: string }|undefined}
	*/
	_resolveName(name) {
		if (name in this._inputMap) return {
			value: this._inputMap[name],
			tier: LIMIT_TIER_EXTERNAL
		};
		if (name in this._externalMap) return {
			value: this._externalMap[name],
			tier: LIMIT_TIER_EXTERNAL
		};
		if (name in this._baseMap) return {
			value: this._baseMap[name],
			tier: LIMIT_TIER_BASE
		};
	}
	/**
	* Classify a codepoint and return the minimum action level that must be applied.
	* Returns -1 when no minimum is imposed (normal allow path).
	*
	* Ranges checked (in priority order):
	*   1. U+0000            — null, governed by nullNCR (always ≥ remove)
	*   2. U+D800–U+DFFF     — surrogates, always prohibited (min: remove)
	*   3. U+0001–U+001F \ {0x09,0x0A,0x0D}  — XML 1.0 restricted C0 (min: remove)
	*      (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)
	*
	* @param {number} cp  — codepoint
	* @returns {number}   — minimum NCR_LEVEL value, or -1 for no restriction
	*/
	_classifyNCR(cp) {
		if (cp === 0) return this._ncrNullLevel;
		if (cp >= 55296 && cp <= 57343) return NCR_LEVEL.remove;
		if (this._ncrXmlVersion === 1) {
			if (cp >= 1 && cp <= 31 && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;
		}
		return -1;
	}
	/**
	* Execute a resolved NCR action.
	*
	* @param {number} action   — NCR_LEVEL value
	* @param {string} token    — raw token (e.g. '#38') for error messages
	* @param {number} cp       — codepoint, used only for error messages
	* @returns {string|undefined}
	*   - decoded character string  → 'allow'
	*   - ''                        → 'remove'
	*   - undefined                 → 'leave' (caller must skip past '&' only)
	*   - throws Error              → 'throw'
	*/
	_applyNCRAction(action, token, cp) {
		switch (action) {
			case NCR_LEVEL.allow: return String.fromCodePoint(cp);
			case NCR_LEVEL.remove: return "";
			case NCR_LEVEL.leave: return;
			case NCR_LEVEL.throw: throw new Error(`[EntityDecoder] Prohibited numeric character reference &${token}; (U+${cp.toString(16).toUpperCase().padStart(4, "0")})`);
			default: return String.fromCodePoint(cp);
		}
	}
	/**
	* Full NCR resolution pipeline for a numeric token.
	*
	* Steps:
	*   1. Parse the codepoint (decimal or hex).
	*   2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).
	*   3. If numericAllowed is false and no minimum restriction applies → leave as-is.
	*   4. Classify the codepoint to find the minimum required action level.
	*   5. Resolve effective action = max(onNCR, minimum).
	*   6. Apply and return.
	*
	* @param {string} token  — e.g. '#38', '#x26', '#X26'
	* @returns {string|undefined}
	*   - string (incl. '')  — replacement ('' = remove)
	*   - undefined          — leave original &token; as-is
	*/
	_resolveNCR(token) {
		const second = token.charCodeAt(1);
		let cp;
		if (second === 120 || second === 88) cp = parseInt(token.slice(2), 16);
		else cp = parseInt(token.slice(1), 10);
		if (Number.isNaN(cp) || cp < 0 || cp > 1114111) return void 0;
		const minimum = this._classifyNCR(cp);
		if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return void 0;
		const effective = minimum === -1 ? this._ncrOnLevel : Math.max(this._ncrOnLevel, minimum);
		return this._applyNCRAction(effective, token, cp);
	}
};
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js
var defaultOnDangerousProperty = (name) => {
	if (DANGEROUS_PROPERTY_NAMES.includes(name)) return "__" + name;
	return name;
};
var defaultOptions = {
	preserveOrder: false,
	attributeNamePrefix: "@_",
	attributesGroupName: false,
	textNodeName: "#text",
	ignoreAttributes: true,
	removeNSPrefix: false,
	allowBooleanAttributes: false,
	parseTagValue: true,
	parseAttributeValue: false,
	trimValues: true,
	cdataPropName: false,
	numberParseOptions: {
		hex: true,
		leadingZeros: true,
		eNotation: true,
		unicode: false
	},
	tagValueProcessor: function(tagName, val) {
		return val;
	},
	attributeValueProcessor: function(attrName, val) {
		return val;
	},
	stopNodes: [],
	alwaysCreateTextNode: false,
	isArray: () => false,
	commentPropName: false,
	unpairedTags: [],
	processEntities: true,
	htmlEntities: false,
	entityDecoder: null,
	ignoreDeclaration: false,
	ignorePiTags: false,
	transformTagName: false,
	transformAttributeName: false,
	updateTag: function(tagName, jPath, attrs) {
		return tagName;
	},
	captureMetaData: false,
	maxNestedTags: 100,
	strictReservedNames: true,
	jPath: true,
	onDangerousProperty: defaultOnDangerousProperty
};
/**
* Validates that a property name is safe to use
* @param {string} propertyName - The property name to validate
* @param {string} optionName - The option field name (for error message)
* @throws {Error} If property name is dangerous
*/
function validatePropertyName(propertyName, optionName) {
	if (typeof propertyName !== "string") return;
	const normalized = propertyName.toLowerCase();
	if (DANGEROUS_PROPERTY_NAMES.some((dangerous) => normalized === dangerous.toLowerCase())) throw new Error(`[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`);
	if (criticalProperties.some((dangerous) => normalized === dangerous.toLowerCase())) throw new Error(`[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`);
}
/**
* Normalizes processEntities option for backward compatibility
* @param {boolean|object} value 
* @returns {object} Always returns normalized object
*/
function normalizeProcessEntities(value, htmlEntities) {
	if (typeof value === "boolean") return {
		enabled: value,
		maxEntitySize: 1e4,
		maxExpansionDepth: 1e4,
		maxTotalExpansions: Infinity,
		maxExpandedLength: 1e5,
		maxEntityCount: 1e3,
		allowedTags: null,
		tagFilter: null,
		appliesTo: "all"
	};
	if (typeof value === "object" && value !== null) return {
		enabled: value.enabled !== false,
		maxEntitySize: Math.max(1, value.maxEntitySize ?? 1e4),
		maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 1e4),
		maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),
		maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 1e5),
		maxEntityCount: Math.max(1, value.maxEntityCount ?? 1e3),
		allowedTags: value.allowedTags ?? null,
		tagFilter: value.tagFilter ?? null,
		appliesTo: value.appliesTo ?? "all"
	};
	return normalizeProcessEntities(true);
}
var buildOptions = function(options) {
	const built = Object.assign({}, defaultOptions, options);
	const propertyNameOptions = [
		{
			value: built.attributeNamePrefix,
			name: "attributeNamePrefix"
		},
		{
			value: built.attributesGroupName,
			name: "attributesGroupName"
		},
		{
			value: built.textNodeName,
			name: "textNodeName"
		},
		{
			value: built.cdataPropName,
			name: "cdataPropName"
		},
		{
			value: built.commentPropName,
			name: "commentPropName"
		}
	];
	for (const { value, name } of propertyNameOptions) if (value) validatePropertyName(value, name);
	if (built.onDangerousProperty === null) built.onDangerousProperty = defaultOnDangerousProperty;
	built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);
	built.unpairedTagsSet = new Set(built.unpairedTags);
	if (built.stopNodes && Array.isArray(built.stopNodes)) built.stopNodes = built.stopNodes.map((node) => {
		if (typeof node === "string" && node.startsWith("*.")) return ".." + node.substring(2);
		return node;
	});
	return built;
};
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/xmlNode.js
var METADATA_SYMBOL$1;
if (typeof Symbol !== "function") METADATA_SYMBOL$1 = "@@xmlMetadata";
else METADATA_SYMBOL$1 = Symbol("XML Node Metadata");
var XmlNode = class {
	constructor(tagname) {
		this.tagname = tagname;
		this.child = [];
		this[":@"] = Object.create(null);
	}
	add(key, val) {
		if (key === "__proto__") key = "#__proto__";
		this.child.push({ [key]: val });
	}
	addChild(node, startIndex) {
		if (node.tagname === "__proto__") node.tagname = "#__proto__";
		if (node[":@"] && Object.keys(node[":@"]).length > 0) this.child.push({
			[node.tagname]: node.child,
			[":@"]: node[":@"]
		});
		else this.child.push({ [node.tagname]: node.child });
		if (startIndex !== void 0) this.child[this.child.length - 1][METADATA_SYMBOL$1] = { startIndex };
	}
	/** symbol used for metadata */
	static getMetaDataSymbol() {
		return METADATA_SYMBOL$1;
	}
};
//#endregion
//#region node_modules/fast-xml-parser/node_modules/xml-naming/src/index.js
/**
* xml-naming
* Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.
* Covers: Name, NCName, QName, NMToken, NMTokens
*
* XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name
* XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar
* XML NS spec:  https://www.w3.org/TR/xml-names/#NT-NCName
*/
var nameStartChar10 = ":A-Za-z_À-ÖØ-öø-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�";
var nameChar10 = ":A-Za-z_À-ÖØ-öø-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�\\-\\.\\d·̀-ͯ‿-⁀";
var nameStartChar11 = ":A-Za-z_À-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿";
var nameChar11 = ":A-Za-z_À-˿Ͱ-ͽͿ-҆҈-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�𐀀-󯿿\\-\\.\\d·̀-ͯ҇‿-⁀";
var buildRegexes = (startChar, char, flags = "") => {
	const ncNamePat = `[${startChar.replace(":", "")}][${char.replace(":", "")}]*`;
	return {
		name: new RegExp(`^[${startChar}][${char}]*$`, flags),
		ncName: new RegExp(`^${ncNamePat}$`, flags),
		qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),
		nmToken: new RegExp(`^[${char}]+$`, flags),
		nmTokens: new RegExp(`^[${char}]+(?:\\s+[${char}]+)*$`, flags)
	};
};
var regexes10 = buildRegexes(nameStartChar10, nameChar10);
var regexes11 = buildRegexes(nameStartChar11, nameChar11, "u");
var regexesAscii = buildRegexes(":A-Za-z_", ":A-Za-z_\\-\\.\\d");
var getRegexes = (xmlVersion = "1.0", asciiOnly = false) => {
	if (asciiOnly) return regexesAscii;
	return xmlVersion === "1.1" ? regexes11 : regexes10;
};
/**
* Returns true if the string is a valid QName (Qualified Name).
* Allows exactly one colon as a prefix separator: prefix:localName.
* Used for: element and attribute names in namespace-aware XML/SVG.
*
* @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]
*   asciiOnly: skip unicode-aware matching, ASCII names only (default false).
*/
var qName = (str, { xmlVersion = "1.0", asciiOnly = false } = {}) => getRegexes(xmlVersion, asciiOnly).qName.test(str);
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js
var DocTypeReader = class {
	constructor(options, xmlVersion) {
		this.suppressValidationErr = !options;
		this.options = options;
		this.xmlVersion = xmlVersion || 1;
	}
	setXmlVersion(xmlVersion = 1) {
		this.xmlVersion = xmlVersion;
	}
	readDocType(xmlData, i) {
		const entities = Object.create(null);
		let entityCount = 0;
		if (xmlData[i + 3] === "O" && xmlData[i + 4] === "C" && xmlData[i + 5] === "T" && xmlData[i + 6] === "Y" && xmlData[i + 7] === "P" && xmlData[i + 8] === "E") {
			i = i + 9;
			let angleBracketsCount = 1;
			let hasBody = false, comment = false;
			let exp = "";
			for (; i < xmlData.length; i++) if (xmlData[i] === "<" && !comment) {
				if (hasBody && hasSeq(xmlData, "!ENTITY", i)) {
					i += 7;
					let entityName, val;
					[entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);
					if (val.indexOf("&") === -1) {
						if (this.options.enabled !== false && this.options.maxEntityCount != null && entityCount >= this.options.maxEntityCount) throw new Error(`Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`);
						entities[entityName] = val;
						entityCount++;
					}
				} else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) {
					i += 8;
					const { index } = this.readElementExp(xmlData, i + 1);
					i = index;
				} else if (hasBody && hasSeq(xmlData, "!ATTLIST", i)) i += 8;
				else if (hasBody && hasSeq(xmlData, "!NOTATION", i)) {
					i += 9;
					const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);
					i = index;
				} else if (hasSeq(xmlData, "!--", i)) comment = true;
				else throw new Error(`Invalid DOCTYPE`);
				angleBracketsCount++;
				exp = "";
			} else if (xmlData[i] === ">") {
				if (comment) {
					if (xmlData[i - 1] === "-" && xmlData[i - 2] === "-") {
						comment = false;
						angleBracketsCount--;
					}
				} else angleBracketsCount--;
				if (angleBracketsCount === 0) break;
			} else if (xmlData[i] === "[") hasBody = true;
			else exp += xmlData[i];
			if (angleBracketsCount !== 0) throw new Error(`Unclosed DOCTYPE`);
		} else throw new Error(`Invalid Tag instead of DOCTYPE`);
		return {
			entities,
			i
		};
	}
	readEntityExp(xmlData, i) {
		i = skipWhitespace(xmlData, i);
		const startIndex = i;
		while (i < xmlData.length && !/\s/.test(xmlData[i]) && xmlData[i] !== "\"" && xmlData[i] !== "'") i++;
		let entityName = xmlData.substring(startIndex, i);
		validateEntityName(entityName, { xmlVersion: this.xmlVersion });
		i = skipWhitespace(xmlData, i);
		if (!this.suppressValidationErr) {
			if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") throw new Error("External entities are not supported");
			else if (xmlData[i] === "%") throw new Error("Parameter entities are not supported");
		}
		let entityValue = "";
		[i, entityValue] = this.readIdentifierVal(xmlData, i, "entity");
		if (this.options.enabled !== false && this.options.maxEntitySize != null && entityValue.length > this.options.maxEntitySize) throw new Error(`Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);
		i--;
		return [
			entityName,
			entityValue,
			i
		];
	}
	readNotationExp(xmlData, i) {
		i = skipWhitespace(xmlData, i);
		const startIndex = i;
		while (i < xmlData.length && !/\s/.test(xmlData[i])) i++;
		let notationName = xmlData.substring(startIndex, i);
		!this.suppressValidationErr && validateEntityName(notationName, { xmlVersion: this.xmlVersion });
		i = skipWhitespace(xmlData, i);
		const identifierType = xmlData.substring(i, i + 6).toUpperCase();
		if (!this.suppressValidationErr && identifierType !== "SYSTEM" && identifierType !== "PUBLIC") throw new Error(`Expected SYSTEM or PUBLIC, found "${identifierType}"`);
		i += identifierType.length;
		i = skipWhitespace(xmlData, i);
		let publicIdentifier = null;
		let systemIdentifier = null;
		if (identifierType === "PUBLIC") {
			[i, publicIdentifier] = this.readIdentifierVal(xmlData, i, "publicIdentifier");
			i = skipWhitespace(xmlData, i);
			if (xmlData[i] === "\"" || xmlData[i] === "'") [i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
		} else if (identifierType === "SYSTEM") {
			[i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
			if (!this.suppressValidationErr && !systemIdentifier) throw new Error("Missing mandatory system identifier for SYSTEM notation");
		}
		return {
			notationName,
			publicIdentifier,
			systemIdentifier,
			index: --i
		};
	}
	readIdentifierVal(xmlData, i, type) {
		let identifierVal = "";
		const startChar = xmlData[i];
		if (startChar !== "\"" && startChar !== "'") throw new Error(`Expected quoted string, found "${startChar}"`);
		i++;
		const startIndex = i;
		while (i < xmlData.length && xmlData[i] !== startChar) i++;
		identifierVal = xmlData.substring(startIndex, i);
		if (xmlData[i] !== startChar) throw new Error(`Unterminated ${type} value`);
		i++;
		return [i, identifierVal];
	}
	readElementExp(xmlData, i) {
		i = skipWhitespace(xmlData, i);
		const startIndex = i;
		while (i < xmlData.length && !/\s/.test(xmlData[i])) i++;
		let elementName = xmlData.substring(startIndex, i);
		if (!this.suppressValidationErr && !qName(elementName, { xmlVersion: this.xmlVersion })) throw new Error(`Invalid element name: "${elementName}"`);
		i = skipWhitespace(xmlData, i);
		let contentModel = "";
		if (xmlData[i] === "E" && hasSeq(xmlData, "MPTY", i)) i += 4;
		else if (xmlData[i] === "A" && hasSeq(xmlData, "NY", i)) i += 2;
		else if (xmlData[i] === "(") {
			i++;
			const startIndex = i;
			while (i < xmlData.length && xmlData[i] !== ")") i++;
			contentModel = xmlData.substring(startIndex, i);
			if (xmlData[i] !== ")") throw new Error("Unterminated content model");
		} else if (!this.suppressValidationErr) throw new Error(`Invalid Element Expression, found "${xmlData[i]}"`);
		return {
			elementName,
			contentModel: contentModel.trim(),
			index: i
		};
	}
	readAttlistExp(xmlData, i) {
		i = skipWhitespace(xmlData, i);
		let startIndex = i;
		while (i < xmlData.length && !/\s/.test(xmlData[i])) i++;
		let elementName = xmlData.substring(startIndex, i);
		validateEntityName(elementName, { xmlVersion: this.xmlVersion });
		i = skipWhitespace(xmlData, i);
		startIndex = i;
		while (i < xmlData.length && !/\s/.test(xmlData[i])) i++;
		let attributeName = xmlData.substring(startIndex, i);
		if (!validateEntityName(attributeName, { xmlVersion: this.xmlVersion })) throw new Error(`Invalid attribute name: "${attributeName}"`);
		i = skipWhitespace(xmlData, i);
		let attributeType = "";
		if (xmlData.substring(i, i + 8).toUpperCase() === "NOTATION") {
			attributeType = "NOTATION";
			i += 8;
			i = skipWhitespace(xmlData, i);
			if (xmlData[i] !== "(") throw new Error(`Expected '(', found "${xmlData[i]}"`);
			i++;
			let allowedNotations = [];
			while (i < xmlData.length && xmlData[i] !== ")") {
				const startIndex = i;
				while (i < xmlData.length && xmlData[i] !== "|" && xmlData[i] !== ")") i++;
				let notation = xmlData.substring(startIndex, i);
				notation = notation.trim();
				if (!validateEntityName(notation, { xmlVersion: this.xmlVersion })) throw new Error(`Invalid notation name: "${notation}"`);
				allowedNotations.push(notation);
				if (xmlData[i] === "|") {
					i++;
					i = skipWhitespace(xmlData, i);
				}
			}
			if (xmlData[i] !== ")") throw new Error("Unterminated list of notations");
			i++;
			attributeType += " (" + allowedNotations.join("|") + ")";
		} else {
			const startIndex = i;
			while (i < xmlData.length && !/\s/.test(xmlData[i])) i++;
			attributeType += xmlData.substring(startIndex, i);
			if (!this.suppressValidationErr && ![
				"CDATA",
				"ID",
				"IDREF",
				"IDREFS",
				"ENTITY",
				"ENTITIES",
				"NMTOKEN",
				"NMTOKENS"
			].includes(attributeType.toUpperCase())) throw new Error(`Invalid attribute type: "${attributeType}"`);
		}
		i = skipWhitespace(xmlData, i);
		let defaultValue = "";
		if (xmlData.substring(i, i + 8).toUpperCase() === "#REQUIRED") {
			defaultValue = "#REQUIRED";
			i += 8;
		} else if (xmlData.substring(i, i + 7).toUpperCase() === "#IMPLIED") {
			defaultValue = "#IMPLIED";
			i += 7;
		} else [i, defaultValue] = this.readIdentifierVal(xmlData, i, "ATTLIST");
		return {
			elementName,
			attributeName,
			attributeType,
			defaultValue,
			index: i
		};
	}
};
var skipWhitespace = (data, index) => {
	while (index < data.length && /\s/.test(data[index])) index++;
	return index;
};
function hasSeq(data, seq, i) {
	for (let j = 0; j < seq.length; j++) if (seq[j] !== data[i + j + 1]) return false;
	return true;
}
function validateEntityName(name, xmlVersion) {
	if (qName(name, { xmlVersion })) return name;
	else throw new Error(`Invalid entity name ${name}`);
}
//#endregion
//#region node_modules/anynum/digitTable.js
/**
* Flat lookup table: maps Unicode code point → ASCII digit (0-9).
* Only decimal digit characters (Unicode category Nd) are included.
*
* Strategy: Int32Array of size (maxCodePoint - minCodePoint + 1).
* Value 0xFF means "not a digit". Value 0-9 is the ASCII digit value.
* This gives O(1) lookup with no branching, no bisect, no loop.
*
* Memory: range is 0x0660 to 0x1FBF0 → ~129,936 entries × 1 byte = ~127 KB.
* Acceptable for a one-time init; lookup is a single array index.
*/
var SCRIPT_ZEROS = [
	48,
	1632,
	1776,
	2406,
	2534,
	2662,
	2790,
	2918,
	3046,
	3174,
	3302,
	3430,
	3558,
	3664,
	3792,
	3872,
	4160,
	4240,
	6112,
	6160,
	6470,
	6608,
	6784,
	6800,
	6992,
	7088,
	7232,
	7248,
	65296,
	120782,
	120792,
	120802,
	120812,
	120822,
	66720,
	68912,
	69734,
	69872,
	69942,
	70096,
	70384,
	70736,
	70864,
	71248,
	71360,
	71472,
	71904,
	72016,
	72688,
	72784,
	73040,
	73120,
	73552,
	92768,
	92864,
	93008,
	123200,
	123632,
	124144,
	125264,
	130032
];
var HIGH_MAP = /* @__PURE__ */ new Map();
var LOW_MAX = 65535;
var TABLE_OFFSET = 1632;
var TABLE = (/* @__PURE__ */ new Uint8Array(63904)).fill(255);
for (const zero of SCRIPT_ZEROS) for (let d = 0; d < 10; d++) {
	const cp = zero + d;
	if (cp <= LOW_MAX) TABLE[cp - TABLE_OFFSET] = d;
	else HIGH_MAP.set(cp, d);
}
//#endregion
//#region node_modules/anynum/anynum.js
var CHAR_0 = 48;
var CHAR_9 = 57;
var CHAR_MINUS = 45;
var MINUS_SET = /* @__PURE__ */ new Set([
	8722,
	65293,
	65123
]);
/**
* Normalize all Unicode decimal digit characters in a string to ASCII (0-9),
* and normalize Unicode minus variants to ASCII '-' (U+002D).
*
* Non-digit, non-minus characters are passed through unchanged.
*
* Performance design:
* - Fast path: if the string has no convertible characters, return it unchanged
*   (zero allocation).
* - BMP digits (0x0660..0xFFFF excl. surrogates): flat Uint8Array lookup (O(1)).
* - Supplementary plane digits (> 0xFFFF, encoded as surrogate pairs): Map lookup.
* - Minus variants: checked inline with a small fixed Set.
*
* @param {string} str
* @returns {string}
*/
function anynum(str) {
	if (typeof str !== "string") return str;
	const len = str.length;
	if (len === 0) return str;
	let firstHit = -1;
	for (let i = 0; i < len; i++) {
		const cc = str.charCodeAt(i);
		if (cc >= CHAR_0 && cc <= CHAR_9 || cc === CHAR_MINUS) continue;
		if (cc < 1632) {
			if (MINUS_SET.has(cc)) {
				firstHit = i;
				break;
			}
			continue;
		}
		if (cc >= 55296 && cc <= 56319) {
			if (i + 1 < len) {
				const low = str.charCodeAt(i + 1);
				if (low >= 56320 && low <= 57343) {
					const cp = 65536 + (cc - 55296 << 10) + (low - 56320);
					if (HIGH_MAP.has(cp)) {
						firstHit = i;
						break;
					}
				}
			}
			continue;
		}
		if (TABLE[cc - 1632] !== 255 || MINUS_SET.has(cc)) {
			firstHit = i;
			break;
		}
	}
	if (firstHit === -1) return str;
	const chars = [];
	if (firstHit > 0) chars.push(str.slice(0, firstHit));
	for (let i = firstHit; i < len; i++) {
		const cc = str.charCodeAt(i);
		if (cc >= CHAR_0 && cc <= CHAR_9 || cc === CHAR_MINUS) {
			chars.push(str[i]);
			continue;
		}
		if (cc < 1632) {
			chars.push(MINUS_SET.has(cc) ? "-" : str[i]);
			continue;
		}
		if (cc >= 55296 && cc <= 56319) {
			if (i + 1 < len) {
				const low = str.charCodeAt(i + 1);
				if (low >= 56320 && low <= 57343) {
					const cp = 65536 + (cc - 55296 << 10) + (low - 56320);
					const d = HIGH_MAP.get(cp);
					if (d !== void 0) {
						chars.push(String.fromCharCode(d + 48));
						i++;
						continue;
					}
				}
			}
			chars.push(str[i]);
			continue;
		}
		if (MINUS_SET.has(cc)) {
			chars.push("-");
			continue;
		}
		const d = TABLE[cc - TABLE_OFFSET];
		chars.push(d !== 255 ? String.fromCharCode(d + 48) : str[i]);
	}
	return chars.join("");
}
//#endregion
//#region node_modules/strnum/strnum.js
var hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
var binRegex = /^0b[01]+$/;
var octRegex = /^0o[0-7]+$/;
var numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
var consider = {
	hex: true,
	binary: false,
	octal: false,
	leadingZeros: true,
	decimalPoint: ".",
	eNotation: true,
	infinity: "original",
	unicode: false
};
function toNumber(str, options = {}) {
	options = Object.assign({}, consider, options);
	if (!str || typeof str !== "string") return str;
	let trimmedStr = str.trim();
	if (trimmedStr.length === 0) return str;
	else if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr)) return str;
	else if (trimmedStr === "0") return 0;
	if (options.unicode) {
		trimmedStr = anynum(trimmedStr);
		if (trimmedStr === "0") return 0;
	}
	if (options.hex && hexRegex.test(trimmedStr)) return parse_int(trimmedStr, 16);
	else if (options.binary && binRegex.test(trimmedStr)) return parse_int(trimmedStr, 2);
	else if (options.octal && octRegex.test(trimmedStr)) return parse_int(trimmedStr, 8);
	else if (!isFinite(trimmedStr)) return handleInfinity(str, Number(trimmedStr), options);
	else if (trimmedStr.includes("e") || trimmedStr.includes("E")) return resolveEnotation(str, trimmedStr, options);
	else {
		const match = numRegex.exec(trimmedStr);
		if (match) {
			const sign = match[1] || "";
			const leadingZeros = match[2];
			let numTrimmedByZeros = trimZeros(match[3]);
			const decimalAdjacentToLeadingZeros = sign ? str[leadingZeros.length + 1] === "." : str[leadingZeros.length] === ".";
			if (!options.leadingZeros && (leadingZeros.length > 1 || leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros)) return str;
			else {
				const num = Number(trimmedStr);
				const parsedStr = String(num);
				if (num === 0) return num;
				if (parsedStr.search(/[eE]/) !== -1) if (options.eNotation) return num;
				else return str;
				else if (trimmedStr.indexOf(".") !== -1) if (parsedStr === "0") return num;
				else if (parsedStr === numTrimmedByZeros) return num;
				else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;
				else return str;
				let n = leadingZeros ? numTrimmedByZeros : trimmedStr;
				if (leadingZeros) return n === parsedStr || sign + n === parsedStr ? num : str;
				else return n === parsedStr || n === sign + parsedStr ? num : str;
			}
		} else return str;
	}
}
var eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
function resolveEnotation(str, trimmedStr, options) {
	if (!options.eNotation) return str;
	const notation = trimmedStr.match(eNotationRegx);
	if (notation) {
		let sign = notation[1] || "";
		const eChar = notation[3].indexOf("e") === -1 ? "E" : "e";
		const leadingZeros = notation[2];
		const eAdjacentToLeadingZeros = sign ? str[leadingZeros.length + 1] === eChar : str[leadingZeros.length] === eChar;
		if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
		else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) return Number(trimmedStr);
		else if (leadingZeros.length > 0) if (options.leadingZeros && !eAdjacentToLeadingZeros) {
			trimmedStr = (notation[1] || "") + notation[3];
			return Number(trimmedStr);
		} else return str;
		else return Number(trimmedStr);
	} else return str;
}
/**
* 
* @param {string} numStr without leading zeros
* @returns 
*/
function trimZeros(numStr) {
	if (numStr && numStr.indexOf(".") !== -1) {
		numStr = numStr.replace(/0+$/, "");
		if (numStr === ".") numStr = "0";
		else if (numStr[0] === ".") numStr = "0" + numStr;
		else if (numStr[numStr.length - 1] === ".") numStr = numStr.substring(0, numStr.length - 1);
		return numStr;
	}
	return numStr;
}
function parse_int(numStr, base) {
	const str = numStr.trim();
	if (base === 2 || base === 8) numStr = str.substring(2);
	if (parseInt) return parseInt(numStr, base);
	else if (Number.parseInt) return Number.parseInt(numStr, base);
	else if (window && window.parseInt) return window.parseInt(numStr, base);
	else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
}
/**
* Handle infinite values based on user option
* @param {string} str - original input string
* @param {number} num - parsed number (Infinity or -Infinity)
* @param {object} options - user options
* @returns {string|number|null} based on infinity option
*/
function handleInfinity(str, num, options) {
	const isPositive = num === Infinity;
	switch (options.infinity.toLowerCase()) {
		case "null": return null;
		case "infinity": return num;
		case "string": return isPositive ? "Infinity" : "-Infinity";
		default: return str;
	}
}
//#endregion
//#region node_modules/fast-xml-parser/src/ignoreAttributes.js
function getIgnoreAttributesFn(ignoreAttributes) {
	if (typeof ignoreAttributes === "function") return ignoreAttributes;
	if (Array.isArray(ignoreAttributes)) return (attrName) => {
		for (const pattern of ignoreAttributes) {
			if (typeof pattern === "string" && attrName === pattern) return true;
			if (pattern instanceof RegExp && pattern.test(attrName)) return true;
		}
	};
	return () => false;
}
//#endregion
//#region node_modules/path-expression-matcher/src/Expression.js
/**
* Expression - Parses and stores a tag pattern expression
* 
* Patterns are parsed once and stored in an optimized structure for fast matching.
* 
* @example
* const expr = new Expression("root.users.user");
* const expr2 = new Expression("..user[id]:first");
* const expr3 = new Expression("root/users/user", { separator: '/' });
*/
var Expression = class {
	/**
	* Create a new Expression
	* @param {string} pattern - Pattern string (e.g., "root.users.user", "..user[id]")
	* @param {Object} options - Configuration options
	* @param {string} options.separator - Path separator (default: '.')
	*/
	constructor(pattern, options = {}, data) {
		this.pattern = pattern;
		this.separator = options.separator || ".";
		this.segments = this._parse(pattern);
		this.data = data;
		this._hasDeepWildcard = this.segments.some((seg) => seg.type === "deep-wildcard");
		this._hasAttributeCondition = this.segments.some((seg) => seg.attrName !== void 0);
		this._hasPositionSelector = this.segments.some((seg) => seg.position !== void 0);
	}
	/**
	* Parse pattern string into segments
	* @private
	* @param {string} pattern - Pattern to parse
	* @returns {Array} Array of segment objects
	*/
	_parse(pattern) {
		const segments = [];
		let i = 0;
		let currentPart = "";
		while (i < pattern.length) if (pattern[i] === this.separator) if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {
			if (currentPart.trim()) {
				segments.push(this._parseSegment(currentPart.trim()));
				currentPart = "";
			}
			segments.push({ type: "deep-wildcard" });
			i += 2;
		} else {
			if (currentPart.trim()) segments.push(this._parseSegment(currentPart.trim()));
			currentPart = "";
			i++;
		}
		else {
			currentPart += pattern[i];
			i++;
		}
		if (currentPart.trim()) segments.push(this._parseSegment(currentPart.trim()));
		return segments;
	}
	/**
	* Parse a single segment
	* @private
	* @param {string} part - Segment string (e.g., "user", "ns::user", "user[id]", "ns::user:first")
	* @returns {Object} Segment object
	*/
	_parseSegment(part) {
		const segment = { type: "tag" };
		let bracketContent = null;
		let withoutBrackets = part;
		const bracketMatch = part.match(/^([^\[]+)(\[[^\]]*\])(.*)$/);
		if (bracketMatch) {
			withoutBrackets = bracketMatch[1] + bracketMatch[3];
			if (bracketMatch[2]) {
				const content = bracketMatch[2].slice(1, -1);
				if (content) bracketContent = content;
			}
		}
		let namespace = void 0;
		let tagAndPosition = withoutBrackets;
		if (withoutBrackets.includes("::")) {
			const nsIndex = withoutBrackets.indexOf("::");
			namespace = withoutBrackets.substring(0, nsIndex).trim();
			tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim();
			if (!namespace) throw new Error(`Invalid namespace in pattern: ${part}`);
		}
		let tag = void 0;
		let positionMatch = null;
		if (tagAndPosition.includes(":")) {
			const colonIndex = tagAndPosition.lastIndexOf(":");
			const tagPart = tagAndPosition.substring(0, colonIndex).trim();
			const posPart = tagAndPosition.substring(colonIndex + 1).trim();
			if ([
				"first",
				"last",
				"odd",
				"even"
			].includes(posPart) || /^nth\(\d+\)$/.test(posPart)) {
				tag = tagPart;
				positionMatch = posPart;
			} else tag = tagAndPosition;
		} else tag = tagAndPosition;
		if (!tag) throw new Error(`Invalid segment pattern: ${part}`);
		segment.tag = tag;
		if (namespace) segment.namespace = namespace;
		if (bracketContent) if (bracketContent.includes("=")) {
			const eqIndex = bracketContent.indexOf("=");
			segment.attrName = bracketContent.substring(0, eqIndex).trim();
			segment.attrValue = bracketContent.substring(eqIndex + 1).trim();
		} else segment.attrName = bracketContent.trim();
		if (positionMatch) {
			const nthMatch = positionMatch.match(/^nth\((\d+)\)$/);
			if (nthMatch) {
				segment.position = "nth";
				segment.positionValue = parseInt(nthMatch[1], 10);
			} else segment.position = positionMatch;
		}
		return segment;
	}
	/**
	* Get the number of segments
	* @returns {number}
	*/
	get length() {
		return this.segments.length;
	}
	/**
	* Check if expression contains deep wildcard
	* @returns {boolean}
	*/
	hasDeepWildcard() {
		return this._hasDeepWildcard;
	}
	/**
	* Check if expression has attribute conditions
	* @returns {boolean}
	*/
	hasAttributeCondition() {
		return this._hasAttributeCondition;
	}
	/**
	* Check if expression has position selectors
	* @returns {boolean}
	*/
	hasPositionSelector() {
		return this._hasPositionSelector;
	}
	/**
	* Get string representation
	* @returns {string}
	*/
	toString() {
		return this.pattern;
	}
};
//#endregion
//#region node_modules/path-expression-matcher/src/ExpressionSet.js
/**
* ExpressionSet - An indexed collection of Expressions for efficient bulk matching
*
* Instead of iterating all expressions on every tag, ExpressionSet pre-indexes
* them at insertion time by depth and terminal tag name. At match time, only
* the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)
* lookup plus O(small bucket) matches.
*
* Three buckets are maintained:
*  - `_byDepthAndTag`  — exact depth + exact tag name  (tightest, used first)
*  - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)
*  - `_deepWildcards`  — expressions containing `..`  (cannot be depth-indexed)
*
* @example
* import { Expression, ExpressionSet } from 'fast-xml-tagger';
*
* // Build once at config time
* const stopNodes = new ExpressionSet();
* stopNodes.add(new Expression('root.users.user'));
* stopNodes.add(new Expression('root.config.setting'));
* stopNodes.add(new Expression('..script'));
*
* // Query on every tag — hot path
* if (stopNodes.matchesAny(matcher)) { ... }
*/
var ExpressionSet = class {
	constructor() {
		/** @type {Map<string, import('./Expression.js').default[]>} depth:tag → expressions */
		this._byDepthAndTag = /* @__PURE__ */ new Map();
		/** @type {Map<number, import('./Expression.js').default[]>} depth → wildcard-tag expressions */
		this._wildcardByDepth = /* @__PURE__ */ new Map();
		/** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */
		this._deepWildcards = [];
		/** @type {Map<string, import('./Expression.js').default[]>} terminalTag → deep wildcard expressions */
		this._deepByTerminalTag = /* @__PURE__ */ new Map();
		/** @type {Set<string>} pattern strings already added — used for deduplication */
		this._patterns = /* @__PURE__ */ new Set();
		/** @type {boolean} whether the set is sealed against further additions */
		this._sealed = false;
	}
	/**
	* Add an Expression to the set.
	* Duplicate patterns (same pattern string) are silently ignored.
	*
	* @param {import('./Expression.js').default} expression - A pre-constructed Expression instance
	* @returns {this} for chaining
	* @throws {TypeError} if called after seal()
	*
	* @example
	* set.add(new Expression('root.users.user'));
	* set.add(new Expression('..script'));
	*/
	add(expression) {
		if (this._sealed) throw new TypeError("ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.");
		if (this._patterns.has(expression.pattern)) return this;
		this._patterns.add(expression.pattern);
		if (expression.hasDeepWildcard()) {
			const lastSeg = expression.segments[expression.segments.length - 1];
			if (lastSeg && lastSeg.type !== "deep-wildcard" && lastSeg.tag !== "*") {
				const tag = lastSeg.tag;
				if (!this._deepByTerminalTag.has(tag)) this._deepByTerminalTag.set(tag, []);
				this._deepByTerminalTag.get(tag).push(expression);
			} else this._deepWildcards.push(expression);
			return this;
		}
		const depth = expression.length;
		const tag = expression.segments[expression.segments.length - 1]?.tag;
		if (!tag || tag === "*") {
			if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);
			this._wildcardByDepth.get(depth).push(expression);
		} else {
			const key = `${depth}:${tag}`;
			if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);
			this._byDepthAndTag.get(key).push(expression);
		}
		return this;
	}
	/**
	* Add multiple expressions at once.
	*
	* @param {import('./Expression.js').default[]} expressions - Array of Expression instances
	* @returns {this} for chaining
	*
	* @example
	* set.addAll([
	*   new Expression('root.users.user'),
	*   new Expression('root.config.setting'),
	* ]);
	*/
	addAll(expressions) {
		for (const expr of expressions) this.add(expr);
		return this;
	}
	/**
	* Check whether a pattern string is already present in the set.
	*
	* @param {import('./Expression.js').default} expression
	* @returns {boolean}
	*/
	has(expression) {
		return this._patterns.has(expression.pattern);
	}
	/**
	* Number of expressions in the set.
	* @type {number}
	*/
	get size() {
		return this._patterns.size;
	}
	/**
	* Seal the set against further modifications.
	* Useful to prevent accidental mutations after config is built.
	* Calling add() or addAll() on a sealed set throws a TypeError.
	*
	* @returns {this}
	*/
	seal() {
		this._sealed = true;
		return this;
	}
	/**
	* Whether the set has been sealed.
	* @type {boolean}
	*/
	get isSealed() {
		return this._sealed;
	}
	/**
	* Test whether the matcher's current path matches any expression in the set.
	*
	* Evaluation order (cheapest → most expensive):
	*  1. Exact depth + tag bucket  — O(1) lookup, typically 0–2 expressions
	*  2. Depth-only wildcard bucket — O(1) lookup, rare
	*  3. Deep-wildcard list         — always checked, but usually small
	*
	* @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
	* @returns {boolean} true if any expression matches the current path
	*
	* @example
	* if (stopNodes.matchesAny(matcher)) {
	*   // handle stop node
	* }
	*/
	matchesAny(matcher) {
		return this.findMatch(matcher) !== null;
	}
	/**
	* Find and return the first Expression that matches the matcher's current path.
	*
	* Uses the same evaluation order as matchesAny (cheapest → most expensive):
	*  1. Exact depth + tag bucket
	*  2. Depth-only wildcard bucket
	*  3. Deep-wildcard list
	*
	* @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
	* @returns {import('./Expression.js').default | null} the first matching Expression, or null
	*
	* @example
	* const expr = stopNodes.findMatch(matcher);
	* if (expr) {
	*   // access expr.config, expr.pattern, etc.
	* }
	*/
	findMatch(matcher) {
		const depth = matcher.getDepth();
		const tag = matcher.getCurrentTag();
		const exactKey = `${depth}:${tag}`;
		const exactBucket = this._byDepthAndTag.get(exactKey);
		if (exactBucket) {
			for (let i = 0; i < exactBucket.length; i++) if (matcher.matches(exactBucket[i])) return exactBucket[i];
		}
		const wildcardBucket = this._wildcardByDepth.get(depth);
		if (wildcardBucket) {
			for (let i = 0; i < wildcardBucket.length; i++) if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];
		}
		const deepBucket = this._deepByTerminalTag.get(tag);
		if (deepBucket) {
			for (let i = 0; i < deepBucket.length; i++) if (matcher.matches(deepBucket[i])) return deepBucket[i];
		}
		for (let i = 0; i < this._deepWildcards.length; i++) if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];
		return null;
	}
};
//#endregion
//#region node_modules/path-expression-matcher/src/Matcher.js
/**
* MatcherView - A lightweight read-only view over a Matcher's internal state.
*
* Created once by Matcher and reused across all callbacks. Holds a direct
* reference to the parent Matcher so it always reflects current parser state
* with zero copying or freezing overhead.
*
* Users receive this via {@link Matcher#readOnly} or directly from parser
* callbacks. It exposes all query and matching methods but has no mutation
* methods — misuse is caught at the TypeScript level rather than at runtime.
*
* @example
* const matcher = new Matcher();
* const view = matcher.readOnly();
*
* matcher.push("root", {});
* view.getCurrentTag(); // "root"
* view.getDepth();      // 1
*/
var MatcherView = class {
	/**
	* @param {Matcher} matcher - The parent Matcher instance to read from.
	*/
	constructor(matcher) {
		this._matcher = matcher;
	}
	/**
	* Get the path separator used by the parent matcher.
	* @returns {string}
	*/
	get separator() {
		return this._matcher.separator;
	}
	/**
	* Get current tag name.
	* @returns {string|undefined}
	*/
	getCurrentTag() {
		const path = this._matcher.path;
		return path.length > 0 ? path[path.length - 1].tag : void 0;
	}
	/**
	* Get current namespace.
	* @returns {string|undefined}
	*/
	getCurrentNamespace() {
		const path = this._matcher.path;
		return path.length > 0 ? path[path.length - 1].namespace : void 0;
	}
	/**
	* Get current node's attribute value.
	* @param {string} attrName
	* @returns {*}
	*/
	getAttrValue(attrName) {
		const path = this._matcher.path;
		if (path.length === 0) return void 0;
		return path[path.length - 1].values?.[attrName];
	}
	/**
	* Check if current node has an attribute.
	* @param {string} attrName
	* @returns {boolean}
	*/
	hasAttr(attrName) {
		const path = this._matcher.path;
		if (path.length === 0) return false;
		const current = path[path.length - 1];
		return current.values !== void 0 && attrName in current.values;
	}
	/**
	* Get the value of a "kept" attribute from the nearest ancestor (or
	* current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.
	* @param {string} attrName
	* @returns {*}
	*/
	getAnyParentAttr(attrName) {
		return this._matcher.getAnyParentAttr(attrName);
	}
	/**
	* Check whether any ancestor (or the current node) kept the given
	* attribute via `push(tag, attrs, ns, { keep: [...] })`.
	* @param {string} attrName
	* @returns {boolean}
	*/
	hasAnyParentAttr(attrName) {
		return this._matcher.hasAnyParentAttr(attrName);
	}
	/**
	* Get current node's sibling position (child index in parent).
	* @returns {number}
	*/
	getPosition() {
		const path = this._matcher.path;
		if (path.length === 0) return -1;
		return path[path.length - 1].position ?? 0;
	}
	/**
	* Get current node's repeat counter (occurrence count of this tag name).
	* @returns {number}
	*/
	getCounter() {
		const path = this._matcher.path;
		if (path.length === 0) return -1;
		return path[path.length - 1].counter ?? 0;
	}
	/**
	* Get current node's sibling index (alias for getPosition).
	* @returns {number}
	* @deprecated Use getPosition() or getCounter() instead
	*/
	getIndex() {
		return this.getPosition();
	}
	/**
	* Get current path depth.
	* @returns {number}
	*/
	getDepth() {
		return this._matcher.path.length;
	}
	/**
	* Get path as string.
	* @param {string} [separator] - Optional separator (uses default if not provided)
	* @param {boolean} [includeNamespace=true]
	* @returns {string}
	*/
	toString(separator, includeNamespace = true) {
		return this._matcher.toString(separator, includeNamespace);
	}
	/**
	* Get path as array of tag names.
	* @returns {string[]}
	*/
	toArray() {
		return this._matcher.path.map((n) => n.tag);
	}
	/**
	* Match current path against an Expression.
	* @param {Expression} expression
	* @returns {boolean}
	*/
	matches(expression) {
		return this._matcher.matches(expression);
	}
	/**
	* Match any expression in the given set against the current path.
	* @param {ExpressionSet} exprSet
	* @returns {boolean}
	*/
	matchesAny(exprSet) {
		return exprSet.matchesAny(this._matcher);
	}
};
/**
* Matcher - Tracks current path in XML/JSON tree and matches against Expressions.
*
* The matcher maintains a stack of nodes representing the current path from root to
* current tag. It only stores attribute values for the current (top) node to minimize
* memory usage. Sibling tracking is used to auto-calculate position and counter.
*
* Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to
* user callbacks — it always reflects current state with no Proxy overhead.
*
* @example
* const matcher = new Matcher();
* matcher.push("root", {});
* matcher.push("users", {});
* matcher.push("user", { id: "123", type: "admin" });
*
* const expr = new Expression("root.users.user");
* matcher.matches(expr); // true
*/
var Matcher = class {
	/**
	* Create a new Matcher.
	* @param {Object} [options={}]
	* @param {string} [options.separator='.'] - Default path separator
	*/
	constructor(options = {}) {
		this.separator = options.separator || ".";
		this.path = [];
		this.siblingStacks = [];
		this._pathStringCache = null;
		this._view = new MatcherView(this);
		this._keptAttrs = [];
	}
	/**
	* Push a new tag onto the path.
	* @param {string} tagName
	* @param {Object|null} [attrValues=null]
	* @param {string|null} [namespace=null]
	* @param {Object|null} [options=null]
	* @param {string[]} [options.keep] - Names of attributes (from attrValues)
	*/
	push(tagName, attrValues = null, namespace = null, options = null) {
		this._pathStringCache = null;
		if (this.path.length > 0) this.path[this.path.length - 1].values = void 0;
		const currentLevel = this.path.length;
		let level = this.siblingStacks[currentLevel];
		if (!level) {
			level = {
				counts: /* @__PURE__ */ new Map(),
				total: 0
			};
			this.siblingStacks[currentLevel] = level;
		}
		const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;
		const counter = level.counts.get(siblingKey) || 0;
		const position = level.total;
		level.counts.set(siblingKey, counter + 1);
		level.total++;
		const node = {
			tag: tagName,
			position,
			counter
		};
		if (namespace !== null && namespace !== void 0) node.namespace = namespace;
		if (attrValues !== null && attrValues !== void 0) node.values = attrValues;
		this.path.push(node);
		const depth = this.path.length;
		const keep = options !== null ? options.keep : null;
		if (keep !== null && keep !== void 0 && keep.length > 0 && attrValues) for (let i = 0; i < keep.length; i++) {
			const name = keep[i];
			if (attrValues[name] !== void 0) this._keptAttrs.push({
				depth,
				name,
				value: attrValues[name]
			});
		}
	}
	/**
	* Pop the last tag from the path.
	* @returns {Object|undefined} The popped node
	*/
	pop() {
		if (this.path.length === 0) return void 0;
		this._pathStringCache = null;
		const node = this.path.pop();
		if (this.siblingStacks.length > this.path.length + 1) this.siblingStacks.length = this.path.length + 1;
		const poppedDepth = this.path.length + 1;
		while (this._keptAttrs.length > 0 && this._keptAttrs[this._keptAttrs.length - 1].depth >= poppedDepth) this._keptAttrs.pop();
		return node;
	}
	/**
	* Update current node's attribute values.
	* Useful when attributes are parsed after push.
	* @param {Object} attrValues
	*/
	updateCurrent(attrValues) {
		if (this.path.length > 0) {
			const current = this.path[this.path.length - 1];
			if (attrValues !== null && attrValues !== void 0) current.values = attrValues;
		}
	}
	/**
	* Get current tag name.
	* @returns {string|undefined}
	*/
	getCurrentTag() {
		return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0;
	}
	/**
	* Get current namespace.
	* @returns {string|undefined}
	*/
	getCurrentNamespace() {
		return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0;
	}
	/**
	* Get current node's attribute value.
	* @param {string} attrName
	* @returns {*}
	*/
	getAttrValue(attrName) {
		if (this.path.length === 0) return void 0;
		return this.path[this.path.length - 1].values?.[attrName];
	}
	/**
	* Check if current node has an attribute.
	* @param {string} attrName
	* @returns {boolean}
	*/
	hasAttr(attrName) {
		if (this.path.length === 0) return false;
		const current = this.path[this.path.length - 1];
		return current.values !== void 0 && attrName in current.values;
	}
	/**
	* Get the value of a "kept" attribute from the nearest ancestor (or
	* current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.
	* Unlike getAttrValue(), this works regardless of how deep the path has
	* gone since the attribute was pushed — but only for attribute names that
	* were explicitly marked with `keep` at push time. Cost is proportional to
	* the number of currently-kept attributes (typically 0-3), not path depth.
	* @param {string} attrName
	* @returns {*} the value, or undefined if no ancestor kept this attribute
	*/
	getAnyParentAttr(attrName) {
		const kept = this._keptAttrs;
		for (let i = kept.length - 1; i >= 0; i--) if (kept[i].name === attrName) return kept[i].value;
	}
	/**
	* Check whether any ancestor (or the current node) kept the given
	* attribute via `push(tag, attrs, ns, { keep: [...] })`.
	* @param {string} attrName
	* @returns {boolean}
	*/
	hasAnyParentAttr(attrName) {
		const kept = this._keptAttrs;
		for (let i = kept.length - 1; i >= 0; i--) if (kept[i].name === attrName) return true;
		return false;
	}
	/**
	* Get current node's sibling position (child index in parent).
	* @returns {number}
	*/
	getPosition() {
		if (this.path.length === 0) return -1;
		return this.path[this.path.length - 1].position ?? 0;
	}
	/**
	* Get current node's repeat counter (occurrence count of this tag name).
	* @returns {number}
	*/
	getCounter() {
		if (this.path.length === 0) return -1;
		return this.path[this.path.length - 1].counter ?? 0;
	}
	/**
	* Get current node's sibling index (alias for getPosition).
	* @returns {number}
	* @deprecated Use getPosition() or getCounter() instead
	*/
	getIndex() {
		return this.getPosition();
	}
	/**
	* Get current path depth.
	* @returns {number}
	*/
	getDepth() {
		return this.path.length;
	}
	/**
	* Get path as string.
	* @param {string} [separator] - Optional separator (uses default if not provided)
	* @param {boolean} [includeNamespace=true]
	* @returns {string}
	*/
	toString(separator, includeNamespace = true) {
		const sep = separator || this.separator;
		if (sep === this.separator && includeNamespace === true) {
			if (this._pathStringCache !== null) return this._pathStringCache;
			const result = this.path.map((n) => n.namespace ? `${n.namespace}:${n.tag}` : n.tag).join(sep);
			this._pathStringCache = result;
			return result;
		}
		return this.path.map((n) => includeNamespace && n.namespace ? `${n.namespace}:${n.tag}` : n.tag).join(sep);
	}
	/**
	* Get path as array of tag names.
	* @returns {string[]}
	*/
	toArray() {
		return this.path.map((n) => n.tag);
	}
	/**
	* Reset the path to empty.
	*/
	reset() {
		this._pathStringCache = null;
		this.path = [];
		this.siblingStacks = [];
		this._keptAttrs = [];
	}
	/**
	* Match current path against an Expression.
	* @param {Expression} expression
	* @returns {boolean}
	*/
	matches(expression) {
		const segments = expression.segments;
		if (segments.length === 0) return false;
		if (expression.hasDeepWildcard()) return this._matchWithDeepWildcard(segments);
		return this._matchSimple(segments);
	}
	/**
	* @private
	*/
	_matchSimple(segments) {
		if (this.path.length !== segments.length) return false;
		for (let i = 0; i < segments.length; i++) if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) return false;
		return true;
	}
	/**
	* @private
	*/
	_matchWithDeepWildcard(segments) {
		let pathIdx = this.path.length - 1;
		let segIdx = segments.length - 1;
		while (segIdx >= 0 && pathIdx >= 0) {
			const segment = segments[segIdx];
			if (segment.type === "deep-wildcard") {
				segIdx--;
				if (segIdx < 0) return true;
				const nextSeg = segments[segIdx];
				let found = false;
				for (let i = pathIdx; i >= 0; i--) if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {
					pathIdx = i - 1;
					segIdx--;
					found = true;
					break;
				}
				if (!found) return false;
			} else {
				if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) return false;
				pathIdx--;
				segIdx--;
			}
		}
		return segIdx < 0;
	}
	/**
	* @private
	*/
	_matchSegment(segment, node, isCurrentNode) {
		if (segment.tag !== "*" && segment.tag !== node.tag) return false;
		if (segment.namespace !== void 0) {
			if (segment.namespace !== "*" && segment.namespace !== node.namespace) return false;
		}
		if (segment.attrName !== void 0) {
			if (!isCurrentNode) return false;
			if (!node.values || !(segment.attrName in node.values)) return false;
			if (segment.attrValue !== void 0) {
				if (String(node.values[segment.attrName]) !== String(segment.attrValue)) return false;
			}
		}
		if (segment.position !== void 0) {
			if (!isCurrentNode) return false;
			const counter = node.counter ?? 0;
			if (segment.position === "first" && counter !== 0) return false;
			else if (segment.position === "odd" && counter % 2 !== 1) return false;
			else if (segment.position === "even" && counter % 2 !== 0) return false;
			else if (segment.position === "nth" && counter !== segment.positionValue) return false;
		}
		return true;
	}
	/**
	* Match any expression in the given set against the current path.
	* @param {ExpressionSet} exprSet
	* @returns {boolean}
	*/
	matchesAny(exprSet) {
		return exprSet.matchesAny(this);
	}
	/**
	* Create a snapshot of current state.
	* @returns {Object}
	*/
	snapshot() {
		return {
			path: this.path.map((node) => ({ ...node })),
			siblingStacks: this.siblingStacks.map((level) => level ? {
				counts: new Map(level.counts),
				total: level.total
			} : level),
			keptAttrs: this._keptAttrs.map((entry) => ({ ...entry }))
		};
	}
	/**
	* Restore state from snapshot.
	* @param {Object} snapshot
	*/
	restore(snapshot) {
		this._pathStringCache = null;
		this.path = snapshot.path.map((node) => ({ ...node }));
		this.siblingStacks = snapshot.siblingStacks.map((level) => level ? {
			counts: new Map(level.counts),
			total: level.total
		} : level);
		this._keptAttrs = (snapshot.keptAttrs || []).map((entry) => ({ ...entry }));
	}
	/**
	* Return the read-only {@link MatcherView} for this matcher.
	*
	* The same instance is returned on every call — no allocation occurs.
	* It always reflects the current parser state and is safe to pass to
	* user callbacks without risk of accidental mutation.
	*
	* @returns {MatcherView}
	*
	* @example
	* const view = matcher.readOnly();
	* // pass view to callbacks — it stays in sync automatically
	* view.matches(expr);       // ✓
	* view.getCurrentTag();     // ✓
	* // view.push(...)         // ✗ method does not exist — caught by TypeScript
	*/
	readOnly() {
		return this._view;
	}
};
//#endregion
//#region node_modules/is-unsafe/src/contexts/html.js
/**
* HTML context patterns.
*
* Detects XSS vectors that are dangerous when a string ends up rendered as HTML.
* All patterns use bounded quantifiers to ensure linear-time matching (ReDoS-safe).
*
* Each entry is { pattern: RegExp, id: string, description: string }
* so callers can inspect which rule fired if they need to.
*/
var HTML_PATTERNS = [
	{
		id: "html-script-open",
		description: "<script opening tag",
		pattern: /<script[\s>/]/i
	},
	{
		id: "html-script-close",
		description: "<\/script closing tag",
		pattern: /<\/script[\s>]/i
	},
	{
		id: "html-javascript-protocol",
		description: "javascript: URI scheme (with optional whitespace/encoding)",
		pattern: /j[\t\n\r ]*a[\t\n\r ]*v[\t\n\r ]*a[\t\n\r ]*s[\t\n\r ]*c[\t\n\r ]*r[\t\n\r ]*i[\t\n\r ]*p[\t\n\r ]*t[\t\n\r ]*:/i
	},
	{
		id: "html-vbscript-protocol",
		description: "vbscript: URI scheme",
		pattern: /vbscript[\t\n\r ]*:/i
	},
	{
		id: "html-data-html",
		description: "data:text/html URI — can execute scripts in browsers",
		pattern: /data[\t\n\r ]*:[\t\n\r ]*text\/html/i
	},
	{
		id: "html-data-xhtml",
		description: "data:application/xhtml+xml URI",
		pattern: /data[\t\n\r ]*:[\t\n\r ]*application\/xhtml/i
	},
	{
		id: "html-data-svg",
		description: "data:image/svg+xml URI — can execute scripts",
		pattern: /data[\t\n\r ]*:[\t\n\r ]*image\/svg\+xml/i
	},
	{
		id: "html-inline-event-handler",
		description: "Inline event handler attributes: onclick=, onerror=, onload=, etc.",
		pattern: /\bon\w{1,30}\s*=/i
	},
	{
		id: "html-entity-obfuscated-script",
		description: "HTML-entity-encoded <script (e.g. &#x3C;script or &lt;script)",
		pattern: /(?:&#x0*3[Cc];?|&#0*60;?|&lt;)\s*script/i
	},
	{
		id: "html-entity-obfuscated-javascript",
		description: "HTML-entity-encoded javascript: (partial — catches common &#106; or &#x6a; for \"j\")",
		pattern: /(?:&#x0*6[Aa];?|&#0*106;?)\s*(?:&#x0*61;?|a)[\s\S]{0,80}script\s*:/i
	},
	{
		id: "html-style-expression",
		description: "CSS expression() — IE-era code execution in style attributes",
		pattern: /style[\s\S]{0,20}expression\s*\(/i
	},
	{
		id: "html-object-embed",
		description: "<object or <embed tags that can load active content",
		pattern: /<(?:object|embed)[\s>/]/i
	},
	{
		id: "html-base-tag",
		description: "<base href= — can hijack all relative URLs on a page",
		pattern: /<base[\s>]/i
	},
	{
		id: "html-meta-refresh",
		description: "<meta http-equiv=\"refresh\" — can redirect users",
		pattern: /<meta[\s\S]{0,40}http-equiv[\s\S]{0,20}refresh/i
	},
	{
		id: "html-srcdoc",
		description: "srcdoc= attribute on iframes — embeds HTML that can run scripts",
		pattern: /srcdoc\s*=/i
	},
	{
		id: "html-iframe",
		description: "<iframe tag",
		pattern: /<iframe[\s>/]/i
	},
	{
		id: "html-form",
		description: "<form tag — can be used for phishing / credential harvesting injection",
		pattern: /<form[\s>/]/i
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/xml.js
/**
* XML context patterns.
*
* Detects injection vectors that are specifically dangerous when a string
* is inserted into an XML document (not HTML rendering context).
*
* Key distinction from HTML: these patterns target parser-level attacks —
* things that can confuse or subvert an XML parser, trigger external entity
* resolution, or inject DTD content. HTML rendering concerns (XSS) belong
* in the HTML context.
*/
var XML_PATTERNS = [
	{
		id: "xml-cdata-injection",
		description: "CDATA section injection: <![CDATA[ breaks out of text node context",
		pattern: /<!\[CDATA\[/i
	},
	{
		id: "xml-cdata-close",
		description: "CDATA close sequence: ]]> can terminate an enclosing CDATA section",
		pattern: /\]\]>/
	},
	{
		id: "xml-processing-instruction",
		description: "XML processing instruction: <?xml-stylesheet or <?php etc.",
		pattern: /<\?(?:xml[\- ]|php|asp)/i
	},
	{
		id: "xml-doctype-injection",
		description: "DOCTYPE declaration embedded in content — can define entities",
		pattern: /<!DOCTYPE(?:[\s[]|$)/i
	},
	{
		id: "xml-entity-system",
		description: "SYSTEM keyword — used in external entity declarations (XXE)",
		pattern: /\bSYSTEM\s+["']/i
	},
	{
		id: "xml-entity-public",
		description: "PUBLIC keyword — used in external entity declarations (XXE)",
		pattern: /\bPUBLIC\s+["']/i
	},
	{
		id: "xml-entity-declaration",
		description: "<!ENTITY declaration — defines entities, potential XXE or entity expansion",
		pattern: /<!ENTITY[\s%]/i
	},
	{
		id: "xml-billion-laughs",
		description: "Entity reference chaining / billion laughs: repeated &eX; style references",
		pattern: /(?:&\w{1,20};){3,}/
	},
	{
		id: "xml-namespace-confusion",
		description: "xmlns: attribute injection — can redefine namespaces to confuse parsers",
		pattern: /\bxmlns\s*(?::\w{1,40})?\s*=/i
	},
	{
		id: "xml-comment-injection",
		description: "<!-- comment injection — can hide content from some parsers",
		pattern: /<!--/
	},
	{
		id: "xml-comment-close",
		description: "--> closes an enclosing XML comment",
		pattern: /-->/
	},
	{
		id: "xml-pi-close",
		description: "?> closes an enclosing processing instruction",
		pattern: /\?>/
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/svg.js
/**
* SVG context patterns.
*
* SVG is XML-based but renders in browsers, giving it a unique attack surface
* that combines XML parser behaviour with browser rendering and JavaScript execution.
*
* Many of these vectors bypass HTML sanitizers that don't understand SVG semantics
* (DOMPurify has documented bypass vulnerabilities specifically in SVG/XML context).
*/
var SVG_PATTERNS = [
	{
		id: "svg-script-element",
		description: "<script element inside SVG executes JavaScript",
		pattern: /<script[\s>/]/i
	},
	{
		id: "svg-xlink-href-javascript",
		description: "xlink:href with javascript: — classic SVG XSS via <a> or <use>",
		pattern: /xlink\s*:\s*href\s*=\s*["']?\s*javascript\s*:/i
	},
	{
		id: "svg-href-javascript",
		description: "href= with javascript: in SVG context (<a>, <animate>, etc.)",
		pattern: /href\s*=\s*["']?\s*javascript\s*:/i
	},
	{
		id: "svg-foreignobject",
		description: "<foreignObject embeds HTML inside SVG — can execute scripts",
		pattern: /<foreignObject[\s>/]/i
	},
	{
		id: "svg-use-external",
		description: "<use xlink:href or href pointing to external resource (non-fragment URL)",
		pattern: /<use[\s\S]{0,60}(?:xlink\s*:\s*)?href\s*=\s*(?:["'][^#]|[^"'#\s>])/i
	},
	{
		id: "svg-animate-href",
		description: "<animate attributeName=\"href\" — can dynamically change href to javascript:",
		pattern: /<animate[\s\S]{0,80}attributeName\s*=\s*["'][\s]*href["']/i
	},
	{
		id: "svg-animate-xlinkhref",
		description: "<animate attributeName=\"xlink:href\"",
		pattern: /<animate[\s\S]{0,80}attributeName\s*=\s*["'][\s]*xlink\s*:\s*href["']/i
	},
	{
		id: "svg-set-javascript",
		description: "<set to=\"javascript:...\" — sets an attribute to a javascript: URI",
		pattern: /<set[\s\S]{0,80}to\s*=\s*["']?\s*javascript\s*:/i
	},
	{
		id: "svg-event-handler",
		description: "SVG-specific event handler attributes: onload=, onerror=, onactivate=, etc.",
		pattern: /\bon(?:load|error|activate|begin|end|repeat|focus|blur|click|mouse\w{1,20}|key\w{1,20})\s*=/i
	},
	{
		id: "svg-handler-generic",
		description: "Generic on* handler catch-all for SVG attributes",
		pattern: /\bon\w{1,30}\s*=/i
	},
	{
		id: "svg-filter-feimage",
		description: "<feImage href= — filter primitive that can load external resources",
		pattern: /<feImage[\s\S]{0,80}(?:xlink\s*:\s*)?href\s*=/i
	},
	{
		id: "svg-image-external",
		description: "<image xlink:href with http/https or javascript protocol",
		pattern: /<image[\s\S]{0,80}(?:xlink\s*:\s*)?href\s*=\s*["']?\s*(?:https?|javascript)\s*:/i
	},
	{
		id: "svg-style-javascript",
		description: "style= attribute containing javascript: (e.g. background:url(javascript:...))",
		pattern: /style\s*=[\s\S]{0,60}javascript\s*:/i
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/sql.js
/**
* SQL context patterns — high-precision rules only.
*
* These rules have very low false-positive risk and are safe to apply to
* general user text (names, descriptions, search queries, etc.).
* All patterns are ReDoS-safe — unlike the `sql-injection` npm package
* which has an active CVE on its own detection regexes.
*
* For exhaustive coverage including noisier heuristics (comment sequences,
* hex literals, stacked queries with semicolons), use 'SQL-STRICT' instead.
* Apply 'SQL-STRICT' only to strings that are specifically SQL fragments,
* not to general free-text fields.
*/
var SQL_PATTERNS = [
	{
		id: "sql-block-comment-open",
		description: "SQL block comment open: /* ... */ — unusual in legitimate user text",
		pattern: /\/\*/
	},
	{
		id: "sql-union-select",
		description: "UNION SELECT — most common SQL injection aggregation attack",
		pattern: /\bUNION\s{1,20}(?:ALL\s{1,20})?SELECT\b/i
	},
	{
		id: "sql-drop-table",
		description: "DROP TABLE — destructive DDL injection",
		pattern: /\bDROP\s{1,20}TABLE\b/i
	},
	{
		id: "sql-drop-database",
		description: "DROP DATABASE — destructive DDL injection",
		pattern: /\bDROP\s{1,20}DATABASE\b/i
	},
	{
		id: "sql-insert-into",
		description: "INSERT INTO — data injection",
		pattern: /\bINSERT\s{1,20}INTO\b/i
	},
	{
		id: "sql-delete-from",
		description: "DELETE FROM — data deletion injection",
		pattern: /\bDELETE\s{1,20}FROM\b/i
	},
	{
		id: "sql-update-set",
		description: "UPDATE ... SET — data modification injection",
		pattern: /\bUPDATE\b[\s\S]{1,60}\bSET\b/i
	},
	{
		id: "sql-exec-xp",
		description: "EXEC xp_ — MSSQL extended stored procedure execution",
		pattern: /\bEXEC(?:UTE)?\s{1,20}xp_/i
	},
	{
		id: "sql-tautology-string",
		description: "Classic string tautology: ' OR '1'='1 or \" OR \"1\"=\"1\"",
		pattern: /'\s{0,10}OR\s{0,10}'[^']{0,20}'\s*=\s*'[^']{0,20}/i
	},
	{
		id: "sql-tautology-numeric",
		description: "Numeric tautology: OR 1=1",
		pattern: /\bOR\s{1,10}1\s*=\s*1\b/i
	},
	{
		id: "sql-always-true-zero",
		description: "Numeric tautology: OR 0=0",
		pattern: /\bOR\s{1,10}0\s*=\s*0\b/i
	},
	{
		id: "sql-sleep-benchmark",
		description: "Time-based blind injection: SLEEP() or BENCHMARK()",
		pattern: /\b(?:SLEEP|BENCHMARK)\s*\(/i
	},
	{
		id: "sql-waitfor-delay",
		description: "MSSQL time-based blind injection: WAITFOR DELAY",
		pattern: /\bWAITFOR\s{1,20}DELAY\b/i
	},
	{
		id: "sql-char-function",
		description: "CHAR() function — used to obfuscate injected strings",
		pattern: /\bCHAR\s*\(\s*\d{1,3}/i
	},
	{
		id: "sql-information-schema",
		description: "INFORMATION_SCHEMA — reconnaissance query for table/column enumeration",
		pattern: /\bINFORMATION_SCHEMA\b/i
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/shell.js
/**
* SHELL context patterns.
*
* Detects shell injection vectors and path traversal patterns.
* Designed for use when a string will be passed to a shell command,
* used as a file path, or interpolated into OS-level operations.
*/
var SHELL_PATTERNS = [
	{
		id: "shell-path-traversal-unix",
		description: "Unix path traversal: ../  — climbing the directory tree",
		pattern: /\.\.\//
	},
	{
		id: "shell-path-traversal-windows",
		description: "Windows path traversal: ..\\ — climbing the directory tree",
		pattern: /\.\.\\/
	},
	{
		id: "shell-path-traversal-encoded",
		description: "URL-encoded path traversal: %2e%2e or %2f variants",
		pattern: /%2e%2e|%2f\.\.|\.\.%2f/i
	},
	{
		id: "shell-null-byte",
		description: "Null byte injection: \\x00 or %00 — truncates strings in C-backed functions",
		pattern: /\x00|%00/
	},
	{
		id: "shell-semicolon",
		description: "Semicolon command separator: cmd1; cmd2",
		pattern: /;/
	},
	{
		id: "shell-pipe",
		description: "Pipe operator: cmd1 | cmd2",
		pattern: /\|/
	},
	{
		id: "shell-and-operator",
		description: "AND operator: cmd1 && cmd2",
		pattern: /&&/
	},
	{
		id: "shell-or-operator",
		description: "OR operator: cmd1 || cmd2",
		pattern: /\|\|/
	},
	{
		id: "shell-backtick",
		description: "Backtick command substitution: `cmd`",
		pattern: /`/
	},
	{
		id: "shell-dollar-paren",
		description: "Dollar-paren command substitution: $(cmd)",
		pattern: /\$\(/
	},
	{
		id: "shell-dollar-brace",
		description: "Dollar-brace variable expansion: ${var} — can be abused for injection",
		pattern: /\$\{/
	},
	{
		id: "shell-redirect-out",
		description: "Output redirection: cmd > file or cmd >> file",
		pattern: />{1,2}/
	},
	{
		id: "shell-redirect-in",
		description: "Input redirection: cmd < file",
		pattern: /</
	},
	{
		id: "shell-newline-injection",
		description: "Newline injection: \\n or \\r — can inject new shell commands",
		pattern: /[\n\r]/
	},
	{
		id: "shell-glob-star",
		description: "Glob expansion: * or ? — can expand to unintended files",
		pattern: /[/\\][*?]/
	},
	{
		id: "shell-absolute-root",
		description: "Absolute root path injection: string starting with / or \\ (Windows UNC)",
		pattern: /^(?:\/|\\\\)/
	},
	{
		id: "shell-windows-drive",
		description: "Windows drive letter path injection: C:\\ or D:/",
		pattern: /^[a-zA-Z]:[/\\]/
	},
	{
		id: "shell-curl-wget",
		description: "curl/wget with URL or flags — can exfiltrate data or download payloads",
		pattern: /\b(?:curl|wget)\s+(?:https?:\/\/|ftp:\/\/|-)/i
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/redos.js
/**
* REDOS context patterns.
*
* Detects strings that, if used as regular expressions, could cause
* catastrophic backtracking (ReDoS — Regular Expression Denial of Service).
*
* These patterns detect the structural forms that lead to exponential or
* polynomial backtracking in NFA-based regex engines (V8, PCRE, Java, etc.).
*
* Use this context when user-supplied strings will be compiled into RegExp objects.
*/
var REDOS_PATTERNS = [
	{
		id: "redos-nested-quantifier-plus",
		description: "Nested + quantifier inside a group with outer quantifier: (a+)+, (.+b)*, etc.",
		pattern: /\([^)]*\+[^)]*\)[+*]/
	},
	{
		id: "redos-nested-quantifier-star",
		description: "Nested * quantifier: (a*)* or (a*)+ — catastrophic backtracking",
		pattern: /\([^)]*\*[^)]*\)[*+]/
	},
	{
		id: "redos-nested-groups",
		description: "Doubly nested quantified groups: ((a+)+) — guaranteed catastrophic",
		pattern: /\(\([^)]{0,40}\)[+*]\)[+*]/
	},
	{
		id: "redos-alternation-overlap",
		description: "Overlapping alternation under quantifier: (a|a)+ — ambiguous NFA paths",
		pattern: /\(([^|()]{1,20})\|(?:\1)(?:\|[^|()]{1,20}){0,5}\)[+*?]{1,2}/
	},
	{
		id: "redos-star-plus-concat",
		description: "(x*x)+ pattern — triggers super-linear backtracking",
		pattern: /\([^)]{0,10}\*[^)]{0,10}\)[+*]/
	},
	{
		id: "redos-dot-star-greedy",
		description: "(.*){n,} or (.+){n,} — repeated greedy dot quantifiers",
		pattern: /\(\.[*+]\)\{?\d/
	},
	{
		id: "redos-large-repetition",
		description: "Very large fixed or range repetition count {1000,} or {1000,n} — denial of service via backtracking",
		pattern: /\{\d{4,}(?:,\d*)?\}/
	},
	{
		id: "redos-catastrophic-alternation",
		description: "Long alternation with many similar branches — polynomial backtracking risk",
		pattern: /\([^)]{0,200}(?:\|[^|)]{0,50}){9,}\)/
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/nosql.js
var sep = "[\"'\\s]*:";
var NOSQL_PATTERNS = [
	{
		id: "nosql-where-operator",
		description: "$where — executes arbitrary JavaScript server-side in MongoDB",
		pattern: new RegExp(`\\$where${sep}`, "i")
	},
	{
		id: "nosql-ne-operator",
		description: "$ne — \"not equal\" operator used to bypass equality checks",
		pattern: new RegExp(`\\$ne${sep}`, "i")
	},
	{
		id: "nosql-gt-operator",
		description: "$gt — \"greater than\" used to bypass password/value checks",
		pattern: new RegExp(`\\$gte?${sep}`, "i")
	},
	{
		id: "nosql-lt-operator",
		description: "$lt / $lte — \"less than\" bypass variants",
		pattern: new RegExp(`\\$lte?${sep}`, "i")
	},
	{
		id: "nosql-regex-operator",
		description: "$regex — can be used to extract data character by character (blind injection)",
		pattern: new RegExp(`\\$regex${sep}`, "i")
	},
	{
		id: "nosql-or-operator",
		description: "$or — logical OR; used to create always-true conditions",
		pattern: new RegExp(`\\$or${sep}\\s*\\[`, "i")
	},
	{
		id: "nosql-and-operator",
		description: "$and — logical AND operator injection",
		pattern: new RegExp(`\\$and${sep}\\s*\\[`, "i")
	},
	{
		id: "nosql-nor-operator",
		description: "$nor — logical NOR operator injection",
		pattern: new RegExp(`\\$nor${sep}\\s*\\[`, "i")
	},
	{
		id: "nosql-exists-operator",
		description: "$exists — can enumerate fields to determine schema",
		pattern: new RegExp(`\\$exists${sep}`, "i")
	},
	{
		id: "nosql-in-operator",
		description: "$in — matches any value in a list; can enumerate values",
		pattern: new RegExp(`\\$in${sep}\\s*\\[`, "i")
	},
	{
		id: "nosql-expr-operator",
		description: "$expr — allows aggregation expressions in queries (MongoDB 3.6+)",
		pattern: new RegExp(`\\$expr${sep}`, "i")
	},
	{
		id: "nosql-function-operator",
		description: "$function — executes arbitrary JavaScript in MongoDB 4.4+",
		pattern: new RegExp(`\\$function${sep}`, "i")
	},
	{
		id: "nosql-accumulator-operator",
		description: "$accumulator — custom aggregation with arbitrary JS execution",
		pattern: new RegExp(`\\$accumulator${sep}`, "i")
	},
	{
		id: "nosql-proto-pollution",
		description: "__proto__ — prototype pollution via object key injection",
		pattern: /__proto__/
	},
	{
		id: "nosql-constructor-prototype",
		description: "constructor.prototype — alternative prototype pollution vector (dot notation or JSON key)",
		pattern: /constructor[\s"':.,{\[]*prototype/i
	},
	{
		id: "nosql-proto-bracket",
		description: "[\"__proto__\"] — bracket-notation prototype pollution",
		pattern: /\[["']__proto__["']\]/
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/log.js
/**
* LOG context patterns.
*
* Detects injection vectors that are dangerous when a string is written
* to a log file, passed to a logging framework, or interpolated into
* a log message that will be parsed or displayed.
*
* Attack categories:
*   1. CRLF injection — injects fake log lines by embedding newlines
*   2. Log4Shell (CVE-2021-44228) — ${jndi:...} triggers JNDI lookup in Log4j
*   3. SSTI in log templates — {{...}}, #{...} trigger template evaluation
*      if the log message is passed through a template engine
*   4. Null byte injection — truncates log entries in some implementations
*   5. ANSI escape injection — manipulates terminal output when logs are
*      tailed in a terminal (colour codes, cursor movement, etc.)
*
* Note: Newline characters (\n, \r) will produce false positives for
* multi-line legitimate values. Use this context only for single-line
* log field values (usernames, IDs, request parameters, etc.).
*/
var LOG_PATTERNS = [
	{
		id: "log-crlf-injection",
		description: "CRLF injection: literal \\r or \\n embeds fake log lines",
		pattern: /[\r\n]/
	},
	{
		id: "log-url-encoded-crlf",
		description: "URL-encoded CRLF: %0d, %0a, %0D, %0A — decoded by some log parsers",
		pattern: /%0[dDaA]/
	},
	{
		id: "log-unicode-newline",
		description: "Unicode newline variants: U+2028 (line separator), U+2029 (paragraph separator)",
		pattern: /[\u2028\u2029]/
	},
	{
		id: "log-log4shell-jndi",
		description: "Log4Shell: ${jndi:...} triggers remote code execution in Apache Log4j",
		pattern: /\$\{jndi\s*:/i
	},
	{
		id: "log-log4shell-obfuscated",
		description: "Obfuscated Log4Shell: ${::-j}... lookup-bypass prefix used to evade WAF detection",
		pattern: /\$\{::-/
	},
	{
		id: "log-log4j-lookup",
		description: "Log4j lookup syntax: ${env:...}, ${sys:...}, ${ctx:...} — data exfiltration",
		pattern: /\$\{(?:env|sys|ctx|main|map|sd|web|docker|k8s|spring)\s*:/i
	},
	{
		id: "log-ssti-double-brace",
		description: "SSTI double-brace: {{expression}} — Jinja2, Twig, Handlebars, etc.",
		pattern: /\{\{[\s\S]{0,80}\}\}/
	},
	{
		id: "log-ssti-hash-brace",
		description: "SSTI hash-brace: #{expression} — Thymeleaf, Velocity, Ruby ERB",
		pattern: /#\{[\s\S]{0,80}\}/
	},
	{
		id: "log-ssti-dollar-brace",
		description: "SSTI/EL injection: ${expression with operators or method calls} — JSP EL, Freemarker, SpEL",
		pattern: /\$\{[^}]*(?:\.|\(|\*|\+|\bclass\b|\bruntime\b|\bprocess\b|\bexec\b)[^}]{0,80}\}/i
	},
	{
		id: "log-ssti-percent-tag",
		description: "SSTI ERB/ASP tag: <%= expression %> — Ruby ERB, ASP",
		pattern: /<%=[\s\S]{0,80}%>/
	},
	{
		id: "log-null-byte",
		description: "Null byte: \\x00 or %00 — can truncate log entries in C-backed loggers",
		pattern: /\x00|%00/
	},
	{
		id: "log-ansi-escape",
		description: "ANSI escape sequence: ESC[ — can manipulate terminal output when logs are tailed",
		pattern: /\x1b\[/
	}
];
//#endregion
//#region node_modules/is-unsafe/src/contexts/sql-strict.js
/**
* SQL-STRICT context patterns.
*
* Extends the base 'SQL' context with three additional rules that are
* effective at detecting real injections but carry a higher false-positive
* risk on general free-text input.
*
* Use 'SQL-STRICT' when:
*   - The string is specifically a SQL fragment or database identifier
*   - You control the input domain (e.g. a dedicated SQL search field)
*   - You can tolerate occasional false positives in exchange for broader coverage
*
* Use 'SQL' (not STRICT) when:
*   - The field is general user text (names, descriptions, comments)
*   - False positives would block legitimate content (e.g. "see note -- above")
*
* Rules moved here from 'SQL' due to false-positive risk:
*
*   sql-line-comment   — "--" fires on "see note -- above", "value--", CSS var(--primary)
*   sql-stacked-query  — "; SELECT" fires on legitimate prose with semicolons + SQL words
*   sql-hex-encoding   — "0xDEAD" fires on hex values in technical docs and log output
*/
var SQL_STRICT_EXTRA = [
	{
		id: "sql-line-comment",
		description: "SQL line comment: -- followed by whitespace or end of string",
		pattern: /--(?:\s|$)/
	},
	{
		id: "sql-stacked-query",
		description: "Stacked queries: semicolon immediately followed by a SQL keyword",
		pattern: /;\s{0,10}(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC)\b/i
	},
	{
		id: "sql-hex-encoding",
		description: "Hex-encoded string injection: 0x41414141 style (MySQL)",
		pattern: /\b0x[0-9a-f]{4,}/i
	}
];
var SQL_STRICT_PATTERNS = [...SQL_PATTERNS, ...SQL_STRICT_EXTRA];
//#endregion
//#region node_modules/is-unsafe/src/index.js
HTML_PATTERNS.label = "HTML";
XML_PATTERNS.label = "XML";
SVG_PATTERNS.label = "SVG";
SQL_PATTERNS.label = "SQL";
SQL_STRICT_PATTERNS.label = "SQL-STRICT";
SHELL_PATTERNS.label = "SHELL";
REDOS_PATTERNS.label = "REDOS";
NOSQL_PATTERNS.label = "NOSQL";
LOG_PATTERNS.label = "LOG";
Object.freeze({
	HTML: HTML_PATTERNS,
	XML: XML_PATTERNS,
	SVG: SVG_PATTERNS,
	SQL: SQL_PATTERNS,
	"SQL-STRICT": SQL_STRICT_PATTERNS,
	SHELL: SHELL_PATTERNS,
	REDOS: REDOS_PATTERNS,
	NOSQL: NOSQL_PATTERNS,
	LOG: LOG_PATTERNS
});
/**
* @typedef {{ id: string, description: string, pattern: RegExp }} Rule
*/
/**
* @typedef {Rule[]} PatternList
*/
/**
* @typedef {Object} MatchResult
* @property {string} context     - Label identifying which context matched ('HTML', 'CUSTOM', etc.)
* @property {string} id          - Rule identifier
* @property {string} description - Human-readable description of what was matched
* @property {RegExp} pattern     - The pattern that matched
*/
/**
* @param {unknown} value
*/
function assertString(value) {
	if (typeof value !== "string") throw new TypeError(`is-unsafe: first argument must be a string, got ${typeof value}`);
}
/**
* @param {unknown} context
*/
function assertContext(context) {
	if (context instanceof RegExp) return;
	if (Array.isArray(context)) {
		if (context.length === 0) throw new TypeError("is-unsafe: context must not be an empty array");
		if (Array.isArray(context[0])) {
			for (const list of context) if (!Array.isArray(list) || list.length === 0) throw new TypeError("is-unsafe: each context in the array must be a non-empty pattern array (PatternList)");
		}
		return;
	}
	throw new TypeError(`is-unsafe: second argument must be a PatternList (e.g. HTML), an array of PatternLists (e.g. [HTML, XML]), or a RegExp. Got: ${typeof context}`);
}
/**
* Normalise any valid context arg into an array of PatternLists.
*
* @param {Rule[]|Rule[][]|RegExp} context
* @returns {{ lists: Rule[][]|null, regex: RegExp|null }}
*/
function normalise(context) {
	if (context instanceof RegExp) return {
		lists: null,
		regex: context
	};
	if (Array.isArray(context[0])) return {
		lists: context,
		regex: null
	};
	return {
		lists: [context],
		regex: null
	};
}
/**
* Test value against a single PatternList. Returns the first MatchResult or null.
*
* @param {string} value
* @param {Rule[]} list
* @returns {MatchResult|null}
*/
function matchList(value, list) {
	const label = list.label ?? "CUSTOM";
	for (const rule of list) if (rule.pattern.test(value)) return {
		context: label,
		id: rule.id,
		description: rule.description,
		pattern: rule.pattern
	};
	return null;
}
/**
* Returns `true` if `value` is unsafe in the given context(s), `false` otherwise.
*
* @param {string} value - The string to test
* @param {PatternList | PatternList[] | RegExp} context
*   - A PatternList imported from is-unsafe (e.g. `HTML`, `XML`)
*   - An array of PatternLists — returns true if unsafe in **any** of them
*   - A custom RegExp — returns true if the pattern matches
* @returns {boolean}
*
* @example
* import { isUnsafe, HTML, SQL } from 'is-unsafe';
*
* isUnsafe('<script>alert(1)<\/script>', HTML)       // true
* isUnsafe('hello world', HTML)                     // false
* isUnsafe('value', [HTML, SQL])                    // false
* isUnsafe('value', /my-pattern/i)                  // false
*/
function isUnsafe(value, context) {
	assertString(value);
	assertContext(context);
	const { lists, regex } = normalise(context);
	if (regex) return regex.test(value);
	for (const list of lists) if (matchList(value, list) !== null) return true;
	return false;
}
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
/**
* Extract raw attributes (without prefix) from prefixed attribute map
* @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap
* @param {object} options - Parser options containing attributeNamePrefix
* @returns {object} Raw attributes for matcher
*/
function extractRawAttributes(prefixedAttrs, options) {
	if (!prefixedAttrs) return {};
	const attrs = options.attributesGroupName ? prefixedAttrs[options.attributesGroupName] : prefixedAttrs;
	if (!attrs) return {};
	const rawAttrs = {};
	for (const key in attrs) if (key.startsWith(options.attributeNamePrefix)) {
		const rawName = key.substring(options.attributeNamePrefix.length);
		rawAttrs[rawName] = attrs[key];
	} else rawAttrs[key] = attrs[key];
	return rawAttrs;
}
/**
* Extract namespace from raw tag name
* @param {string} rawTagName - Tag name possibly with namespace (e.g., "soap:Envelope")
* @returns {string|undefined} Namespace or undefined
*/
function extractNamespace(rawTagName) {
	if (!rawTagName || typeof rawTagName !== "string") return void 0;
	const colonIndex = rawTagName.indexOf(":");
	if (colonIndex !== -1 && colonIndex > 0) {
		const ns = rawTagName.substring(0, colonIndex);
		if (ns !== "xmlns") return ns;
	}
}
var OrderedObjParser = class {
	constructor(options, externalEntities) {
		this.options = options;
		this.currentNode = null;
		this.tagsNodeStack = [];
		this.parseXml = parseXml;
		this.parseTextData = parseTextData;
		this.resolveNameSpace = resolveNameSpace;
		this.buildAttributesMap = buildAttributesMap;
		this.isItStopNode = isItStopNode;
		this.replaceEntitiesValue = replaceEntitiesValue;
		this.readStopNodeData = readStopNodeData;
		this.saveTextToParentTag = saveTextToParentTag;
		this.addChild = addChild;
		this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
		this.entityExpansionCount = 0;
		this.currentExpandedLength = 0;
		this.doctypefound = false;
		let namedEntities = { ...XML };
		if (this.options.entityDecoder) this.entityDecoder = this.options.entityDecoder;
		else {
			if (typeof this.options.htmlEntities === "object") namedEntities = this.options.htmlEntities;
			else if (this.options.htmlEntities === true) namedEntities = {
				...COMMON_HTML,
				...CURRENCY
			};
			this.entityDecoder = new EntityDecoder({
				namedEntities: {
					...namedEntities,
					...externalEntities
				},
				numericAllowed: this.options.htmlEntities,
				limit: {
					maxTotalExpansions: this.options.processEntities.maxTotalExpansions,
					maxExpandedLength: this.options.processEntities.maxExpandedLength,
					applyLimitsTo: this.options.processEntities.appliesTo
				},
				onInputEntity: (name, value) => isUnsafe(value, [HTML_PATTERNS, XML_PATTERNS]) ? ENTITY_ACTION.BLOCK : ENTITY_ACTION.ALLOW
			});
		}
		this.matcher = new Matcher();
		this.readonlyMatcher = this.matcher.readOnly();
		this.isCurrentNodeStopNode = false;
		this.stopNodeExpressionsSet = new ExpressionSet();
		const stopNodesOpts = this.options.stopNodes;
		if (stopNodesOpts && stopNodesOpts.length > 0) {
			for (let i = 0; i < stopNodesOpts.length; i++) {
				const stopNodeExp = stopNodesOpts[i];
				if (typeof stopNodeExp === "string") this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));
				else if (stopNodeExp instanceof Expression) this.stopNodeExpressionsSet.add(stopNodeExp);
			}
			this.stopNodeExpressionsSet.seal();
		}
	}
};
/**
* @param {string} val
* @param {string} tagName
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
* @param {boolean} dontTrim
* @param {boolean} hasAttributes
* @param {boolean} isLeafNode
* @param {boolean} escapeEntities
*/
function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {
	const options = this.options;
	if (val !== void 0) {
		if (options.trimValues && !dontTrim) val = val.trim();
		if (val.length > 0) {
			if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
			const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;
			const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
			if (newval === null || newval === void 0) return val;
			else if (typeof newval !== typeof val || newval !== val) return newval;
			else if (options.trimValues) return parseValue(val, options.parseTagValue, options.numberParseOptions);
			else if (val.trim() === val) return parseValue(val, options.parseTagValue, options.numberParseOptions);
			else return val;
		}
	}
}
function resolveNameSpace(tagname) {
	if (this.options.removeNSPrefix) {
		const tags = tagname.split(":");
		const prefix = tagname.charAt(0) === "/" ? "/" : "";
		if (tags[0] === "xmlns") return "";
		if (tags.length === 2) tagname = prefix + tags[1];
	}
	return tagname;
}
var attrsRegx = /* @__PURE__ */ new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?", "gm");
function buildAttributesMap(attrStr, jPath, tagName, force = false) {
	const options = this.options;
	if (force === true || options.ignoreAttributes !== true && typeof attrStr === "string") {
		const matches = getAllMatches(attrStr, attrsRegx);
		const len = matches.length;
		const attrs = {};
		const processedVals = new Array(len);
		let hasRawAttrs = false;
		const rawAttrsForMatcher = {};
		for (let i = 0; i < len; i++) {
			const attrName = this.resolveNameSpace(matches[i][1]);
			const oldVal = matches[i][4];
			if (attrName.length && oldVal !== void 0) {
				let val = oldVal;
				if (options.trimValues) val = val.trim();
				val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);
				processedVals[i] = val;
				rawAttrsForMatcher[attrName] = val;
				hasRawAttrs = true;
			}
		}
		if (hasRawAttrs && typeof jPath === "object" && jPath.updateCurrent) jPath.updateCurrent(rawAttrsForMatcher);
		const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;
		let hasAttrs = false;
		for (let i = 0; i < len; i++) {
			const attrName = this.resolveNameSpace(matches[i][1]);
			if (this.ignoreAttributesFn(attrName, jPathStr)) continue;
			let aName = options.attributeNamePrefix + attrName;
			if (attrName.length) {
				if (options.transformAttributeName) aName = options.transformAttributeName(aName);
				aName = sanitizeName(aName, options);
				if (matches[i][4] !== void 0) {
					const oldVal = processedVals[i];
					const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);
					if (newVal === null || newVal === void 0) attrs[aName] = oldVal;
					else if (typeof newVal !== typeof oldVal || newVal !== oldVal) attrs[aName] = newVal;
					else attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);
					hasAttrs = true;
				} else if (options.allowBooleanAttributes) {
					attrs[aName] = true;
					hasAttrs = true;
				}
			}
		}
		if (!hasAttrs) return;
		if (options.attributesGroupName && !options.preserveOrder) {
			const attrCollection = {};
			attrCollection[options.attributesGroupName] = attrs;
			return attrCollection;
		}
		return attrs;
	}
}
var parseXml = function(xmlData) {
	xmlData = xmlData.replace(/\r\n?/g, "\n");
	const xmlObj = new XmlNode("!xml");
	let currentNode = xmlObj;
	let textData = "";
	this.matcher.reset();
	this.entityDecoder.reset();
	this.entityExpansionCount = 0;
	this.currentExpandedLength = 0;
	this.doctypefound = false;
	const options = this.options;
	const docTypeReader = new DocTypeReader(options.processEntities);
	const xmlLen = xmlData.length;
	for (let i = 0; i < xmlLen; i++) if (xmlData[i] === "<") {
		const c1 = xmlData.charCodeAt(i + 1);
		if (c1 === 47) {
			const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.");
			let tagName = xmlData.substring(i + 2, closeIndex).trim();
			if (options.removeNSPrefix) {
				const colonIndex = tagName.indexOf(":");
				if (colonIndex !== -1) tagName = tagName.substr(colonIndex + 1);
			}
			tagName = transformTagName(options.transformTagName, tagName, "", options).tagName;
			if (currentNode) textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
			const lastTagName = this.matcher.getCurrentTag();
			if (tagName && options.unpairedTagsSet.has(tagName)) throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
			if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {
				this.matcher.pop();
				this.tagsNodeStack.pop();
			}
			this.matcher.pop();
			this.isCurrentNodeStopNode = false;
			currentNode = this.tagsNodeStack.pop();
			textData = "";
			i = closeIndex;
		} else if (c1 === 63) {
			let tagData = readTagExp(xmlData, i, false, "?>");
			if (!tagData) throw new Error("Pi Tag is not closed.");
			textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
			const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);
			if (attsMap) {
				const ver = attsMap[this.options.attributeNamePrefix + "version"];
				this.entityDecoder.setXmlVersion(Number(ver) || 1);
				docTypeReader.setXmlVersion(Number(ver) || 1);
			}
			if (options.ignoreDeclaration && tagData.tagName === "?xml" || options.ignorePiTags) {} else {
				const childNode = new XmlNode(tagData.tagName);
				childNode.add(options.textNodeName, "");
				if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) childNode[":@"] = attsMap;
				this.addChild(currentNode, childNode, this.readonlyMatcher, i);
			}
			i = tagData.closeIndex + 1;
		} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) {
			const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed.");
			if (options.commentPropName) {
				const comment = xmlData.substring(i + 4, endIndex - 2);
				textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
				currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);
			}
			i = endIndex;
		} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 68) {
			if (this.doctypefound) throw new Error("Multiple DOCTYPE declarations found.");
			this.doctypefound = true;
			const result = docTypeReader.readDocType(xmlData, i);
			this.entityDecoder.addInputEntities(result.entities);
			i = result.i;
		} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) {
			const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
			const tagExp = xmlData.substring(i + 9, closeIndex);
			textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
			let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);
			if (val == void 0) val = "";
			if (options.cdataPropName) currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);
			else currentNode.add(options.textNodeName, val);
			i = closeIndex + 2;
		} else {
			let result = readTagExp(xmlData, i, options.removeNSPrefix);
			if (!result) {
				const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));
				throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`);
			}
			let tagName = result.tagName;
			const rawTagName = result.rawTagName;
			let tagExp = result.tagExp;
			let attrExpPresent = result.attrExpPresent;
			let closeIndex = result.closeIndex;
			({tagName, tagExp} = transformTagName(options.transformTagName, tagName, tagExp, options));
			if (options.strictReservedNames && (tagName === options.commentPropName || tagName === options.cdataPropName || tagName === options.textNodeName || tagName === options.attributesGroupName)) throw new Error(`Invalid tag name: ${tagName}`);
			if (currentNode && textData) {
				if (currentNode.tagname !== "!xml") textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);
			}
			const lastTag = currentNode;
			if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {
				currentNode = this.tagsNodeStack.pop();
				this.matcher.pop();
			}
			let isSelfClosing = false;
			if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
				isSelfClosing = true;
				if (tagName[tagName.length - 1] === "/") {
					tagName = tagName.substr(0, tagName.length - 1);
					tagExp = tagName;
				} else tagExp = tagExp.substr(0, tagExp.length - 1);
				attrExpPresent = tagName !== tagExp;
			}
			let prefixedAttrs = null;
			let namespace = void 0;
			namespace = extractNamespace(rawTagName);
			if (tagName !== xmlObj.tagname) this.matcher.push(tagName, {}, namespace);
			if (tagName !== tagExp && attrExpPresent) {
				prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
				if (prefixedAttrs) extractRawAttributes(prefixedAttrs, options);
			}
			if (tagName !== xmlObj.tagname) this.isCurrentNodeStopNode = this.isItStopNode();
			const startIndex = i;
			if (this.isCurrentNodeStopNode) {
				let tagContent = "";
				if (isSelfClosing) i = result.closeIndex;
				else if (options.unpairedTagsSet.has(tagName)) i = result.closeIndex;
				else {
					const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
					if (!result) throw new Error(`Unexpected end of ${rawTagName}`);
					i = result.i;
					tagContent = result.tagContent;
				}
				const childNode = new XmlNode(tagName);
				if (prefixedAttrs) childNode[":@"] = prefixedAttrs;
				childNode.add(options.textNodeName, tagContent);
				this.matcher.pop();
				this.isCurrentNodeStopNode = false;
				this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
			} else {
				if (isSelfClosing) {
					({tagName, tagExp} = transformTagName(options.transformTagName, tagName, tagExp, options));
					const childNode = new XmlNode(tagName);
					if (prefixedAttrs) childNode[":@"] = prefixedAttrs;
					this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
					this.matcher.pop();
					this.isCurrentNodeStopNode = false;
				} else if (options.unpairedTagsSet.has(tagName)) {
					const childNode = new XmlNode(tagName);
					if (prefixedAttrs) childNode[":@"] = prefixedAttrs;
					this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
					this.matcher.pop();
					this.isCurrentNodeStopNode = false;
					i = result.closeIndex;
					continue;
				} else {
					const childNode = new XmlNode(tagName);
					if (this.tagsNodeStack.length > options.maxNestedTags) throw new Error("Maximum nested tags exceeded");
					this.tagsNodeStack.push(currentNode);
					if (prefixedAttrs) childNode[":@"] = prefixedAttrs;
					this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
					currentNode = childNode;
				}
				textData = "";
				i = closeIndex;
			}
		}
	} else textData += xmlData[i];
	return xmlObj.child;
};
function addChild(currentNode, childNode, matcher, startIndex) {
	if (!this.options.captureMetaData) startIndex = void 0;
	const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
	const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"]);
	if (result === false) {} else if (typeof result === "string") {
		childNode.tagname = result;
		currentNode.addChild(childNode, startIndex);
	} else currentNode.addChild(childNode, startIndex);
}
/**
* @param {object} val - Entity object with regex and val properties
* @param {string} tagName - Tag name
* @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath
*/
function replaceEntitiesValue(val, tagName, jPath) {
	const entityConfig = this.options.processEntities;
	if (!entityConfig || !entityConfig.enabled) return val;
	if (entityConfig.allowedTags) {
		const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
		if (!(Array.isArray(entityConfig.allowedTags) ? entityConfig.allowedTags.includes(tagName) : entityConfig.allowedTags(tagName, jPathOrMatcher))) return val;
	}
	if (entityConfig.tagFilter) {
		const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
		if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) return val;
	}
	return this.entityDecoder.decode(val);
}
function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
	if (textData) {
		if (isLeafNode === void 0) isLeafNode = parentNode.child.length === 0;
		textData = this.parseTextData(textData, parentNode.tagname, matcher, false, parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false, isLeafNode);
		if (textData !== void 0 && textData !== "") parentNode.add(this.options.textNodeName, textData);
		textData = "";
	}
	return textData;
}
/**
* @param {Array<Expression>} stopNodeExpressions - Array of compiled Expression objects
* @param {Matcher} matcher - Current path matcher
*/
function isItStopNode() {
	if (this.stopNodeExpressionsSet.size === 0) return false;
	return this.matcher.matchesAny(this.stopNodeExpressionsSet);
}
/**
* Returns the tag Expression and where it is ending handling single-double quotes situation
* @param {string} xmlData 
* @param {number} i starting index
* @returns 
*/
function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
	let attrBoundary = 0;
	const len = xmlData.length;
	const closeCode0 = closingChar.charCodeAt(0);
	const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;
	let result = "";
	let segmentStart = i;
	for (let index = i; index < len; index++) {
		const code = xmlData.charCodeAt(index);
		if (attrBoundary) {
			if (code === attrBoundary) attrBoundary = 0;
		} else if (code === 34 || code === 39) attrBoundary = code;
		else if (code === closeCode0) if (closeCode1 !== -1) {
			if (xmlData.charCodeAt(index + 1) === closeCode1) {
				result += xmlData.substring(segmentStart, index);
				return {
					data: result,
					index
				};
			}
		} else {
			result += xmlData.substring(segmentStart, index);
			return {
				data: result,
				index
			};
		}
		else if (code === 9 && !attrBoundary) {
			result += xmlData.substring(segmentStart, index) + " ";
			segmentStart = index + 1;
		}
	}
}
function findClosingIndex(xmlData, str, i, errMsg) {
	const closingIndex = xmlData.indexOf(str, i);
	if (closingIndex === -1) throw new Error(errMsg);
	else return closingIndex + str.length - 1;
}
function findClosingChar(xmlData, char, i, errMsg) {
	const closingIndex = xmlData.indexOf(char, i);
	if (closingIndex === -1) throw new Error(errMsg);
	return closingIndex;
}
function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") {
	const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);
	if (!result) return;
	let tagExp = result.data;
	const closeIndex = result.index;
	const separatorIndex = tagExp.search(/\s/);
	let tagName = tagExp;
	let attrExpPresent = true;
	if (separatorIndex !== -1) {
		tagName = tagExp.substring(0, separatorIndex);
		tagExp = tagExp.substring(separatorIndex + 1).trimStart();
	}
	const rawTagName = tagName;
	if (removeNSPrefix) {
		const colonIndex = tagName.indexOf(":");
		if (colonIndex !== -1) {
			tagName = tagName.substr(colonIndex + 1);
			attrExpPresent = tagName !== result.data.substr(colonIndex + 1);
		}
	}
	return {
		tagName,
		tagExp,
		closeIndex,
		attrExpPresent,
		rawTagName
	};
}
/**
* find paired tag for a stop node
* @param {string} xmlData 
* @param {string} tagName 
* @param {number} i 
*/
function readStopNodeData(xmlData, tagName, i) {
	const startIndex = i;
	let openTagCount = 1;
	const xmllen = xmlData.length;
	for (; i < xmllen; i++) if (xmlData[i] === "<") {
		const c1 = xmlData.charCodeAt(i + 1);
		if (c1 === 47) {
			const closeIndex = findClosingChar(xmlData, ">", i, `${tagName} is not closed`);
			if (xmlData.substring(i + 2, closeIndex).trim() === tagName) {
				openTagCount--;
				if (openTagCount === 0) return {
					tagContent: xmlData.substring(startIndex, i),
					i: closeIndex
				};
			}
			i = closeIndex;
		} else if (c1 === 63) i = findClosingIndex(xmlData, "?>", i + 1, "StopNode is not closed.");
		else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) i = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed.");
		else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) i = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
		else {
			const tagData = readTagExp(xmlData, i, false);
			if (tagData) {
				if ((tagData && tagData.tagName) === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== "/") openTagCount++;
				i = tagData.closeIndex;
			}
		}
	}
}
function parseValue(val, shouldParse, options) {
	if (shouldParse && typeof val === "string") {
		const newval = val.trim();
		if (newval === "true") return true;
		else if (newval === "false") return false;
		else return toNumber(val, options);
	} else if (isExist(val)) return val;
	else return "";
}
function transformTagName(fn, tagName, tagExp, options) {
	if (fn) {
		const newTagName = fn(tagName);
		if (tagExp === tagName) tagExp = newTagName;
		tagName = newTagName;
	}
	tagName = sanitizeName(tagName, options);
	return {
		tagName,
		tagExp
	};
}
function sanitizeName(name, options) {
	if (criticalProperties.includes(name)) throw new Error(`[SECURITY] Invalid name: "${name}" is a reserved JavaScript keyword that could cause prototype pollution`);
	else if (DANGEROUS_PROPERTY_NAMES.includes(name)) return options.onDangerousProperty(name);
	return name;
}
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/node2json.js
var METADATA_SYMBOL = XmlNode.getMetaDataSymbol();
/**
* Helper function to strip attribute prefix from attribute map
* @param {object} attrs - Attributes with prefix (e.g., {"@_class": "code"})
* @param {string} prefix - Attribute prefix to remove (e.g., "@_")
* @returns {object} Attributes without prefix (e.g., {"class": "code"})
*/
function stripAttributePrefix(attrs, prefix) {
	if (!attrs || typeof attrs !== "object") return {};
	if (!prefix) return attrs;
	const rawAttrs = {};
	for (const key in attrs) if (key.startsWith(prefix)) {
		const rawName = key.substring(prefix.length);
		rawAttrs[rawName] = attrs[key];
	} else rawAttrs[key] = attrs[key];
	return rawAttrs;
}
/**
* 
* @param {array} node 
* @param {any} options 
* @param {Matcher} matcher - Path matcher instance
* @returns 
*/
function prettify(node, options, matcher, readonlyMatcher) {
	return compress(node, options, matcher, readonlyMatcher);
}
/**
* @param {array} arr 
* @param {object} options 
* @param {Matcher} matcher - Path matcher instance
* @returns object
*/
function compress(arr, options, matcher, readonlyMatcher) {
	let text;
	const compressedObj = {};
	for (let i = 0; i < arr.length; i++) {
		const tagObj = arr[i];
		const property = propName(tagObj);
		if (property !== void 0 && property !== options.textNodeName) {
			const rawAttrs = stripAttributePrefix(tagObj[":@"] || {}, options.attributeNamePrefix);
			matcher.push(property, rawAttrs);
		}
		if (property === options.textNodeName) if (text === void 0) text = tagObj[property];
		else text += "" + tagObj[property];
		else if (property === void 0) continue;
		else if (tagObj[property]) {
			let val = compress(tagObj[property], options, matcher, readonlyMatcher);
			const isLeaf = isLeafTag(val, options);
			if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) val[options.textNodeName] = "";
			if (tagObj[":@"]) assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
			else if (Object.keys(val).length === 1 && val[options.textNodeName] !== void 0 && !options.alwaysCreateTextNode) val = val[options.textNodeName];
			else if (Object.keys(val).length === 0) if (options.alwaysCreateTextNode) val[options.textNodeName] = "";
			else val = "";
			if (tagObj[METADATA_SYMBOL] !== void 0 && typeof val === "object" && val !== null) val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL];
			if (compressedObj[property] !== void 0 && Object.prototype.hasOwnProperty.call(compressedObj, property)) {
				if (!Array.isArray(compressedObj[property])) compressedObj[property] = [compressedObj[property]];
				compressedObj[property].push(val);
			} else {
				const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;
				if (options.isArray(property, jPathOrMatcher, isLeaf)) compressedObj[property] = [val];
				else compressedObj[property] = val;
			}
			if (property !== void 0 && property !== options.textNodeName) matcher.pop();
		}
	}
	if (typeof text === "string") {
		if (text.length > 0) compressedObj[options.textNodeName] = text;
	} else if (text !== void 0) compressedObj[options.textNodeName] = text;
	return compressedObj;
}
function propName(obj) {
	const keys = Object.keys(obj);
	for (let i = 0; i < keys.length; i++) {
		const key = keys[i];
		if (key !== ":@") return key;
	}
}
function assignAttributes(obj, attrMap, readonlyMatcher, options) {
	if (attrMap) {
		const keys = Object.keys(attrMap);
		const len = keys.length;
		for (let i = 0; i < len; i++) {
			const atrrName = keys[i];
			const rawAttrName = atrrName.startsWith(options.attributeNamePrefix) ? atrrName.substring(options.attributeNamePrefix.length) : atrrName;
			const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() + "." + rawAttrName : readonlyMatcher;
			if (options.isArray(atrrName, jPathOrMatcher, true, true)) obj[atrrName] = [attrMap[atrrName]];
			else obj[atrrName] = attrMap[atrrName];
		}
	}
}
function isLeafTag(obj, options) {
	const { textNodeName } = options;
	const propCount = Object.keys(obj).length;
	if (propCount === 0) return true;
	if (propCount === 1 && (obj[textNodeName] || typeof obj[textNodeName] === "boolean" || obj[textNodeName] === 0)) return true;
	return false;
}
//#endregion
//#region node_modules/fast-xml-parser/src/xmlparser/XMLParser.js
var XMLParser = class {
	constructor(options) {
		this.externalEntities = {};
		this.options = buildOptions(options);
	}
	/**
	* Parse XML dats to JS object 
	* @param {string|Uint8Array} xmlData 
	* @param {boolean|Object} validationOption 
	*/
	parse(xmlData, validationOption) {
		if (typeof xmlData !== "string" && xmlData.toString) xmlData = xmlData.toString();
		else if (typeof xmlData !== "string") throw new Error("XML data is accepted in String or Bytes[] form.");
		if (validationOption) {
			if (validationOption === true) validationOption = {};
			const result = validate(xmlData, validationOption);
			if (result !== true) throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`);
		}
		const orderedObjParser = new OrderedObjParser(this.options, this.externalEntities);
		const orderedResult = orderedObjParser.parseXml(xmlData);
		if (this.options.preserveOrder || orderedResult === void 0) return orderedResult;
		else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);
	}
	/**
	* Add Entity which is not by default supported by this library
	* @param {string} key 
	* @param {string} value 
	*/
	addEntity(key, value) {
		if (value.indexOf("&") !== -1) throw new Error("Entity value can't have '&'");
		else if (key.indexOf("&") !== -1 || key.indexOf(";") !== -1) throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '&#xD;'");
		else if (value === "&") throw new Error("An entity with value '&' is not permitted");
		else this.externalEntities[key] = value;
	}
	/**
	* Returns a Symbol that can be used to access the metadata
	* property on a node.
	* 
	* If Symbol is not available in the environment, an ordinary property is used
	* and the name of the property is here returned.
	* 
	* The XMLMetaData property is only present when `captureMetaData`
	* is true in the options.
	*/
	static getMetaDataSymbol() {
		return XmlNode.getMetaDataSymbol();
	}
};
//#endregion
//#region src/ntqqapi/helper/forwardMsg.ts
/**
* 把收到的消息 elements 转成可再次发送的 SendMessageElement[] (转发/re-send 用).
* 图片/视频/语音需重新下载再上传; ark/reply/marketFace 直接透传; 嵌套合并转发重建 multimsg ark 卡片.
* 返回 deleteAfterSentFiles: 非本地的临时下载文件, 发送后需清理.
* 从 onebot11 ForwardSingleMsg 提取, 供 OB11 action 与 WebQQ 转发路由共用.
*/
async function rawElementsToSend(ctx, elements, fromPeer) {
	const isGroup = fromPeer.chatType === ChatType.Group;
	const out = [];
	const deleteAfterSentFiles = [];
	const fetchFile = async (url) => {
		const res = await uri2local(ctx, url);
		if (!res.success) {
			ctx.logger.error(res.errMsg);
			throw new Error(res.errMsg);
		}
		if (!res.isLocal) deleteAfterSentFiles.push(res.path);
		return res.path;
	};
	for (const e of elements) if (e.textElement) out.push(e);
	else if (e.faceElement) out.push(e);
	else if (e.picElement) {
		const path = await fetchFile(await ctx.ntFileApi.getImageUrl(e.picElement.originImageUrl, e.picElement.md5HexStr));
		out.push(await SendElement.pic(ctx, path));
	} else if (e.videoElement) {
		const path = await fetchFile(await ctx.ntFileApi.getVideoUrl(e.videoElement.fileUuid, isGroup));
		out.push(await SendElement.video(ctx, path));
	} else if (e.pttElement) {
		const path = await fetchFile(await ctx.ntFileApi.getPttUrl(e.pttElement.fileUuid, isGroup));
		out.push(await SendElement.ptt(ctx, path));
	} else if (e.fileElement) {
		const { url } = await ctx.ntFileApi.getFileUrl(e.fileElement.fileUuid, isGroup, isGroup ? +fromPeer.peerUid : void 0);
		const path = await fetchFile(url);
		out.push(await SendElement.file(ctx, path, e.fileElement.fileName));
	} else if (e.arkElement) out.push(e);
	else if (e.replyElement) out.push(e);
	else if (e.marketFaceElement) out.push(e);
	else if (e.multiForwardMsgElement) {
		const content = new XMLParser().parse(e.multiForwardMsgElement.xmlContent);
		const uuid = e.multiForwardMsgElement.fileName;
		const prompt = e.multiForwardMsgElement.xmlContent.match(/brief="([^"]*)"/)?.[1] ?? "[聊天记录]";
		const json = JSON.stringify({
			app: "com.tencent.multimsg",
			config: {
				autosize: 1,
				forward: 1,
				round: 1,
				type: "normal",
				width: 300
			},
			desc: prompt,
			extra: JSON.stringify({
				filename: uuid,
				tsum: 0
			}),
			meta: { detail: {
				news: content.msg.item.title.slice(1).map((e) => ({ text: e })),
				resid: e.multiForwardMsgElement.resId,
				source: content.msg.item.title[0],
				summary: content.msg.item.summary,
				uniseq: uuid
			} },
			prompt,
			ver: "0.0.0.5",
			view: "contact"
		});
		out.push(SendElement.ark(json));
	}
	return {
		elements: out,
		deleteAfterSentFiles
	};
}
//#endregion
//#region src/onebot11/action/llbot/msg/ForwardSingleMsg.ts
var ForwardSingleMsg = class extends BaseAction {
	payloadSchema = lib_default$1.object({
		message_id: lib_default$1.union([Number, String]).required(),
		group_id: lib_default$1.union([Number, String]),
		user_id: lib_default$1.union([Number, String])
	});
	async _handle(payload) {
		const info = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!info) throw new Error(`无法找到消息${payload.message_id}`);
		let msg = this.ctx.store.getMsgByMsgId(info.msgId);
		if (!msg) msg = (await this.ctx.ntMsgApi.getSingleMsg(info.peer, info.msgSeq)).msgList[0];
		if (!msg) throw new Error(`无法找到消息内容${payload.message_id}`);
		const { elements, deleteAfterSentFiles } = await rawElementsToSend(this.ctx, msg.elements, info.peer);
		const peer = await createPeer(this.ctx, payload);
		const ret = await this.ctx.app.sendMessage(this.ctx, peer, elements, deleteAfterSentFiles);
		return { message_id: this.ctx.store.createMsgShortId(ret) };
	}
};
var ForwardFriendSingleMsg = class extends ForwardSingleMsg {
	actionName = ActionName.ForwardFriendSingleMsg;
};
var ForwardGroupSingleMsg = class extends ForwardSingleMsg {
	actionName = ActionName.ForwardGroupSingleMsg;
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupEssence.ts
var GetEssenceMsgList = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetEssenceMsgList;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const groupCode = payload.group_id.toString();
		const peer = {
			guildId: "",
			chatType: ChatType.Group,
			peerUid: groupCode
		};
		const result = await this.ctx.ntWebApi.getGroupEssenceList(+payload.group_id);
		if (result.retcode !== 0) throw new Error(result.retmsg);
		const data = [];
		for (const item of result.data.msg_list) {
			let msg = this.ctx.store.getMsgBySeq(peer.peerUid, item.msg_seq);
			if (!msg) {
				const { msgList } = await this.ctx.ntMsgApi.getSingleMsg(peer, item.msg_seq);
				msg = msgList[0];
			}
			if (!msg) continue;
			data.push({
				sender_id: +item.sender_uin,
				sender_nick: item.sender_nick,
				sender_time: +msg.msgTime,
				operator_id: +item.add_digest_uin,
				operator_nick: item.add_digest_nick,
				operator_time: item.add_digest_time,
				message_id: this.ctx.store.createMsgShortId(msg)
			});
		}
		return data;
	}
};
//#endregion
//#region src/onebot11/action/group/GetGroupHonorInfo.ts
var GetGroupHonorInfo = class extends BaseAction {
	actionName = ActionName.GetGroupHonorInfo;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		type: lib_default$1.union([
			"talkative",
			"performer",
			"legend",
			"strong_newbie",
			"emotion",
			"all"
		]).default("all")
	});
	async _handle(payload) {
		const groupCode = +payload.group_id;
		const pSkey = (await this.ctx.ntUserApi.getPSkey(["qun.qq.com"])).get("qun.qq.com");
		const ret = { group_id: groupCode };
		let talkative, performer, legend, emotion;
		if (payload.type === "all") {
			const resps = await Promise.all([
				this.ctx.ntWebApi.getGroupHonorTalkative(groupCode, pSkey),
				this.ctx.ntWebApi.getGroupHonorContinuous(groupCode, 2, pSkey),
				this.ctx.ntWebApi.getGroupHonorContinuous(groupCode, 3, pSkey),
				this.ctx.ntWebApi.getGroupHonorEmotion(groupCode, pSkey)
			]);
			talkative = resps[0];
			performer = resps[1];
			legend = resps[2];
			emotion = resps[3];
		}
		if (payload.type === "talkative" || payload.type === "all") {
			const resp = talkative ?? await this.ctx.ntWebApi.getGroupHonorTalkative(groupCode, pSkey);
			if (resp.retcode !== 0) throw new Error(resp.msg);
			const { data } = resp;
			if (data.current_talkative) ret.current_talkative = {
				user_id: data.current_talkative.uin,
				nickname: data.current_talkative.nick,
				avatar: data.current_talkative.avatar,
				day_count: data.current_talkative.day_count
			};
			ret.talkative_list = data.talkative_list.map((t) => ({
				user_id: t.uin,
				nickname: t.nick,
				avatar: t.avatar,
				description: `${t.day_count_history}天，最长蝉联${t.day_count_max}天`
			}));
		}
		if (payload.type === "performer" || payload.type === "all") {
			const resp = performer ?? await this.ctx.ntWebApi.getGroupHonorContinuous(groupCode, 2, pSkey);
			if (resp.retcode !== 0) throw new Error(resp.msg);
			const { data } = resp;
			ret.performer_list = data.continuous_list.map((c) => ({
				user_id: c.uin,
				nickname: c.nick,
				avatar: c.avatar,
				description: `连续发消息${c.day_count}天`
			}));
		}
		if (payload.type === "legend" || payload.type === "all") {
			const resp = legend ?? await this.ctx.ntWebApi.getGroupHonorContinuous(groupCode, 3, pSkey);
			if (resp.retcode !== 0) throw new Error(resp.msg);
			const { data } = resp;
			ret.legend_list = data.continuous_list.map((c) => ({
				user_id: c.uin,
				nickname: c.nick,
				avatar: c.avatar,
				description: `连续发消息${c.day_count}天`
			}));
		}
		if (payload.type === "strong_newbie" || payload.type === "all") ret.strong_newbie_list = [];
		if (payload.type === "emotion" || payload.type === "all") {
			const resp = emotion ?? await this.ctx.ntWebApi.getGroupHonorEmotion(groupCode, pSkey);
			if (resp.retcode !== 0) throw new Error(resp.msg);
			const { data } = resp;
			ret.emotion_list = data.emotion_list.map((e) => ({
				user_id: e.uin,
				nickname: e.nick,
				avatar: e.avatar,
				description: `已连续发送表情包${e.day_count}天`
			}));
		}
		return ret;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/QuickOperation.ts
var HandleQuickOperation = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_HandleQuickOperation;
	payloadSchema = lib_default$1.object({
		context: lib_default$1.any().required(),
		operation: lib_default$1.any().required()
	});
	async _handle(payload) {
		handleQuickOperation(this.ctx, payload.context, payload.operation).catch((e) => this.ctx.logger.error(e));
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SetEssenceMsg.ts
var SetEssenceMsg = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SetEssenceMsg;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const info = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!info) throw new Error("msg not found");
		const res = await this.ctx.ntGroupApi.addGroupEssence(+info.peer.peerUid, info.msgSeq, Number(BigInt(info.msgId) & 4294967295n));
		if (res.retCode !== 0) throw new Error(res.retMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/DeleteEssenceMsg.ts
var DeleteEssenceMsg = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_DeleteEssenceMsg;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const info = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!info) throw new Error("msg not found");
		const res = await this.ctx.ntGroupApi.removeGroupEssence(+info.peer.peerUid, info.msgSeq, Number(BigInt(info.msgId) & 4294967295n));
		if (res.retCode !== 0) throw new Error(res.retMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/GetEvent.ts
var GetEvent = class extends BaseAction {
	actionName = ActionName.GetEvent;
	payloadSchema = lib_default$1.object({
		key: lib_default$1.string(),
		timeout: lib_default$1.union([Number, String])
	});
	async _handle(payload) {
		let key = "";
		if (payload.key) key = payload.key;
		const timeout = +payload.timeout?.toString() || 0;
		return await getHttpEvent(key, timeout);
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/DeleteGroupFile.ts
var DeleteGroupFile$1 = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_DeleteGroupFile;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file_id: lib_default$1.string().required(),
		busid: lib_default$1.union([Number, String]).default(102)
	});
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.deleteGroupFile(+payload.group_id, payload.file_id, +payload.busid);
		if (res.retCode !== 0) throw new Error(res.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupSystemMsg.ts
var GetGroupSystemMsg = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupSystemMsg;
	async _handle() {
		let notifications;
		notifications = (await this.ctx.ntGroupApi.getGroupNotifications(false, 50)).notifications;
		const doubt = await this.ctx.ntGroupApi.getGroupNotifications(true, 50);
		notifications.push(...doubt.notifications);
		const data = {
			invited_requests: [],
			join_requests: []
		};
		for (const n of notifications) if (n.type === GroupNotificationType.Invitation) data.invited_requests.push({
			request_id: n.sequence,
			invitor_uin: await this.ctx.ntUserApi.getUinByUid(n.user2.uid),
			invitor_nick: n.user2.nickName,
			group_id: n.group.groupCode,
			group_name: n.group.groupName,
			checked: n.requestState !== RequestState.Unhandle,
			actor: n.user3?.uid ? await this.ctx.ntUserApi.getUinByUid(n.user3.uid) : 0
		});
		else if (n.type === GroupNotificationType.JoinRequest) data.join_requests.push({
			request_id: n.sequence,
			requester_uin: await this.ctx.ntUserApi.getUinByUid(n.user1.uid),
			requester_nick: n.user1.nickName,
			message: n.comment ?? "",
			group_id: n.group.groupCode,
			group_name: n.group.groupName,
			checked: n.requestState !== RequestState.Unhandle,
			actor: n.user2?.uid ? await this.ctx.ntUserApi.getUinByUid(n.user2.uid) : 0
		});
		return data;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/CreateGroupFileFolder.ts
var CreateGroupFileFolder = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_CreateGroupFileFolder;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		name: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.createGroupFolder(+payload.group_id, payload.name);
		if (result.retCode !== 0) throw new Error(result.clientWording);
		return { folder_id: result.folderInfo.folderId };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/DeleteGroupFolder.ts
var DeleteGroupFolder$1 = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_DeleteGroupFolder;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		folder_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.deleteGroupFolder(+payload.group_id, payload.folder_id);
		if (result.retCode !== 0) throw new Error(result.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupAtAllRemain.ts
var GetGroupAtAllRemain = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupAtAllRemain;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const data = await this.ctx.ntGroupApi.getGroupRemainAtTimes(+payload.group_id);
		return {
			can_at_all: data.canAtAll,
			remain_at_all_count_for_group: data.remainAtAllCountForGroup,
			remain_at_all_count_for_uin: data.remainAtAllCountForUin
		};
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupRootFiles.ts
var GetGroupRootFiles = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupRootFiles;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const groupId = +payload.group_id;
		const data = [];
		let nextIndex;
		while (nextIndex !== 0) {
			const res = await this.ctx.ntGroupApi.getGroupFileList(groupId, "/", nextIndex ?? 0, 100);
			if (res.retCode !== 0) throw new Error(res.clientWording);
			data.push(...res.items);
			nextIndex = res.nextIndex;
		}
		return {
			files: data.filter((item) => item.fileInfo).map((item) => {
				const file = item.fileInfo;
				return {
					group_id: groupId,
					file_id: file.fileId,
					file_name: file.fileName,
					busid: file.busId,
					file_size: file.fileSize,
					upload_time: file.uploadedTime,
					dead_time: file.expireTime,
					modify_time: file.modifiedTime,
					download_times: file.downloadedTimes,
					uploader: file.uploaderUin,
					uploader_name: file.uploaderName
				};
			}),
			folders: data.filter((item) => item.folderInfo).map((item) => {
				const folder = item.folderInfo;
				return {
					group_id: groupId,
					folder_id: folder.folderId,
					folder_name: folder.folderName,
					create_time: folder.createTime,
					creator: folder.createUin,
					creator_name: folder.creatorName,
					total_file_count: folder.totalFileCount,
					modify_time: folder.modifyTime,
					modifier: folder.modifyUin,
					modifier_name: folder.modifyName
				};
			})
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetOnlineStatus.ts
var SetOnlineStatus = class extends BaseAction {
	actionName = ActionName.SetOnlineStatus;
	payloadSchema = lib_default$1.object({
		status: lib_default$1.union([Number, String]).required(),
		ext_status: lib_default$1.union([Number, String]).required(),
		battery_status: lib_default$1.union([Number, String]).required()
	});
	async _handle(payload) {
		const ret = await this.ctx.ntUserApi.setSelfStatus(Number(payload.status), Number(payload.ext_status), Number(payload.battery_status));
		if (ret.retCode !== 0) throw new Error(ret.message);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SendGroupNotice.ts
var SendGroupNotice = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SendGroupNotice;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		content: lib_default$1.string().required(),
		image: lib_default$1.string(),
		pinned: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false),
		confirm_required: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(true),
		is_show_edit_card: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false),
		tip_window: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false),
		send_new_member: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async _handle(payload) {
		let picInfo;
		if (payload.image) {
			const { path, isLocal, success, errMsg } = await uri2local(this.ctx, payload.image, true);
			if (!success) throw new Error(`获取图片文件失败, 错误信息: ${errMsg}`);
			const result = await this.ctx.ntWebApi.uploadGroupBulletinPic(+payload.group_id, path);
			if (result.errCode !== 0) throw new Error(`上传群公告图片失败, 错误信息: ${result.errMsg}`);
			if (!isLocal) unlink$1(path).catch(noop);
			picInfo = result.picInfo;
		}
		const res = await this.ctx.ntWebApi.publishGroupBulletin(+payload.group_id, payload.content, +payload.pinned, payload.send_new_member ? 20 : 1, +payload.is_show_edit_card, +!payload.tip_window, +payload.confirm_required, picInfo?.id, picInfo?.width, picInfo?.height);
		if (res.ec !== 0) throw new Error(`设置群公告失败, 错误信息: ${res.em}`);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetProfileLikeMe.ts
var GetProfileLikeMe = class extends BaseAction {
	actionName = ActionName.GetProfileLikeMe;
	payloadSchema = lib_default$1.object({
		start: lib_default$1.union([Number, String]).default(0),
		count: lib_default$1.union([Number, String]).default(20)
	});
	async _handle(payload) {
		const ret = await this.ctx.ntUserApi.getProfileLikeMe(selfInfo.uid, +payload.start, +payload.count);
		const users = ret.userLikeInfo.voteInfo.users ?? [];
		for (const item of users) Object.assign(item, {
			uin: await this.ctx.ntUserApi.getUinByUid(item.uid),
			isFriend: await this.ctx.ntFriendApi.isFriend(item.uid)
		});
		return {
			users,
			nextStart: ret.start
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/FetchEmojiLike.ts
var FetchEmojiLike = class extends BaseAction {
	actionName = ActionName.FetchEmojiLike;
	payloadSchema = lib_default$1.object({
		message_id: lib_default$1.union([Number, String]).required(),
		emoji_id: lib_default$1.union([Number, String]),
		emojiId: lib_default$1.union([Number, String]),
		count: lib_default$1.union([Number, String]).default(20),
		cookie: lib_default$1.string()
	});
	async _handle(payload) {
		const msgInfo = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!msgInfo) throw new Error("消息不存在");
		const emojiId = payload.emoji_id ?? payload.emojiId;
		if (!emojiId) throw new Error("未指定表情 ID");
		const result = await this.ctx.ntMsgApi.getMsgReactionList(msgInfo.peer, msgInfo.msgSeq, emojiId.toString(), +payload.count, payload.cookie ?? "");
		return {
			emojiLikesList: result.users.map((u) => ({
				tinyId: u.uin.toString(),
				nickName: "",
				headUrl: `https://q1.qlogo.cn/g?b=qq&nk=${u.uin}&s=640`
			})),
			cookie: result.cookie,
			isLastPage: result.isLastPage,
			isFirstPage: result.isFirstPage
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/FetchCustomFace.ts
var FetchCustomFace = class extends BaseAction {
	actionName = ActionName.FetchCustomFace;
	async _handle(payload) {
		const ret = await this.ctx.ntMsgApi.getCustomFaceList();
		if (ret.retCode !== 0) throw new Error(ret.errMsg);
		return ret.emojiInfoList.map((e) => e.url);
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/GetFriendMsgHistory.ts
var GetFriendMsgHistory = class extends BaseAction {
	actionName = ActionName.GetFriendMsgHistory;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		message_seq: lib_default$1.union([Number, String]),
		count: lib_default$1.union([Number, String]).default(20),
		reverseOrder: lib_default$1.union([Boolean, lib_default$1.transform(String, parseBool)]).default(false)
	});
	async fetchRangeRaw(peer, startSeq, endSeq) {
		return (await this.ctx.ntMsgApi.getMsgsBySeqAndCount(peer, endSeq, endSeq - startSeq + 1, true)).msgList;
	}
	async _handle(payload, config) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error(`无法获取用户信息`);
		const peer = {
			chatType: await this.ctx.ntFriendApi.isFriend(uid) ? ChatType.C2C : ChatType.TempC2CFromGroup,
			peerUid: uid
		};
		const count = +payload.count;
		if (count === 0) return { messages: [] };
		const endSeq = payload.message_seq && +payload.message_seq > 0 ? +payload.message_seq : await this.ctx.ntMsgApi.getLatestMsgSeq(peer);
		const overallStartSeq = Math.max(1, endSeq - count + 1);
		const windows = [];
		for (let cur = endSeq; cur >= overallStartSeq; cur -= 30) {
			const start = Math.max(overallStartSeq, cur - 30 + 1);
			windows.push({
				start,
				end: cur
			});
		}
		const rawBatches = await mapWithConcurrency(windows, 5, (w) => this.fetchRangeRaw(peer, w.start, w.end), (r) => r.length === 0);
		const firstEmpty = rawBatches.findIndex((r) => r.length === 0);
		const validBatches = firstEmpty === -1 ? rawBatches : rawBatches.slice(0, firstEmpty);
		validBatches.reverse();
		const flatRaw = validBatches.flat();
		if (firstEmpty === -1 && flatRaw.length < count) {
			let remaining = count - flatRaw.length;
			let nextEndSeq = windows.at(-1).start - 1;
			while (remaining > 0 && nextEndSeq >= 1) {
				const startSeq = Math.max(1, nextEndSeq - Math.min(30, remaining) + 1);
				const batch = await this.fetchRangeRaw(peer, startSeq, nextEndSeq);
				if (batch.length === 0) break;
				flatRaw.unshift(...batch);
				remaining -= batch.length;
				nextEndSeq = startSeq - 1;
			}
		}
		const messages = await Promise.all(flatRaw.map((msg) => OB11Entities.message(this.ctx, msg, config)));
		if (payload.reverseOrder) messages.reverse();
		return { messages };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupFilesByFolder.ts
var GetGroupFilesByFolder = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupFilesByFolder;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		folder_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const groupId = +payload.group_id;
		const data = [];
		let nextIndex;
		while (nextIndex !== 0) {
			const res = await this.ctx.ntGroupApi.getGroupFileList(groupId, payload.folder_id, nextIndex ?? 0, 100);
			if (res.retCode !== 0) throw new Error(res.clientWording);
			data.push(...res.items);
			nextIndex = res.nextIndex;
		}
		return {
			files: data.filter((item) => item.fileInfo).map((item) => {
				const file = item.fileInfo;
				return {
					group_id: groupId,
					file_id: file.fileId,
					file_name: file.fileName,
					busid: file.busId,
					file_size: file.fileSize,
					upload_time: file.uploadedTime,
					dead_time: file.expireTime,
					modify_time: file.modifiedTime,
					download_times: file.downloadedTimes,
					uploader: file.uploaderUin,
					uploader_name: file.uploaderName
				};
			}),
			folders: []
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetFriendWithCategory.ts
var GetFriendWithCategory = class extends BaseAction {
	actionName = ActionName.GetFriendsWithCategory;
	async _handle() {
		const result = await this.ctx.ntFriendApi.getFriends(true);
		const status = await this.ctx.ntFriendApi.getFriendsStatus();
		return result.categories.values().map((item) => {
			const buddy = result.friends.filter((friend) => friend.categoryId === item.categoryId);
			return {
				categoryId: item.categoryId,
				categorySortId: item.categorySortId,
				categoryName: item.categoryName,
				categoryMbCount: item.categoryMemberCount,
				onlineCount: buddy.filter((friend) => status.find((e) => e.uid === friend.uid)?.status !== 20).length,
				buddyList: buddy.map((friend) => {
					return OB11Entities.friend(friend);
				})
			};
		}).toArray();
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/UploadGroupFile.ts
var UploadGroupFile$1 = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_UploadGroupFile;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file: lib_default$1.string().required(),
		name: lib_default$1.string(),
		folder: lib_default$1.string(),
		folder_id: lib_default$1.string()
	});
	async _handle(payload) {
		const { success, errMsg, path, fileName, isLocal } = await uri2local(this.ctx, payload.file);
		if (!success) throw new Error(errMsg);
		const name = payload.name || fileName;
		if (name.includes("/") || name.includes("\\")) throw new Error(`文件名 ${name} 不合法`);
		const info = await this.ctx.ntFileApi.uploadGroupFile(+payload.group_id, path, name, payload.folder ?? payload.folder_id);
		if (!isLocal) unlink(path).catch(noop);
		const result = await this.ctx.ntMsgApi.sendGroupFileMessage(+payload.group_id, info.fileId, info.busId);
		if (result.retCode !== 0) throw new Error(result.clientWording);
		return { file_id: info.fileId };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/UploadPrivateFile.ts
var UploadPrivateFile$1 = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_UploadPrivateFile;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		file: lib_default$1.string().required(),
		name: lib_default$1.string()
	});
	async _handle(payload) {
		const { success, errMsg, path, fileName, isLocal } = await uri2local(this.ctx, payload.file);
		if (!success) throw new Error(errMsg);
		const name = payload.name || fileName;
		if (name.includes("/") || name.includes("\\")) throw new Error(`文件名 ${name} 不合法`);
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取用户信息");
		const info = await this.ctx.ntFileApi.uploadPrivateFile(ChatType.C2C, uid, path, name);
		if (!isLocal) unlink(path).catch(noop);
		const result = await this.ctx.ntMsgApi.sendPrivateFileMessage({
			toUin: +payload.user_id,
			toUid: uid,
			fileUuid: info.fileId,
			fileName: name,
			fileSize: info.fileSize,
			file10MMd5: info.file10MMd5,
			crcMedia: info.crcMedia
		});
		if (result.resultCode !== 0) throw new Error(result.errMsg ?? "");
		return { file_id: info.fileId };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupFileUrl.ts
var GetGroupFileUrl = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupFileUrl;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntFileApi.getFileUrl(payload.file_id, true, +payload.group_id);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		const file = await this.ctx.store.getFileCacheById(payload.file_id);
		if (file.length > 0) return { url: result.url + encodeURIComponent(file[0].fileName) };
		else return { url: result.url };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupNotice.ts
var GetGroupNotice = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupNotice;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const data = await this.ctx.ntWebApi.getGroupBulletinList(+payload.group_id);
		if (data.ec !== 0) throw new Error(data.em);
		const feeds = data.feeds ?? [];
		const inst = data.inst ?? [];
		const result = [];
		for (const feed of [...feeds, ...inst]) result.push({
			notice_id: feed.fid,
			sender_id: feed.u,
			publish_time: feed.pubt,
			message: {
				text: feed.msg.text,
				images: feed.msg.pics?.map((image) => {
					return {
						height: image.h,
						width: image.w,
						id: image.id
					};
				}) ?? []
			},
			settings: {
				is_show_edit_card: !!feed.settings.is_show_edit_card,
				tip_window: !feed.settings.tip_window_type,
				confirm_required: !!feed.settings.confirm_required,
				pinned: !!feed.pinned,
				send_new_member: feed.type === 20
			}
		});
		if (inst.length > 0) result.sort((a, b) => b.publish_time - a.publish_time);
		return result;
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/GetRobotUinRange.ts
var GetRobotUinRange = class extends BaseAction {
	actionName = ActionName.GetRobotUinRange;
	async _handle() {
		return [
			{
				minUin: "3328144510",
				maxUin: "3328144510"
			},
			{
				minUin: "2854196301",
				maxUin: "2854216399"
			},
			{
				minUin: "66600000",
				maxUin: "66600000"
			},
			{
				minUin: "3889000000",
				maxUin: "3889999999"
			},
			{
				minUin: "4010000000",
				maxUin: "4019999999"
			}
		];
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/DeleteFriend.ts
var DeleteFriend$1 = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_DeleteFriend;
	payloadSchema = lib_default$1.object({ user_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取用户信息");
		const result = await this.ctx.ntFriendApi.deleteFriend(uid);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/OCRImage.ts
var OCRImage = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_OCRImage;
	payloadSchema = lib_default$1.object({ image: lib_default$1.string().required() });
	async _handle(payload) {
		let url;
		if (isHttpUrl(payload.image)) url = payload.image;
		else {
			const cached = await this.ctx.store.getFileCacheByName(payload.image);
			if (cached?.[0]?.originImageUrl) url = await this.ctx.ntFileApi.getImageUrl(cached[0].originImageUrl, cached[0].md5HexStr);
			else {
				const { errMsg, isLocal, path, success } = await uri2local(this.ctx, payload.image);
				if (!success) throw new Error(errMsg);
				const size = await getImageSize(path);
				const result = await this.ctx.ntFileApi.uploadPrivateImage(ChatType.C2C, selfInfo.uid, path, size.width, size.height, "", 0);
				if (!isLocal) unlink(path).catch(noop);
				const msgInfoBytes = result.msgInfo instanceof Uint8Array || Buffer.isBuffer(result.msgInfo) ? Buffer.from(result.msgInfo) : null;
				if (!msgInfoBytes) throw new Error("uploadC2CImage 返回的 msgInfo 不是 bytes");
				const head = Media.MsgInfo.decode(msgInfoBytes).msgInfoBody?.[0];
				if (!head?.pic || !head.index) throw new Error("上传图片返回无效");
				url = await this.ctx.ntFileApi.getImageUrl(head.pic.urlPath + head.pic.ext.originalParam, head.index.info.md5HexStr);
			}
		}
		const result = await this.ctx.ntFileApi.ocrImage(url);
		if (result.retCode) throw new Error(result.wording);
		return {
			texts: result.ocrRspBody.textDetections.map((item) => ({
				text: item.detectedText,
				confidence: item.confidence,
				coordinates: item.polygon?.coordinates ?? []
			})),
			language: result.ocrRspBody.language
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupPoke.ts
var GroupPoke = class extends BaseAction {
	actionName = ActionName.GroupPoke;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.sendGroupNudge(+payload.group_id, +payload.user_id);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/FriendPoke.ts
var FriendPoke = class extends BaseAction {
	actionName = ActionName.FriendPoke;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		target_id: lib_default$1.union([Number, String])
	});
	async _handle(payload) {
		const isSelf = payload.target_id ? payload.target_id.toString() === selfInfo.uin : false;
		const result = await this.ctx.ntFriendApi.sendFriendNudge(+payload.user_id, isSelf);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/GetGroupFileSystemInfo.ts
var GetGroupFileSystemInfo = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_GetGroupFileSystemInfo;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const groupId = +payload.group_id;
		const [count, space] = await Promise.all([this.ctx.ntGroupApi.getGroupFileCount(groupId), this.ctx.ntGroupApi.getGroupFileSpace(groupId)]);
		return {
			file_count: count.fileCount,
			limit_count: count.limitCount,
			used_space: space.usedSpace,
			total_space: space.totalSpace
		};
	}
};
//#endregion
//#region src/onebot11/action/system/GetCredentials.ts
var GetCredentials = class extends BaseAction {
	actionName = ActionName.GetCredentials;
	payloadSchema = lib_default$1.object({ domain: lib_default$1.string().required() });
	async _handle(payload) {
		const cookiesObject = await this.ctx.ntWebApi.getCookies(payload.domain);
		return {
			cookies: Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join("; "),
			csrf_token: +(cookiesObject.skey ? this.ctx.ntWebApi.genBkn(cookiesObject.skey) : "")
		};
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SetGroupSpecialTitle.ts
var SetGroupSpecialTitle = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SetGroupSpecialTitle;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_id: lib_default$1.union([Number, String]).required(),
		special_title: lib_default$1.string().default("")
	});
	async _handle(payload) {
		const groupCode = +payload.group_id;
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id, groupCode);
		if (!uid) throw new Error(`用户信息获取失败`);
		const result = await this.ctx.ntGroupApi.setGroupMemberSpecialTitle(groupCode, uid, payload.special_title);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SendGroupSign.ts
var SendGroupSign = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SendGroupSign;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.groupClockIn(+payload.group_id);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/system/SetRestart.ts
var SetRestart = class extends BaseAction {
	actionName = ActionName.SetRestart;
	async _handle() {
		await this.ctx.ntSystemApi.restart();
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetFriendCategory.ts
var SetFriendCategory = class extends BaseAction {
	actionName = ActionName.SetFriendCategory;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		category_id: lib_default$1.union([Number, String]).required()
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取好友信息");
		const result = await this.ctx.ntFriendApi.setFriendCategory(uid, +payload.category_id);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetFriendRemark.ts
var SetFriendRemark = class extends BaseAction {
	actionName = ActionName.SetFriendRemark;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		remark: lib_default$1.string().default("")
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取好友信息");
		const result = await this.ctx.ntFriendApi.setFriendRemark(uid, payload.remark);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/SetGroupMsgMask.ts
var SetGroupMsgMask = class extends BaseAction {
	actionName = ActionName.SetGroupMsgMask;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		mask: lib_default$1.union([Number, String]).required()
	});
	async _handle(payload) {
		if ((await this.ctx.ntGroupApi.setGroupMsgMask(+payload.group_id, +payload.mask)).errCode !== 0) throw new Error("系统错误");
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/SetGroupRemark.ts
var SetGroupRemark = class extends BaseAction {
	actionName = ActionName.SetGroupRemark;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		remark: lib_default$1.string()
	});
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.setGroupRemark(payload.group_id.toString(), payload.remark);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SetQQProfile.ts
var SetQQProfile = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SetQQProfile;
	payloadSchema = lib_default$1.object({
		nickname: lib_default$1.string(),
		personal_note: lib_default$1.string()
	});
	async _handle(payload) {
		const res = await this.ctx.ntUserApi.modifySelfProfile({
			nick: payload.nickname,
			bio: payload.personal_note
		});
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetProfileLike.ts
var GetProfileLike = class extends BaseAction {
	actionName = ActionName.GetProfileLike;
	payloadSchema = lib_default$1.object({
		start: lib_default$1.union([Number, String]).default(0),
		count: lib_default$1.union([Number, String]).default(20)
	});
	async _handle(payload) {
		const ret = await this.ctx.ntUserApi.getProfileLike(selfInfo.uid, +payload.start, +payload.count);
		const users = ret.userLikeInfo.favoriteInfo.users ?? [];
		for (const item of users) Object.assign(item, {
			uin: await this.ctx.ntUserApi.getUinByUid(item.uid),
			isFriend: await this.ctx.ntFriendApi.isFriend(item.uid)
		});
		return {
			users,
			nextStart: ret.start
		};
	}
};
//#endregion
//#region src/onebot11/action/system/GetCsrfToken.ts
var GetCsrfToken = class extends BaseAction {
	actionName = ActionName.GetCsrfToken;
	async _handle() {
		const cookiesObject = await this.ctx.ntWebApi.getCookies("h5.qzone.qq.com");
		return { token: +this.ctx.ntWebApi.genBkn(cookiesObject.skey) };
	}
};
//#endregion
//#region src/onebot11/action/go-cqhttp/SetGroupPortrait.ts
var SetGroupPortrait = class extends BaseAction {
	actionName = ActionName.GoCQHTTP_SetGroupPortrait;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file: lib_default$1.string().required()
	});
	async _handle(payload) {
		const { path, isLocal, errMsg } = await uri2local(this.ctx, payload.file);
		if (errMsg) throw new Error(errMsg);
		const groupCode = payload.group_id.toString();
		const res = await this.ctx.ntGroupApi.setGroupAvatar(groupCode, path);
		if (!isLocal) unlink(path).catch(noop);
		if (res.result !== 0) throw new Error(res.errMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/MoveGroupFile.ts
var MoveGroupFile$1 = class extends BaseAction {
	actionName = ActionName.MoveGroupFile;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file_id: lib_default$1.string().required(),
		parent_directory: lib_default$1.string().required(),
		target_directory: lib_default$1.string().required()
	});
	async _handle(payload) {
		const groupId = +payload.group_id;
		const res = await this.ctx.ntGroupApi.moveGroupFile(groupId, payload.file_id, payload.parent_directory, payload.target_directory);
		if (res.retCode !== 0) throw new Error(res.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/RenameGroupFile.ts
var RenameGroupFile$1 = class extends BaseAction {
	actionName = ActionName.RenameGroupFile;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file_id: lib_default$1.string().required(),
		current_parent_directory: lib_default$1.string().required(),
		new_name: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.renameGroupFile(+payload.group_id, payload.file_id, payload.current_parent_directory, payload.new_name);
		if (result.retCode !== 0) throw new Error(result.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GetGroupShutList.ts
var GetGroupShutList = class extends BaseAction {
	actionName = ActionName.GetGroupShutList;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const members = await this.ctx.ntGroupApi.getGroupMembers(+payload.group_id, true);
		const now = Math.floor(Date.now() / 1e3);
		return members.filter((member) => member.shutupExpireTime > now).map((member) => ({
			uid: member.uid,
			uin: member.uin.toString(),
			nick: member.nick,
			cardName: member.cardName,
			role: member.role,
			shutUpTime: member.shutupExpireTime,
			memberRealLevel: member.level,
			memberSpecialTitle: member.specialTitle,
			joinTime: member.joinedAt,
			lastSpeakTime: member.lastSpokeAt
		}));
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/RenameGroupFileFolder.ts
var RenameGroupFileFolder = class extends BaseAction {
	actionName = ActionName.RenameGroupFileFolder;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		folder_id: lib_default$1.string().required(),
		new_folder_name: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.renameGroupFolder(+payload.group_id, payload.folder_id, payload.new_folder_name);
		if (result.retCode !== 0) throw new Error(result.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/VoiceMsg2Text.ts
var VoiceMsg2Text = class extends BaseAction {
	actionName = ActionName.VoiceMsg2Text;
	payloadSchema = lib_default$1.object({ message_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const msgInfo = await this.ctx.store.getMsgInfoByShortId(+payload.message_id);
		if (!msgInfo) throw new Error("消息不存在");
		let msg = this.ctx.store.getMsgByMsgId(msgInfo.msgId);
		if (!msg) {
			const res = await this.ctx.ntMsgApi.getSingleMsg(msgInfo.peer, msgInfo.msgSeq);
			if (res.msgList.length === 0) throw new Error("无法获取该消息");
			msg = res.msgList[0];
		}
		const voiceElement = msg?.elements.find((e) => e.elementType === ElementType.Ptt);
		if (!voiceElement) throw new Error("该消息不是语音消息");
		const text = await this.ctx.ntMsgApi.translatePtt2Text(msgInfo.msgId, msgInfo.peer, +msg.senderUin, voiceElement);
		if (!text) throw new Error("未识别到文字");
		return { text };
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/SendPB.ts
var SendPB = class extends BaseAction {
	actionName = ActionName.SendPB;
	payloadSchema = lib_default$1.object({
		cmd: lib_default$1.string().required(),
		hex: lib_default$1.string().required()
	});
	async _handle(payload) {
		try {
			const result = await this.ctx.qqProtocol.sendPB(payload.cmd, payload.hex);
			return {
				cmd: result.cmd,
				hex: result.pb,
				...result.echo !== void 0 ? { echo: result.echo } : {}
			};
		} catch (e) {
			this.ctx.logger.error("pmhq 发包失败", e);
			throw new Error(`pmhq 发包失败: ${e}`, { cause: e });
		}
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/GetRkey.ts
var GetRKey = class extends BaseAction {
	actionName = ActionName.GetRKey;
	async _handle() {
		const rkey = await this.ctx.ntFileApi.getRKey();
		const now = /* @__PURE__ */ new Date();
		const updatedTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}`;
		return {
			private_key: rkey.privateRKey,
			group_key: rkey.groupRKey,
			expired_time: rkey.expiredTime,
			updated_time: updatedTime
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/UploadFlashFile.ts
var UploadFlashFile = class extends BaseAction {
	actionName = ActionName.UploadFlashFile;
	payloadSchema = lib_default$1.object({
		title: lib_default$1.string(),
		paths: lib_default$1.array(String).required()
	});
	async _handle(payload) {
		const { title, paths } = payload;
		const localPaths = await Promise.all(paths.map(async (path) => {
			const { fileName, path: localPath, isLocal, errMsg } = await uri2local(this.ctx, path);
			if (errMsg) throw new Error(errMsg);
			if (localPath) return localPath;
			else throw new Error(`无法获取文件${path}的本地路径`);
		}));
		const res = await this.ctx.ntFileApi.uploadFlashFile(title, localPaths);
		if (res.result !== 0) throw new Error(res.result);
		if (!res.createFlashTransferResult) {
			const oldFlashFileInfo = await this.ctx.ntFileApi.getFlashFileInfo(res.fileSetId);
			return {
				file_set_id: oldFlashFileInfo.fileSetId,
				share_link: oldFlashFileInfo.shareInfo.shareLink,
				expire_time: +oldFlashFileInfo.expireTime
			};
		}
		return {
			file_set_id: res.createFlashTransferResult.fileSetId,
			share_link: res.createFlashTransferResult.shareLink,
			expire_time: +res.createFlashTransferResult.expireTime,
			downloads: res.downloads
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/GetFlashFileInfo.ts
var GetFlashFileInfoBase = class extends BaseAction {
	actionName = ActionName.GetFlashFileInfo;
	payloadSchema = lib_default$1.object({
		share_link: lib_default$1.string(),
		file_set_id: lib_default$1.string()
	});
	async get_file_set_id(payload) {
		const { share_link } = payload;
		let { file_set_id } = payload;
		if (share_link) {
			const match = share_link.match(/qfile.qq.com\/q\/([\w\d]+)/);
			if (!match) throw new Error("分享链接格式不正确");
			const code = match[1];
			const res = await this.ctx.ntFileApi.getFlashFileSetIdByCode(code);
			if (res.result !== 0) throw new Error(`获取闪传文件 fileSetId 失败: ${res.errMsg}`);
			file_set_id = res.fileSetId;
		}
		if (!file_set_id) throw new Error("请提供有效的 share_link 或 file_set_id");
		return file_set_id;
	}
};
var GetFlashFileInfo = class extends GetFlashFileInfoBase {
	actionName = ActionName.GetFlashFileInfo;
	async _handle(payload) {
		const file_set_id = await this.get_file_set_id(payload);
		const fileInfo = await this.ctx.ntFileApi.getFlashFileInfo(file_set_id);
		const fileList = await this.ctx.ntFileApi.getFlashFileList(file_set_id);
		const files = [];
		for (const file of fileList) for (const file2 of file.fileList) files.push({
			name: file2.name,
			size: +file2.fileSize
		});
		return {
			file_set_id,
			title: fileInfo.name,
			share_link: fileInfo.shareInfo.shareLink,
			total_file_size: +fileInfo.totalFileSize,
			files
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/ReShareFlashFile.ts
/**
* 闪传：用老 share_link / file_set_id 重新分享，拿到全新 share_link + 14 天有效期。
*
* 实现链路（跟 Windows QQ "重新分享" 按钮一致，但**不需要本地有原文件**）：
*   share_link → 0x93eb_1 → 老 fileSetId
*   → 0x93d4_1 (field3=2) 拿每文件的 sha1
*   → 走完整 upload 链路 (createFlashFileSet/register/prep/preflight/commit)
*   → preflight 拿 list 给的 sha1，server 端秒传命中，瞬间完成
*   → 全新 share_link + 14 天有效期
*
* 限制：老 fileSet 必须没过期（过期后 list 调不通拿不到 sha1）。
*
* Payload: { share_link } 或 { file_set_id }
*/
var ReShareFlashFile = class extends GetFlashFileInfoBase {
	actionName = ActionName.ReShareFlashFile;
	async _handle(payload) {
		const file_set_id = await this.get_file_set_id(payload);
		const res = await this.ctx.ntFileApi.reshareFlashFile(file_set_id);
		if (res.result !== 0) throw new Error(res.errMsg || String(res.result));
		return {
			file_set_id: res.createFlashTransferResult.fileSetId,
			share_link: res.createFlashTransferResult.shareLink,
			expire_time: +res.createFlashTransferResult.expireTime
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetQQAvatar.ts
var GetQQAvatar = class extends BaseAction {
	actionName = ActionName.GetQQAvatar;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]),
		group_id: lib_default$1.union([Number, String])
	});
	async _handle(payload) {
		if (payload.user_id) return { url: `https://thirdqq.qlogo.cn/g?b=qq&nk=${payload.user_id}&s=640` };
		else if (payload.group_id) return { url: `https://p.qlogo.cn/gh/${payload.group_id}/${payload.group_id}/0` };
		else throw new Error("未指定 user_id 或 group_id");
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/DownloadFlashFile.ts
var DownloadFlashFile = class extends GetFlashFileInfoBase {
	actionName = ActionName.DownloadFlashFile;
	async _handle(payload) {
		const file_set_id = await this.get_file_set_id(payload);
		const res = await this.ctx.ntFileApi.downloadFlashFile(file_set_id);
		if (res.result !== 0) throw new Error(res.errMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/GetFlashFileDownloadUrls.ts
/**
* 获取闪传文件集里所有文件的下载入口（默认全选）。
*
* 关键：list req body 里 `field3 = 2`（Windows QQ 客户端的发法）才能让 server 返
* `f14.historyToken`——0x12a9_200 download preflight 真正识别的 fileId。Linux QQ
* 客户端默认 `field3 = 1`，server 主动剥光 historyToken / sha1 / md5 字段，URL
* 拿到也是 fileid= 空。
*
* 流程：
*   share_link → 0x93eb_1 → fileSetId
*   fileSetId → 0x93d4_1 (f3=2) → 每个 entry 含 historyToken
*   (fileSetId, fileUuid, historyToken) → 0x12a9_200 → 完整 download URL
*
* Payload: { share_link } 或 { file_set_id }
*/
var GetFlashFileDownloadUrls = class extends GetFlashFileInfoBase {
	actionName = ActionName.GetFlashFileDownloadUrls;
	async _handle(payload) {
		const file_set_id = await this.get_file_set_id(payload);
		const info = await this.ctx.ntFileApi.getFlashFileInfo(file_set_id);
		const fileList = await this.ctx.ntFileApi.getFlashFileList(file_set_id);
		const urls = [];
		for (const group of fileList) for (const f of group.fileList) {
			const url = await this.ctx.ntFileApi.getFlashFileDownloadUrl({
				fileSetId: file_set_id,
				fileUuid: f.cliFileId,
				fileName: f.name,
				fileSize: +f.fileSize,
				fileId: f.fileId
			});
			urls.push({
				name: f.name,
				size: +f.fileSize,
				url: url.fullUrl,
				expire: url.ttl
			});
		}
		return {
			file_set_id,
			share_link: info.shareInfo?.shareLink ?? "",
			files: urls
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/GetRecommendFace.ts
var GetRecommendFace = class extends BaseAction {
	actionName = ActionName.GetRecommendFace;
	payloadSchema = lib_default$1.object({ word: lib_default$1.string().required() });
	async _handle(payload) {
		return { url: (await this.ctx.ntMsgApi.getRecommendFace(payload.word)).info.map((e) => e.url) };
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/BatchDeleteGroupMember.ts
var BatchDeleteGroupMember = class extends BaseAction {
	actionName = ActionName.BatchDeleteGroupMember;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		user_ids: lib_default$1.array(lib_default$1.union([Number, String])).required()
	});
	async _handle(payload) {
		const groupCode = +payload.group_id;
		const memberUinList = payload.user_ids.map((id) => +id);
		const memberUids = await Promise.all(memberUinList.map(async (uin) => {
			return await this.ctx.ntUserApi.getUidByUin(uin, groupCode);
		}));
		const res = await this.ctx.ntGroupApi.kickGroupMember(+payload.group_id, memberUids);
		if (res.errorCode !== 0) throw new Error(res.errorMsg);
		return null;
	}
};
//#endregion
//#region node_modules/ts-case-convert/lib/caseConvert.js
var require_caseConvert = /* @__PURE__ */ __commonJSMin(((exports) => {
	Object.defineProperty(exports, "__esModule", { value: true });
	exports.toCamel = toCamel;
	exports.objectToCamel = objectToCamel;
	exports.toSnake = toSnake;
	exports.toSnakeNoSplitNumbers = toSnakeNoSplitNumbers;
	exports.objectToSnake = objectToSnake;
	exports.objectToSnakeNoSplitNumbers = objectToSnakeNoSplitNumbers;
	exports.toScreamingSnake = toScreamingSnake;
	exports.toScreamingSnakeNoSplitNumbers = toScreamingSnakeNoSplitNumbers;
	exports.objectToScreamingSnake = objectToScreamingSnake;
	exports.objectToScreamingSnakeNoSplitNumbers = objectToScreamingSnakeNoSplitNumbers;
	exports.toPascal = toPascal;
	exports.objectToPascal = objectToPascal;
	function convertObject(obj, keyConverter) {
		if (obj === null || typeof obj === "undefined" || typeof obj !== "object") return obj;
		const out = Array.isArray(obj) ? [] : {};
		for (const [k, v] of Object.entries(obj)) out[keyConverter(k)] = Array.isArray(v) ? v.map((item) => typeof item === "object" && !(item instanceof Uint8Array) && !(item instanceof Date) ? convertObject(item, keyConverter) : item) : v instanceof Uint8Array || v instanceof Date ? v : typeof v === "object" ? convertObject(v, keyConverter) : v;
		return out;
	}
	function toCamel(term) {
		if (isNumericKey(term)) return term;
		return term.length === 1 ? term.toLowerCase() : term.replace(/^([A-Z])/, (m) => m[0].toLowerCase()).replace(/[_-]([a-z0-9])/g, (m) => m[1].toUpperCase());
	}
	function objectToCamel(obj) {
		return convertObject(obj, toCamel);
	}
	function toSnakeWithSplitNumbers(term, splitNumbers) {
		var _a, _b;
		if (isNumericKey(term)) return term;
		let result = term;
		let circuitBreaker = 0;
		if (splitNumbers) while ((((_a = /([a-z])([0-9]+)(?![0-9]*[A-Z][a-z])/.exec(result)) === null || _a === void 0 ? void 0 : _a.length) || 0) > 2 && circuitBreaker < 10) {
			result = result.replace(/([a-z])([0-9]+)(?![0-9]*[A-Z][a-z])/, (_all, head, numbers) => `${head.toLowerCase()}_${numbers.toLowerCase()}`);
			circuitBreaker += 1;
		}
		while ((((_b = /(.+?)([A-Z])/.exec(result)) === null || _b === void 0 ? void 0 : _b.length) || 0) > 2 && circuitBreaker < 10) {
			result = result.replace(/(.+?)([A-Z])/, (_all, $1, $2) => `${$1.toLowerCase()}_${$2.toLowerCase()}`);
			circuitBreaker += 1;
		}
		return result.toLowerCase();
	}
	function toSnake(term) {
		return toSnakeWithSplitNumbers(term, true);
	}
	function toSnakeNoSplitNumbers(term) {
		return toSnakeWithSplitNumbers(term, false);
	}
	function objectToSnake(obj) {
		return convertObject(obj, (key) => toSnakeWithSplitNumbers(key, true));
	}
	function objectToSnakeNoSplitNumbers(obj) {
		return convertObject(obj, (key) => toSnakeWithSplitNumbers(key, false));
	}
	function toScreamingSnake(term) {
		return toSnake(term).toUpperCase();
	}
	function toScreamingSnakeNoSplitNumbers(term) {
		return toSnakeNoSplitNumbers(term).toUpperCase();
	}
	function objectToScreamingSnake(obj) {
		return convertObject(obj, toScreamingSnake);
	}
	function objectToScreamingSnakeNoSplitNumbers(obj) {
		return convertObject(obj, toScreamingSnakeNoSplitNumbers);
	}
	function toPascal(term) {
		if (isNumericKey(term)) return term;
		return toCamel(term).replace(/^([a-z])/, (m) => m[0].toUpperCase());
	}
	function objectToPascal(obj) {
		return convertObject(obj, toPascal);
	}
	function isNumericKey(term) {
		return /^-?\d+(?:\.\d+)?$/.test(term);
	}
}));
//#endregion
//#region src/onebot11/action/llbot/msg/GetAiCharacters.ts
var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
	Object.defineProperty(exports, "__esModule", { value: true });
	exports.objectToPascal = exports.toPascal = exports.toCamel = exports.toScreamingSnake = exports.toSnake = exports.objectToScreamingSnake = exports.objectToSnake = exports.objectToCamel = void 0;
	var caseConvert_1 = require_caseConvert();
	Object.defineProperty(exports, "objectToCamel", {
		enumerable: true,
		get: function() {
			return caseConvert_1.objectToCamel;
		}
	});
	Object.defineProperty(exports, "objectToSnake", {
		enumerable: true,
		get: function() {
			return caseConvert_1.objectToSnake;
		}
	});
	Object.defineProperty(exports, "objectToScreamingSnake", {
		enumerable: true,
		get: function() {
			return caseConvert_1.objectToScreamingSnake;
		}
	});
	Object.defineProperty(exports, "toSnake", {
		enumerable: true,
		get: function() {
			return caseConvert_1.toSnake;
		}
	});
	Object.defineProperty(exports, "toScreamingSnake", {
		enumerable: true,
		get: function() {
			return caseConvert_1.toScreamingSnake;
		}
	});
	Object.defineProperty(exports, "toCamel", {
		enumerable: true,
		get: function() {
			return caseConvert_1.toCamel;
		}
	});
	Object.defineProperty(exports, "toPascal", {
		enumerable: true,
		get: function() {
			return caseConvert_1.toPascal;
		}
	});
	Object.defineProperty(exports, "objectToPascal", {
		enumerable: true,
		get: function() {
			return caseConvert_1.objectToPascal;
		}
	});
})))();
var GetAiCharacters = class extends BaseAction {
	actionName = ActionName.GetAiCharacters;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).default(42),
		chat_type: lib_default$1.union([Number, String]).default(1)
	});
	async _handle(payload) {
		const res = await this.ctx.qqProtocol.fetchAiCharacterList(+payload.group_id, +payload.chat_type);
		return (0, import_lib.objectToSnake)(res.property);
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/SendGroupAiRecord.ts
var SendGroupAiRecord = class extends BaseAction {
	actionName = ActionName.SendGroupAiRecord;
	payloadSchema = lib_default$1.object({
		character: lib_default$1.string().required(),
		group_id: lib_default$1.union([Number, String]).required(),
		text: lib_default$1.string().required(),
		chat_type: lib_default$1.union([Number, String]).default(1)
	});
	async _handle(payload) {
		const seen = [];
		let targetMsgRandom = null;
		const { promise, resolve } = Promise.withResolvers();
		const checkAndResolve = (msg) => {
			if (targetMsgRandom !== null && msg.msgRandom === targetMsgRandom) {
				dispose();
				const shortId = this.ctx.store.createMsgShortId(msg);
				resolve({ message_id: shortId });
				return true;
			}
			return false;
		};
		const dispose = this.ctx.on("nt/message-sent", (data) => {
			if (!checkAndResolve(data.message)) seen.push(data.message);
		});
		try {
			targetMsgRandom = (await this.ctx.qqProtocol.getGroupGenerateAiRecord(+payload.group_id, payload.character, payload.text, +payload.chat_type)).msgRandom;
			for (const msg of seen) if (checkAndResolve(msg)) break;
		} catch (e) {
			dispose();
			throw e;
		}
		return promise;
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/GetPrivateFileUrl.ts
var GetPrivateFileUrl = class extends BaseAction {
	actionName = ActionName.GetPrivateFileUrl;
	payloadSchema = lib_default$1.object({ file_id: lib_default$1.string().required() });
	async _handle(payload) {
		const result = await this.ctx.ntFileApi.getFileUrl(payload.file_id, false);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		return { url: result.url };
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetDoubtFriendsAddRequest.ts
var GetDoubtFriendsAddRequest = class extends BaseAction {
	actionName = ActionName.GetDoubtFriendsAddRequest;
	payloadSchema = lib_default$1.object({ count: lib_default$1.union([Number, String]).default(50) });
	async _handle(payload) {
		const res = await this.ctx.ntFriendApi.getDoubtFriendRequests(+payload.count);
		return await Promise.all(res.map(async (e) => {
			return {
				flag: e.sourceUid,
				uin: String(await this.ctx.ntUserApi.getUinByUid(e.sourceUid)),
				nick: e.sourceNickname,
				source: e.source,
				reason: e.warningInfo,
				msg: e.comment,
				group_code: e.groupCode.toString(),
				time: e.timestamp.toString(),
				type: "doubt"
			};
		}));
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetDoubtFriendsAddRequest.ts
var SetDoubtFriendsAddRequest = class extends BaseAction {
	actionName = ActionName.SetDoubtFriendsAddRequest;
	payloadSchema = lib_default$1.object({ flag: lib_default$1.string().required() });
	async _handle(payload) {
		const result = await this.ctx.ntFriendApi.approvalDoubtFriendRequest(payload.flag);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/file/SetGroupFileForever.ts
var SetGroupFileForever = class extends BaseAction {
	actionName = ActionName.SetGroupFileForever;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		file_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const res = await this.ctx.ntGroupApi.persistGroupFile(+payload.group_id, payload.file_id);
		if (res.retCode !== 0) throw new Error(res.clientWording);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupAlbum/UploadGroupAlbum.ts
var UploadGroupAlbum = class extends BaseAction {
	actionName = ActionName.UploadGroupAlbum;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		album_id: lib_default$1.string().required(),
		files: lib_default$1.array(String).required()
	});
	async _handle(payload) {
		const filePathList = await Promise.all(payload.files.map(async (uri) => (await uri2local(this.ctx, uri)).path || uri));
		return this.ctx.ntWebApi.uploadGroupAlbum(+payload.group_id, filePathList, payload.album_id);
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupAlbum/GetGroupAlbumList.ts
var GetGroupAlbumList = class extends BaseAction {
	actionName = ActionName.GetGroupAlbumList;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.getGroupAlbumList(+payload.group_id);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		return result.albumList.map((a) => ({
			...(0, import_lib.objectToSnake)(a),
			create_time: a.createTime.toString(),
			modify_time: a.modifyTime.toString(),
			last_upload_time: a.lastUploadTime.toString(),
			upload_number: a.uploadNumber.toString()
		}));
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupAlbum/CreateGroupAlbum.ts
var CreateGroupAlbum = class extends BaseAction {
	actionName = ActionName.CreateGroupAlbum;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		name: lib_default$1.string().required(),
		desc: lib_default$1.string()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.createGroupAlbum(+payload.group_id, payload.name, payload.desc);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		if (!result.info?.albumId) throw new Error("create group album failed: server returned no album_id");
		return {
			album_id: result.info.albumId,
			owner: result.info.groupCode,
			name: result.info.name,
			desc: result.info.desc
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/DeleteGroupNotice.ts
var DeleteGroupNotice = class extends BaseAction {
	actionName = ActionName.DeleteGroupNotice;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		notice_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const res = await this.ctx.ntWebApi.deleteGroupBulletin(+payload.group_id, payload.notice_id);
		if (res.ec !== 0) throw new Error(res.em);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupAlbum/DeleteGroupAlbum.ts
var DeleteGroupAlbum = class extends BaseAction {
	actionName = ActionName.DeleteGroupAlbum;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		album_id: lib_default$1.string().required()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.deleteGroupAlbum(+payload.group_id, payload.album_id);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/system/ScanQRCode.ts
var ScanQRCode = class extends BaseAction {
	actionName = ActionName.ScanQRCode;
	payloadSchema = lib_default$1.object({ file: lib_default$1.string().required() });
	async _handle(payload) {
		throw new Error("暂不支持");
	}
};
//#endregion
//#region src/onebot11/action/llbot/msg/SendPoke.ts
var SendPoke = class extends BaseAction {
	actionName = ActionName.SendPoke;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]),
		user_id: lib_default$1.union([Number, String]).required(),
		target_id: lib_default$1.union([Number, String])
	});
	async _handle(payload) {
		let result;
		if (payload.group_id) result = await this.ctx.ntGroupApi.sendGroupNudge(+payload.group_id, +payload.user_id);
		else {
			const isSelf = payload.target_id ? payload.target_id.toString() === selfInfo.uin : false;
			result = await this.ctx.ntFriendApi.sendFriendNudge(+payload.user_id, isSelf);
		}
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/SetInputStatus.ts
var SetInputStatus = class extends BaseAction {
	actionName = ActionName.SetInputStatus;
	payloadSchema = lib_default$1.object({
		user_id: lib_default$1.union([Number, String]).required(),
		event_type: lib_default$1.union([Number, String]).required()
	});
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取用户信息");
		if ((await this.ctx.ntMsgApi.setPrivateInputStatus(uid, +payload.event_type)).retCode !== 0) throw new Error("设置输入状态失败");
		return null;
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GroupAlbum/GetGroupAlbumMediaList.ts
var GetGroupAlbumMediaList = class extends BaseAction {
	actionName = ActionName.GetGroupAlbumMediaList;
	payloadSchema = lib_default$1.object({
		group_id: lib_default$1.union([Number, String]).required(),
		album_id: lib_default$1.string().required(),
		attach_info: lib_default$1.string()
	});
	async _handle(payload) {
		const result = await this.ctx.ntGroupApi.getGroupAlbumMediaList(+payload.group_id, payload.album_id, payload.attach_info ?? void 0);
		if (result.retCode !== 0) throw new Error(result.retMsg);
		const album = result.body.album;
		const mediaList = result.body.mediaList;
		const { nextAttachInfo, nextHasMore } = result.body;
		return {
			album: {
				...(0, import_lib.objectToSnake)(album),
				create_time: album.createTime.toString(),
				modify_time: album.modifyTime.toString(),
				last_upload_time: album.lastUploadTime.toString(),
				upload_number: album.uploadNumber.toString()
			},
			media_list: mediaList.map((media) => ({
				...(0, import_lib.objectToSnake)(media),
				video: media.video ? {
					...(0, import_lib.objectToSnake)(media.video),
					video_time: media.video.videoTime.toString()
				} : void 0,
				batch_id: media.batchId.toString(),
				upload_time: media.uploadTime.toString()
			})),
			next_attach_info: nextAttachInfo,
			next_has_more: nextHasMore
		};
	}
};
//#endregion
//#region src/onebot11/action/llbot/group/GetGroupSignedList.ts
var GetGroupSignedList = class extends BaseAction {
	actionName = ActionName.GetGroupSignedList;
	payloadSchema = lib_default$1.object({ group_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const data = await this.ctx.ntWebApi.getDaySignedList(+payload.group_id);
		if (!data.response.page) throw new Error("无法获取该群组打卡列表");
		return data.response.page[0]?.infos?.map((info) => ({
			user_id: +info.uid,
			nick: info.uidGroupNick,
			time: +info.signedTimeStamp,
			rank: (info.signInRank - 1) / 2 + 1
		})) ?? [];
	}
};
//#endregion
//#region src/onebot11/action/llbot/user/GetProfileLikeCount.ts
var GetProfileLikeCount = class extends BaseAction {
	actionName = ActionName.GetProfileLikeCount;
	payloadSchema = lib_default$1.object({ user_id: lib_default$1.union([Number, String]).required() });
	async _handle(payload) {
		const uid = await this.ctx.ntUserApi.getUidByUin(+payload.user_id);
		if (!uid) throw new Error("无法获取用户信息");
		return { count: (await this.ctx.ntUserApi.getProfileLikeCount(uid)).body.voteInfo.totalCount };
	}
};
//#endregion
//#region src/onebot11/action/index.ts
function initActionMap(adapter) {
	const actionHandlers = [
		new ScanQRCode(adapter),
		new CreateGroupAlbum(adapter),
		new DeleteGroupAlbum(adapter),
		new GetGroupAlbumList(adapter),
		new UploadGroupAlbum(adapter),
		new SetGroupFileForever(adapter),
		new BatchDeleteGroupMember(adapter),
		new GetFlashFileInfo(adapter),
		new DownloadFlashFile(adapter),
		new GetFlashFileDownloadUrls(adapter),
		new UploadFlashFile(adapter),
		new ReShareFlashFile(adapter),
		new GetRKey(adapter),
		new SendPB(adapter),
		new VoiceMsg2Text(adapter),
		new GetFile(adapter),
		new Debug(adapter),
		new GetConfigAction(adapter),
		new SetConfigAction(adapter),
		new GetGroupAddRequest(adapter),
		new SetQQAvatar(adapter),
		new GetQQAvatar(adapter),
		new GetFriendWithCategory(adapter),
		new GetEvent(adapter),
		new SetOnlineStatus(adapter),
		new GetProfileLike(adapter),
		new GetProfileLikeMe(adapter),
		new GetFriendMsgHistory(adapter),
		new FetchEmojiLike(adapter),
		new FetchCustomFace(adapter),
		new SetMsgEmojiLike(adapter),
		new UnSetMsgEmojiLike(adapter),
		new GetRobotUinRange(adapter),
		new GroupPoke(adapter),
		new FriendPoke(adapter),
		new SetFriendCategory(adapter),
		new SetFriendRemark(adapter),
		new SetGroupMsgMask(adapter),
		new SetGroupRemark(adapter),
		new MoveGroupFile$1(adapter),
		new RenameGroupFile$1(adapter),
		new GetGroupShutList(adapter),
		new RenameGroupFileFolder(adapter),
		new GetRecommendFace(adapter),
		new GetAiCharacters(adapter),
		new SendGroupAiRecord(adapter),
		new GetPrivateFileUrl(adapter),
		new GetDoubtFriendsAddRequest(adapter),
		new SetDoubtFriendsAddRequest(adapter),
		new DeleteGroupNotice(adapter),
		new SendPoke(adapter),
		new SetInputStatus(adapter),
		new GetGroupAlbumMediaList(adapter),
		new GetGroupSignedList(adapter),
		new GetProfileLikeCount(adapter),
		new SendLike(adapter),
		new GetMsg(adapter),
		new GetLoginInfo$1(adapter),
		new GetFriendList$1(adapter),
		new GetGroupList$1(adapter),
		new GetGroupInfo$1(adapter),
		new GetGroupMemberList$1(adapter),
		new GetGroupMemberInfo$1(adapter),
		new SendGroupMsg(adapter),
		new SendPrivateMsg(adapter),
		new SendMsg(adapter),
		new DeleteMsg(adapter),
		new SetGroupAddRequest(adapter),
		new SetFriendAddRequest(adapter),
		new SetGroupLeave(adapter),
		new GetVersionInfo(adapter),
		new CanSendRecord(adapter),
		new CanSendImage(adapter),
		new GetStatus(adapter),
		new SetGroupWholeBan(adapter),
		new SetGroupBan(adapter),
		new SetGroupKick(adapter),
		new SetGroupAdmin(adapter),
		new SetGroupName$1(adapter),
		new SetGroupCard(adapter),
		new GetImage(adapter),
		new GetRecord(adapter),
		new CleanCache(adapter),
		new GetCookies$1(adapter),
		new ForwardFriendSingleMsg(adapter),
		new ForwardGroupSingleMsg(adapter),
		new GetCredentials(adapter),
		new SetRestart(adapter),
		new GetCsrfToken(adapter),
		new GetEssenceMsgList(adapter),
		new GetGroupHonorInfo(adapter),
		new SendForwardMsg(adapter),
		new SendGroupForwardMsg(adapter),
		new SendPrivateForwardMsg(adapter),
		new GetStrangerInfo(adapter),
		new DownloadFile(adapter),
		new GetGuildList(adapter),
		new MarkMsgAsRead(adapter),
		new UploadGroupFile$1(adapter),
		new UploadPrivateFile$1(adapter),
		new GetGroupMsgHistory(adapter),
		new GetForwardMsg(adapter),
		new HandleQuickOperation(adapter),
		new SetEssenceMsg(adapter),
		new DeleteEssenceMsg(adapter),
		new DeleteGroupFile$1(adapter),
		new GetGroupSystemMsg(adapter),
		new CreateGroupFileFolder(adapter),
		new DeleteGroupFolder$1(adapter),
		new GetGroupAtAllRemain(adapter),
		new GetGroupRootFiles(adapter),
		new SendGroupNotice(adapter),
		new GetGroupFilesByFolder(adapter),
		new GetGroupFileUrl(adapter),
		new GetGroupNotice(adapter),
		new DeleteFriend$1(adapter),
		new OCRImage(adapter),
		new GetGroupFileSystemInfo(adapter),
		new SetGroupSpecialTitle(adapter),
		new SendGroupSign(adapter),
		new SetQQProfile(adapter),
		new SetGroupPortrait(adapter)
	];
	const actionMap = /* @__PURE__ */ new Map();
	for (const action of actionHandlers) {
		actionMap.set(action.actionName, action);
		actionMap.set(action.actionName + "_async", action);
		actionMap.set(action.actionName + "_rate_limited", action);
	}
	return actionMap;
}
//#endregion
//#region src/onebot11/event/notice/OB11GroupAdminNoticeEvent.ts
var OB11GroupAdminNoticeEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_admin";
	sub_type;
	group_id;
	user_id;
	constructor(subType, groupId, userId) {
		super();
		this.sub_type = subType;
		this.group_id = groupId;
		this.user_id = userId;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11ProfileLikeEvent.ts
var OB11ProfileLikeEvent = class extends OB11BaseNoticeEvent {
	notice_type = "notify";
	sub_type = "profile_like";
	operator_id;
	operator_nick;
	times;
	constructor(operatorId, operatorNick, times) {
		super();
		this.operator_id = operatorId;
		this.operator_nick = operatorNick;
		this.times = times;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11PokeEvent.ts
var OB11PokeEvent = class extends OB11BaseNoticeEvent {
	notice_type = "notify";
	sub_type = "poke";
	target_id = 0;
};
var OB11FriendPokeEvent = class extends OB11PokeEvent {
	user_id;
	raw_info;
	constructor(user_id, target_id, raw_message) {
		super();
		this.target_id = target_id;
		this.user_id = user_id;
		this.raw_info = raw_message;
	}
};
var OB11GroupPokeEvent = class extends OB11PokeEvent {
	user_id;
	group_id;
	raw_info;
	constructor(group_id, user_id, target_id, raw_message) {
		super();
		this.group_id = group_id;
		this.target_id = target_id;
		this.user_id = user_id;
		this.raw_info = raw_message;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupDismissEvent.ts
var OB11GroupDismissEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_dismiss";
	user_id;
	group_id;
	constructor(groupId, user_id) {
		super();
		this.group_id = groupId;
		this.user_id = user_id;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11MsgEmojiLikeEvent.ts
var OB11GroupMsgEmojiLikeEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_msg_emoji_like";
	message_id;
	likes;
	group_id;
	user_id;
	is_add;
	constructor(groupId, userId, messageId, likes, isAdd) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.message_id = messageId;
		this.likes = likes;
		this.is_add = isAdd;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupEssenceEvent.ts
var GroupEssenceEvent = class extends OB11GroupNoticeEvent {
	notice_type = "essence";
	message_id;
	sender_id;
	sub_type;
	group_id;
	user_id;
	operator_id;
	constructor(groupId, messageId, senderId, operatorId, subType) {
		super();
		this.group_id = groupId;
		this.user_id = senderId;
		this.message_id = messageId;
		this.sender_id = senderId;
		this.operator_id = operatorId;
		this.sub_type = subType;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupBanEvent.ts
var GroupBanEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_ban";
	operator_id;
	duration;
	sub_type;
	group_id;
	user_id;
	constructor(groupId, userId, operatorId, duration, sub_type) {
		super();
		this.group_id = groupId;
		this.operator_id = operatorId;
		this.user_id = userId;
		this.duration = duration;
		this.sub_type = sub_type;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupTitleEvent.ts
var OB11GroupTitleEvent = class extends OB11GroupNoticeEvent {
	notice_type = "notify";
	sub_type = "title";
	title;
	group_id;
	user_id;
	constructor(groupId, userId, title) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.title = title;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11FriendAddNoticeEvent.ts
var OB11FriendAddNoticeEvent = class extends OB11BaseNoticeEvent {
	notice_type = "friend_add";
	user_id;
	constructor(userId) {
		super();
		this.user_id = userId;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupCardEvent.ts
var OB11GroupCardEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_card";
	group_id;
	user_id;
	card_new;
	card_old;
	constructor(groupId, userId, cardNew, cardOld) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.card_new = cardNew;
		this.card_old = cardOld;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupRecallNoticeEvent.ts
var OB11GroupRecallNoticeEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_recall";
	operator_id;
	message_id;
	group_id;
	user_id;
	constructor(groupId, userId, operatorId, messageId) {
		super();
		this.group_id = groupId;
		this.user_id = userId;
		this.operator_id = operatorId;
		this.message_id = messageId;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11FriendRecallNoticeEvent.ts
var OB11FriendRecallNoticeEvent = class extends OB11BaseNoticeEvent {
	notice_type = "friend_recall";
	user_id;
	message_id;
	constructor(userId, messageId) {
		super();
		this.user_id = userId;
		this.message_id = messageId;
	}
};
//#endregion
//#region src/onebot11/event/notice/OB11GroupIncreaseEvent.ts
var OB11GroupIncreaseEvent = class extends OB11GroupNoticeEvent {
	notice_type = "group_increase";
	operator_id;
	sub_type;
	group_id;
	user_id;
	constructor(groupId, userId, operatorId, subType = "approve") {
		super();
		this.group_id = groupId;
		this.operator_id = operatorId;
		this.user_id = userId;
		this.sub_type = subType;
	}
};
//#endregion
//#region src/onebot11/adapter.ts
var Onebot11Adapter = class extends Service {
	ctx;
	config;
	static inject = [
		"ntMsgApi",
		"ntFileApi",
		"ntFriendApi",
		"ntGroupApi",
		"ntUserApi",
		"ntWebApi",
		"ntSystemApi",
		"store",
		"app",
		"qqProtocol",
		"timer",
		"config"
	];
	connect;
	actionMap;
	reportOfflineMessage;
	reportSelfMessage;
	constructor(ctx, config) {
		super(ctx, "onebot");
		this.ctx = ctx;
		this.config = config;
		this.actionMap = initActionMap(this);
		this.reportOfflineMessage = false;
		this.reportSelfMessage = false;
		this.connect = config.connect.map((item) => {
			if (item.reportOfflineMessage) this.reportOfflineMessage = true;
			if (item.reportSelfMessage) this.reportSelfMessage = true;
			if (item.type === "http") return new OB11Http(ctx, {
				...item,
				actionMap: this.actionMap
			});
			else if (item.type === "http-post") return new OB11HttpPost(ctx, item);
			else if (item.type === "ws") return new OB11WebSocket(ctx, {
				...item,
				actionMap: this.actionMap
			});
			else if (item.type === "ws-reverse") return new OB11WebSocketReverse(ctx, {
				...item,
				actionMap: this.actionMap
			});
			else throw new Error("incorrect ob11 connect type");
		});
	}
	async [Service.init]() {
		this.start();
		return noop;
	}
	dispatch(event) {
		for (const item of this.connect) item.emitEvent(event);
	}
	dispatchMessageLike(event, self, offline) {
		if (this.connect.length === 1) {
			this.connect[0].emitMessageLikeEvent(event, self, offline);
			return;
		}
		for (const item of this.connect) item.emitMessageLikeEvent(cloneObj(event), self, offline);
	}
	async handleMsg(message, self, offline) {
		if (offline && !this.reportOfflineMessage) return;
		if (self && !this.reportSelfMessage) return;
		OB11Entities.message(this.ctx, message).then((msg) => {
			if (!msg) return;
			if (msg.user_id.toString() === selfInfo.uin) msg.target_id = +message.peerUin;
			this.dispatchMessageLike(msg, self, offline);
		}).catch((e) => this.ctx.logger.error("handling incoming messages", e));
		OB11Entities.groupEvent(this.ctx, message).then((groupEvent) => {
			if (groupEvent) if (Array.isArray(groupEvent)) for (const item of groupEvent) this.dispatchMessageLike(item, self, offline);
			else this.dispatchMessageLike(groupEvent, self, offline);
		}).catch((e) => this.ctx.logger.error("handling incoming group events", e));
	}
	async handleConfigUpdated(config) {
		for (const item of this.connect) if (item.config.enable) await item.stop();
		if (config.ob11.enable) {
			this.reportOfflineMessage = false;
			this.reportSelfMessage = false;
			this.connect = config.ob11.connect.map((item) => {
				if (item.reportOfflineMessage) this.reportOfflineMessage = true;
				if (item.reportSelfMessage) this.reportSelfMessage = true;
				if (item.type === "http") return new OB11Http(this.ctx, {
					...item,
					actionMap: this.actionMap
				});
				else if (item.type === "http-post") return new OB11HttpPost(this.ctx, item);
				else if (item.type === "ws") return new OB11WebSocket(this.ctx, {
					...item,
					actionMap: this.actionMap
				});
				else if (item.type === "ws-reverse") return new OB11WebSocketReverse(this.ctx, {
					...item,
					actionMap: this.actionMap
				});
				else throw new Error("incorrect ob11 connect type");
			});
			for (const item of this.connect) if (item.config.enable) item.start();
		}
		Object.assign(this.config, {
			...config.ob11,
			msgCacheExpire: config.msgCacheExpire,
			musicSignUrl: config.musicSignUrl,
			enableLocalFile2Url: config.enableLocalFile2Url,
			ffmpeg: config.ffmpeg
		});
	}
	start() {
		if (this.config.enable) {
			for (const item of this.connect) if (item.config.enable) item.start();
		}
		this.ctx.on("llob/config-updated", (input) => {
			this.handleConfigUpdated(input).catch(noop);
		});
		this.ctx.on("nt/message-created", (data) => {
			this.handleMsg(data.message, false, false);
		});
		this.ctx.on("nt/message-deleted", async (data) => {
			let resolved = data;
			if (data.chatType === ChatType.Group && data.msgRandom === 0) {
				const cached = this.ctx.store.getMsgBySeq(data.peerUid, data.msgSeq);
				if (cached) resolved = {
					...data,
					msgRandom: cached.msgRandom,
					msgId: cached.msgId
				};
				else return;
			}
			const shortId = this.ctx.store.createMsgShortId(resolved);
			let event;
			if (resolved.chatType === ChatType.Group) event = new OB11GroupRecallNoticeEvent(resolved.peerUin, resolved.senderUin, resolved.operatorUin, shortId);
			else event = new OB11FriendRecallNoticeEvent(resolved.senderUin, shortId);
			this.dispatch(event);
		});
		this.ctx.on("nt/message-sent", (data) => {
			this.handleMsg(data.message, true, false);
		});
		this.ctx.on("nt/group-join-request", (data) => {
			const event = new OB11GroupRequestAddEvent(data.groupCode, data.initiatorUin, encodeGroupRequestFlag$2(data.groupCode, data.notificationSeq, GroupNotificationType.JoinRequest, data.isDoubt), data.comment);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-invited-join-request", (data) => {
			const event = new OB11GroupRequestAddEvent(data.groupCode, data.targetUserUin, encodeGroupRequestFlag$2(data.groupCode, data.notificationSeq, GroupNotificationType.InvitedJoinRequest, false), "", data.initiatorUin);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-invitation", (data) => {
			const event = new OB11GroupRequestInviteBotEvent(data.groupCode, data.initiatorUin, encodeGroupRequestFlag$2(data.groupCode, data.invitationSeq, GroupNotificationType.Invitation, false), "");
			this.dispatch(event);
		});
		this.ctx.on("nt/group-disband", (data) => {
			const event = new OB11GroupDismissEvent(data.groupCode, data.operatorUin);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-nudge", (data) => {
			const userId = data.senderUin;
			const targetId = data.receiverUin;
			if (!userId || !targetId) return;
			const rawInfo = [
				{
					col: "1",
					jp: "",
					nm: "",
					tp: "0",
					type: "qq",
					uid: userId.toString()
				},
				{
					col: "1",
					jp: "",
					txt: data.displayAction,
					type: "nor"
				},
				{
					col: "1",
					jp: "",
					nm: "",
					tp: "0",
					type: "qq",
					uid: targetId.toString()
				}
			];
			if (data.displaySuffix) rawInfo.push({
				col: "1",
				jp: "",
				txt: data.displaySuffix,
				type: "nor"
			});
			if (data.displayActionImgUrl) rawInfo.push({
				src: data.displayActionImgUrl,
				type: "img"
			});
			const event = new OB11GroupPokeEvent(data.groupCode, userId, targetId, rawInfo);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-admin-changed", (data) => {
			const event = new OB11GroupAdminNoticeEvent(data.isSet ? "set" : "unset", data.groupCode, data.targetUin);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-message-reaction", async (data) => {
			const peer = {
				chatType: ChatType.Group,
				peerUid: data.groupCode.toString()
			};
			const cached = this.ctx.store.getMsgBySeq(peer.peerUid, data.msgSeq);
			let messageId;
			if (cached) messageId = this.ctx.store.createMsgShortId(cached);
			else {
				const { msgList } = await this.ctx.ntMsgApi.getSingleMsg(peer, data.msgSeq);
				messageId = this.ctx.store.createMsgShortId(msgList[0]);
			}
			const event = new OB11GroupMsgEmojiLikeEvent(data.groupCode, data.operatorUin, messageId, [{
				emoji_id: data.faceId,
				count: data.count
			}], data.isAdd);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-essence-message-changed", (data) => {
			const messageId = this.ctx.store.createMsgShortId({
				msgId: data.msgId,
				msgSeq: data.msgSeq,
				msgRandom: data.msgRandom,
				peerUid: data.groupCode.toString(),
				senderUid: data.senderUid,
				chatType: ChatType.Group
			});
			const event = new GroupEssenceEvent(data.groupCode, messageId, data.senderUin, data.operatorUin, data.isSet ? "add" : "delete");
			this.dispatch(event);
		});
		this.ctx.on("nt/group-whole-mute", (data) => {
			const event = new GroupBanEvent(data.groupCode, 0, data.operatorUin, data.isMute ? -1 : 0, data.isMute ? "ban" : "lift_ban");
			this.dispatch(event);
		});
		this.ctx.on("nt/group-mute", (data) => {
			const event = new GroupBanEvent(data.groupCode, data.memberUin, data.operatorUin, data.duration, data.duration !== 0 ? "ban" : "lift_ban");
			this.dispatch(event);
		});
		this.ctx.on("nt/group-member-added", (data) => {
			const event = new OB11GroupIncreaseEvent(data.groupCode, data.memberUin, data.operatorUin ?? data.invitorUin, data.operatorUid ? "approve" : "invite");
			this.dispatch(event);
		});
		this.ctx.on("nt/group-member-removed", (data) => {
			let subType = "leave";
			if (data.operatorUin) if (data.memberUin === +selfInfo.uin) subType = "kick_me";
			else subType = "kick";
			const event = new OB11GroupDecreaseEvent(data.groupCode, data.memberUin, data.operatorUin ?? data.memberUin, subType);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-member-card-name-changed", (data) => {
			const event = new OB11GroupCardEvent(data.groupCode, data.uin, data.newCardName, data.oldCardName);
			this.dispatch(event);
		});
		this.ctx.on("nt/group-member-special-title-changed", (data) => {
			const event = new OB11GroupTitleEvent(data.groupCode, data.uin, data.newSpecialTitle);
			this.dispatch(event);
		});
		this.ctx.on("nt/friend-request", (data) => {
			const event = new OB11FriendRequestEvent(data.initiatorUin, data.comment, data.initiatorUid, data.via);
			this.dispatch(event);
		});
		this.ctx.on("nt/friend-added", (data) => {
			const event = new OB11FriendAddNoticeEvent(data.uin);
			this.dispatch(event);
		});
		this.ctx.on("nt/friend-nudge", (data) => {
			const userId = data.uin;
			const targetId = data.isSelfReceive ? +selfInfo.uin : data.uin;
			if (!userId || !targetId) return;
			const rawInfo = [
				{
					col: "1",
					jp: "",
					nm: "",
					tp: "0",
					type: "qq",
					uid: userId.toString()
				},
				{
					col: "1",
					jp: "",
					txt: data.displayAction,
					type: "nor"
				},
				{
					col: "1",
					jp: "",
					nm: "",
					tp: "0",
					type: "qq",
					uid: targetId.toString()
				}
			];
			if (data.displaySuffix) rawInfo.push({
				col: "1",
				jp: "",
				txt: data.displaySuffix,
				type: "nor"
			});
			if (data.displayActionImgUrl) rawInfo.push({
				src: data.displayActionImgUrl,
				type: "img"
			});
			this.dispatch(new OB11FriendPokeEvent(userId, targetId, rawInfo));
		});
		this.ctx.on("nt/profile-like", (data) => {
			const event = new OB11ProfileLikeEvent(data.uin, data.nick, data.times);
			this.dispatch(event);
		});
	}
};
//#endregion
//#region node_modules/@satorijs/element/lib/index.mjs
var __defProp$5 = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __name$5 = (target, value) => __defProp$5(target, "name", {
	value,
	configurable: true
});
var __commonJS = (cb, mod) => function __require() {
	return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var lib_default = __commonJS({ "src/index.ts"(exports, module) {
	var kElement = /* @__PURE__ */ Symbol.for("satori.element");
	var ElementConstructor = class {
		static {
			__name$5(this, "ElementConstructor");
		}
		get data() {
			return this.attrs;
		}
		getTagName() {
			if (this.type === "component") return this.attrs.is?.name ?? "component";
			else return this.type;
		}
		toAttrString() {
			return Object.entries(this.attrs).map(([key, value]) => {
				if (isNullable(value)) return "";
				key = hyphenate(key);
				if (value === true) return ` ${key}`;
				if (value === false) return ` no-${key}`;
				return ` ${key}="${Element.escape("" + value, true)}"`;
			}).join("");
		}
		toString(strip = false) {
			if (this.type === "text" && "content" in this.attrs) return strip ? this.attrs.content : Element.escape(this.attrs.content);
			const inner = this.children.map((child) => child.toString(strip)).join("");
			if (strip) return inner;
			const attrs = this.toAttrString();
			const tag = this.getTagName();
			if (!this.children.length) return `<${tag}${attrs}/>`;
			return `<${tag}${attrs}>${inner}</${tag}>`;
		}
	};
	defineProperty(ElementConstructor, "name", "Element");
	defineProperty(ElementConstructor.prototype, kElement, true);
	function Element(type, ...args) {
		const el = Object.create(ElementConstructor.prototype);
		const attrs = {}, children = [];
		if (args[0] && typeof args[0] === "object" && !Element.isElement(args[0]) && !Array.isArray(args[0])) {
			const props = args.shift();
			for (const [key, value] of Object.entries(props)) {
				if (isNullable(value)) continue;
				if (key === "children") args.push(...makeArray(value));
				else attrs[camelize(key)] = value;
			}
		}
		for (const child of args) children.push(...Element.toElementArray(child));
		if (typeof type === "function") {
			attrs.is = type;
			type = "component";
		}
		return Object.assign(el, {
			type,
			attrs,
			children
		});
	}
	__name$5(Element, "Element");
	var evaluate = new Function("expr", "context", `
  try {
    with (context) {
      return eval(expr)
    }
  } catch {}
`);
	((Element2) => {
		Element2.jsx = Element2;
		Element2.jsxs = Element2;
		Element2.jsxDEV = Element2;
		Element2.Fragment = "template";
		function isElement(source) {
			return source && typeof source === "object" && source[kElement];
		}
		Element2.isElement = isElement;
		__name$5(isElement, "isElement");
		function toElement(content) {
			if (typeof content === "string" || typeof content === "number" || typeof content === "boolean") {
				content = "" + content;
				if (content) return Element2("text", { content });
			} else if (isElement(content)) return content;
			else if (!isNullable(content)) throw new TypeError(`Invalid content: ${content}`);
		}
		Element2.toElement = toElement;
		__name$5(toElement, "toElement");
		function toElementArray(content) {
			if (Array.isArray(content)) return content.map(toElement).filter(isNonNullable);
			else return [toElement(content)].filter(isNonNullable);
		}
		Element2.toElementArray = toElementArray;
		__name$5(toElementArray, "toElementArray");
		function normalize(source, context) {
			return typeof source === "string" ? parse(source, context) : toElementArray(source);
		}
		Element2.normalize = normalize;
		__name$5(normalize, "normalize");
		function escape(source, inline = false) {
			const result = (source ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
			return inline ? result.replace(/"/g, "&quot;") : result;
		}
		Element2.escape = escape;
		__name$5(escape, "escape");
		function unescape(source) {
			return source.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, "\"").replace(/&#(\d+);/g, (_, code) => code === "38" ? _ : String.fromCharCode(+code)).replace(/&#x([0-9a-f]+);/gi, (_, code) => code === "26" ? _ : String.fromCharCode(parseInt(code, 16))).replace(/&(amp|#38|#x26);/g, "&");
		}
		Element2.unescape = unescape;
		__name$5(unescape, "unescape");
		function from(source, options = {}) {
			const elements = parse(source);
			if (options.caret) {
				if (options.type && elements[0]?.type !== options.type) return;
				return elements[0];
			}
			return select(elements, options.type || "*")[0];
		}
		Element2.from = from;
		__name$5(from, "from");
		const combRegExp = / *([ >+~]) */g;
		function parseSelector(input) {
			return input.split(",").map((query) => {
				const selectors = [];
				query = query.trim();
				let combCap, combinator = " ";
				while (combCap = combRegExp.exec(query)) {
					selectors.push({
						type: query.slice(0, combCap.index),
						combinator
					});
					combinator = combCap[1];
					query = query.slice(combCap.index + combCap[0].length);
				}
				selectors.push({
					type: query,
					combinator
				});
				return selectors;
			});
		}
		Element2.parseSelector = parseSelector;
		__name$5(parseSelector, "parseSelector");
		function select(source, query) {
			if (!source || !query) return [];
			if (typeof source === "string") source = parse(source);
			if (typeof query === "string") query = parseSelector(query);
			if (!query.length) return [];
			let adjacent = [];
			const results = [];
			for (const [index, element] of source.entries()) {
				const inner = [];
				const local = [...query, ...adjacent];
				adjacent = [];
				let matched = false;
				for (const group of local) {
					const { type, combinator } = group[0];
					if (type === element.type || type === "*") if (group.length === 1) matched = true;
					else if ([" ", ">"].includes(group[1].combinator)) inner.push(group.slice(1));
					else if (group[1].combinator === "+") adjacent.push(group.slice(1));
					else query.push(group.slice(1));
					if (combinator === " ") inner.push(group);
				}
				if (matched) results.push(source[index]);
				results.push(...select(element.children, inner));
			}
			return results;
		}
		Element2.select = select;
		__name$5(select, "select");
		function interpolate(expr, context) {
			expr = expr.trim();
			if (!/^[\w.]+$/.test(expr)) return evaluate(expr, context) ?? "";
			let value = context;
			for (const part of expr.split(".")) {
				value = value[part];
				if (isNullable(value)) return "";
			}
			return value ?? "";
		}
		Element2.interpolate = interpolate;
		__name$5(interpolate, "interpolate");
		const tagRegExp1 = /(?<comment><!--[\s\S]*?-->)|(?<tag><(\/?)([^!\s>/]*)([^>]*?)\s*(\/?)>)/;
		const tagRegExp2 = /(?<comment><!--[\s\S]*?-->)|(?<tag><(\/?)([^!\s>/]*)([^>]*?)\s*(\/?)>)|(?<curly>\{(?<derivative>[@:/#][^\s}]*)?[\s\S]*?\})/;
		const attrRegExp1 = /([^\s=]+)(?:="(?<value1>[^"]*)"|='(?<value2>[^']*)')?/g;
		const attrRegExp2 = /([^\s=]+)(?:="(?<value1>[^"]*)"|='(?<value2>[^']*)'|=\{(?<curly>[^}]+)\})?/g;
		let Position;
		((Position2) => {
			Position2[Position2["OPEN"] = 0] = "OPEN";
			Position2[Position2["CLOSE"] = 1] = "CLOSE";
			Position2[Position2["EMPTY"] = 2] = "EMPTY";
			Position2[Position2["CONTINUE"] = 3] = "CONTINUE";
		})(Position || (Position = {}));
		function parse(source, context) {
			const tokens = [];
			function pushText(content) {
				if (content) tokens.push(content);
			}
			__name$5(pushText, "pushText");
			const tagRegExp = context ? tagRegExp2 : tagRegExp1;
			let tagCap;
			let trimStart = true;
			while (tagCap = tagRegExp.exec(source)) {
				const { curly, comment, derivative } = tagCap.groups;
				const trimEnd = !curly;
				parseContent(source.slice(0, tagCap.index), trimStart, trimEnd);
				trimStart = trimEnd;
				source = source.slice(tagCap.index + tagCap[0].length);
				const [_, , , close, type, extra, empty] = tagCap;
				if (comment) continue;
				if (curly) {
					let name = "", position = 2;
					if (derivative) {
						name = derivative.slice(1);
						position = {
							"@": 2,
							"#": 0,
							"/": 1,
							":": 3
						}[derivative[0]];
					}
					tokens.push({
						type: "curly",
						name,
						position,
						source: curly,
						extra: curly.slice(1 + (derivative ?? "").length, -1)
					});
					continue;
				}
				tokens.push({
					type: "angle",
					source: _,
					name: type || Element2.Fragment,
					position: close ? 1 : empty ? 2 : 0,
					extra
				});
			}
			parseContent(source, trimStart, true);
			function parseContent(source2, trimStart2, trimEnd) {
				source2 = unescape(source2);
				if (trimStart2) source2 = source2.replace(/^\s*\n\s*/, "");
				if (trimEnd) source2 = source2.replace(/\s*\n\s*$/, "");
				pushText(source2);
			}
			__name$5(parseContent, "parseContent");
			return parseTokens(foldTokens(tokens), context);
		}
		Element2.parse = parse;
		__name$5(parse, "parse");
		function foldTokens(tokens) {
			const stack = [[{
				type: "angle",
				name: Element2.Fragment,
				position: 0,
				source: "",
				extra: "",
				children: { default: [] }
			}, "default"]];
			function pushToken(...tokens2) {
				const [token, slot] = stack[0];
				token.children[slot].push(...tokens2);
			}
			__name$5(pushToken, "pushToken");
			for (const token of tokens) {
				if (typeof token === "string") {
					pushToken(token);
					continue;
				}
				const { name, position } = token;
				if (position === 1) {
					if (stack[0][0].name === name) stack.shift();
				} else if (position === 3) {
					stack[0][0].children[name] = [];
					stack[0][1] = name;
				} else if (position === 0) {
					pushToken(token);
					token.children = { default: [] };
					stack.unshift([token, "default"]);
				} else pushToken(token);
			}
			return stack[stack.length - 1][0].children.default;
		}
		__name$5(foldTokens, "foldTokens");
		function parseTokens(tokens, context) {
			const result = [];
			for (const token of tokens) if (typeof token === "string") result.push(Element2("text", { content: token }));
			else if (token.type === "angle") {
				const attrs = {};
				const attrRegExp = context ? attrRegExp2 : attrRegExp1;
				let attrCap;
				while (attrCap = attrRegExp.exec(token.extra)) {
					const [, key, v1, v2 = v1, v3] = attrCap;
					if (v3) attrs[key] = interpolate(v3, context);
					else if (!isNullable(v2)) attrs[key] = unescape(v2);
					else if (key.startsWith("no-")) attrs[key.slice(3)] = false;
					else attrs[key] = true;
				}
				result.push(Element2(token.name, attrs, token.children && parseTokens(token.children.default, context)));
			} else if (!token.name) result.push(...toElementArray(interpolate(token.extra, context)));
			else if (token.name === "if") if (evaluate(token.extra, context)) result.push(...parseTokens(token.children.default, context));
			else result.push(...parseTokens(token.children.else || [], context));
			else if (token.name === "each") {
				const [expr, ident] = token.extra.split(/\s+as\s+/);
				const items = interpolate(expr, context);
				if (!items || !items[Symbol.iterator]) continue;
				for (const item of items) result.push(...parseTokens(token.children.default, {
					...context,
					[ident]: item
				}));
			}
			return result;
		}
		__name$5(parseTokens, "parseTokens");
		function visit(element, rules, session) {
			const { type, attrs, children } = element;
			if (typeof rules === "function") return rules(element, session);
			else {
				let result = rules[typeof type === "string" ? type : ""] ?? rules.default ?? true;
				if (typeof result === "function") result = result(attrs, children, session);
				return result;
			}
		}
		__name$5(visit, "visit");
		function transform(source, rules, session) {
			const elements = typeof source === "string" ? parse(source) : source;
			const output = [];
			elements.forEach((element) => {
				const { type, attrs, children } = element;
				const result = visit(element, rules, session);
				if (result === true) output.push(Element2(type, attrs, transform(children, rules, session)));
				else if (result !== false) output.push(...toElementArray(result));
			});
			return typeof source === "string" ? output.join("") : output;
		}
		Element2.transform = transform;
		__name$5(transform, "transform");
		async function transformAsync(source, rules, session) {
			const elements = typeof source === "string" ? parse(source) : source;
			const children = (await Promise.all(elements.map(async (element) => {
				const { type, attrs, children: children2 } = element;
				const result = await visit(element, rules, session);
				if (result === true) return [Element2(type, attrs, await transformAsync(children2, rules, session))];
				else if (result !== false) return toElementArray(result);
				else return [];
			}))).flat(1);
			return typeof source === "string" ? children.join("") : children;
		}
		Element2.transformAsync = transformAsync;
		__name$5(transformAsync, "transformAsync");
		function createFactory(type, ...keys) {
			return (...args) => {
				const element = Element2(type);
				keys.forEach((key, index) => {
					if (!isNullable(args[index])) element.attrs[key] = args[index];
				});
				if (args[keys.length]) Object.assign(element.attrs, args[keys.length]);
				return element;
			};
		}
		__name$5(createFactory, "createFactory");
		Element2.warn = /* @__PURE__ */ __name$5(() => {}, "warn");
		function createAssetFactory(type) {
			return (src, ...args) => {
				let prefix = "base64://";
				if (typeof args[0] === "string") prefix = `data:${args.shift()};base64,`;
				if (is("Buffer", src)) src = prefix + src.toString("base64");
				else if (is("ArrayBuffer", src)) src = prefix + Binary.toBase64(src);
				else if (ArrayBuffer.isView(src)) src = prefix + Binary.toBase64(src.buffer);
				if (src.startsWith("base64://")) (0, Element2.warn)(`protocol "base64:" is deprecated and will be removed in the future, please use "data:" instead`);
				return Element2(type, {
					...args[0],
					src
				});
			};
		}
		__name$5(createAssetFactory, "createAssetFactory");
		Element2.text = createFactory("text", "content");
		Element2.at = createFactory("at", "id");
		Element2.sharp = createFactory("sharp", "id");
		Element2.quote = createFactory("quote", "id");
		Element2.emoji = createFactory("emoji", "id");
		Element2.image = createAssetFactory("img");
		Element2.img = createAssetFactory("img");
		Element2.video = createAssetFactory("video");
		Element2.audio = createAssetFactory("audio");
		Element2.file = createAssetFactory("file");
		function i18n(path, children) {
			return Element2("i18n", typeof path === "string" ? { path } : path, children);
		}
		Element2.i18n = i18n;
		__name$5(i18n, "i18n");
	})(Element || (Element = {}));
	module.exports = Element;
} })();
//#endregion
//#region node_modules/@satorijs/protocol/lib/index.mjs
var __defProp$4 = Object.defineProperty;
var __name$4 = (target, value) => __defProp$4(target, "name", {
	value,
	configurable: true
});
function Field$1(name) {
	return { name };
}
__name$4(Field$1, "Field");
function Method(name, fields, isForm = false) {
	return {
		name,
		fields: fields.map(Field$1),
		isForm
	};
}
__name$4(Method, "Method");
var Methods = {
	"channel.get": Method("getChannel", ["channel_id", "guild_id"]),
	"channel.list": Method("getChannelList", ["guild_id", "next"]),
	"channel.create": Method("createChannel", ["guild_id", "data"]),
	"channel.update": Method("updateChannel", ["channel_id", "data"]),
	"channel.delete": Method("deleteChannel", ["channel_id"]),
	"channel.mute": Method("muteChannel", [
		"channel_id",
		"guild_id",
		"enable"
	]),
	"message.create": Method("createMessage", [
		"channel_id",
		"content",
		"referrer"
	]),
	"message.update": Method("editMessage", [
		"channel_id",
		"message_id",
		"content"
	]),
	"message.delete": Method("deleteMessage", ["channel_id", "message_id"]),
	"message.get": Method("getMessage", ["channel_id", "message_id"]),
	"message.list": Method("getMessageList", [
		"channel_id",
		"next",
		"direction",
		"limit",
		"order"
	]),
	"reaction.create": Method("createReaction", [
		"channel_id",
		"message_id",
		"emoji_id"
	]),
	"reaction.delete": Method("deleteReaction", [
		"channel_id",
		"message_id",
		"emoji_id",
		"user_id"
	]),
	"reaction.clear": Method("clearReaction", [
		"channel_id",
		"message_id",
		"emoji_id"
	]),
	"reaction.list": Method("getReactionList", [
		"channel_id",
		"message_id",
		"emoji_id",
		"next"
	]),
	"upload.create": Method("createUpload", [], true),
	"guild.get": Method("getGuild", ["guild_id"]),
	"guild.list": Method("getGuildList", ["next"]),
	"guild.member.get": Method("getGuildMember", ["guild_id", "user_id"]),
	"guild.member.list": Method("getGuildMemberList", ["guild_id", "next"]),
	"guild.member.kick": Method("kickGuildMember", [
		"guild_id",
		"user_id",
		"permanent"
	]),
	"guild.member.mute": Method("muteGuildMember", [
		"guild_id",
		"user_id",
		"duration",
		"reason"
	]),
	"guild.member.role.set": Method("setGuildMemberRole", [
		"guild_id",
		"user_id",
		"role_id"
	]),
	"guild.member.role.unset": Method("unsetGuildMemberRole", [
		"guild_id",
		"user_id",
		"role_id"
	]),
	"guild.member.role.list": Method("getGuildMemberRoleList", [
		"guild_id",
		"user_id",
		"next"
	]),
	"guild.role.list": Method("getGuildRoleList", ["guild_id", "next"]),
	"guild.role.create": Method("createGuildRole", ["guild_id", "data"]),
	"guild.role.update": Method("updateGuildRole", [
		"guild_id",
		"role_id",
		"data"
	]),
	"guild.role.delete": Method("deleteGuildRole", ["guild_id", "role_id"]),
	"login.get": Method("getLogin", []),
	"user.get": Method("getUser", ["user_id"]),
	"user.channel.create": Method("createDirectChannel", ["user_id", "guild_id"]),
	"friend.list": Method("getFriendList", ["next"]),
	"friend.delete": Method("deleteFriend", ["user_id"]),
	"friend.approve": Method("handleFriendRequest", [
		"message_id",
		"approve",
		"comment"
	]),
	"guild.approve": Method("handleGuildRequest", [
		"message_id",
		"approve",
		"comment"
	]),
	"guild.member.approve": Method("handleGuildMemberRequest", [
		"message_id",
		"approve",
		"comment"
	])
};
var Channel;
((Channel2) => {
	((Type2) => {
		Type2[Type2["TEXT"] = 0] = "TEXT";
		Type2[Type2["DIRECT"] = 1] = "DIRECT";
		Type2[Type2["CATEGORY"] = 2] = "CATEGORY";
		Type2[Type2["VOICE"] = 3] = "VOICE";
	})(Channel2.Type || (Channel2.Type = {}));
})(Channel || (Channel = {}));
function Resource(attrs = [], children = [], content) {
	return {
		attrs,
		children,
		content
	};
}
__name$4(Resource, "Resource");
((Resource2) => {
	const Definitions = {
		user: Resource2([
			"id",
			"name",
			"nick",
			"avatar",
			"isBot"
		]),
		member: Resource2([
			"name",
			"nick",
			"avatar"
		]),
		channel: Resource2([
			"id",
			"type",
			"name"
		]),
		guild: Resource2([
			"id",
			"name",
			"avatar"
		]),
		quote: Resource2(["id"], [
			"quote",
			"user",
			"member",
			"channel"
		], "content")
	};
	function encode(type, data) {
		const resource = Definitions[type];
		const element = lib_default(type, pick$1(data, resource.attrs));
		for (const key of resource.children) {
			if (isNullable(data[key])) continue;
			element.children.push(encode(key, data[key]));
		}
		if (resource.content && !isNullable(data[resource.content])) element.children.push(...lib_default.parse(data[resource.content]));
		return element;
	}
	Resource2.encode = encode;
	__name$4(encode, "encode");
	function decode(element) {
		const data = element.attrs;
		const resource = Definitions[element.type];
		for (const key of resource.children) {
			const index = element.children.findIndex((el) => el.type === key);
			if (index === -1) continue;
			const [child] = element.children.splice(index, 1);
			data[key] = decode(child);
		}
		if (resource.content && element.children.length) data[resource.content] = element.children.join("");
		return data;
	}
	Resource2.decode = decode;
	__name$4(decode, "decode");
})(Resource || (Resource = {}));
function transformKey(source, callback) {
	if (!source || typeof source !== "object") return source;
	if (Array.isArray(source)) return source.map((value) => transformKey(value, callback));
	return Object.fromEntries(Object.entries(source).map(([key, value]) => {
		if (key.startsWith("_") || key === "referrer") return [key, value];
		return [callback(key), transformKey(value, callback)];
	}));
}
__name$4(transformKey, "transformKey");
var Status = /* @__PURE__ */ ((Status2) => {
	Status2[Status2["OFFLINE"] = 0] = "OFFLINE";
	Status2[Status2["ONLINE"] = 1] = "ONLINE";
	Status2[Status2["CONNECT"] = 2] = "CONNECT";
	Status2[Status2["DISCONNECT"] = 3] = "DISCONNECT";
	Status2[Status2["RECONNECT"] = 4] = "RECONNECT";
	return Status2;
})(Status || {});
var Opcode = /* @__PURE__ */ ((Opcode2) => {
	Opcode2[Opcode2["EVENT"] = 0] = "EVENT";
	Opcode2[Opcode2["PING"] = 1] = "PING";
	Opcode2[Opcode2["PONG"] = 2] = "PONG";
	Opcode2[Opcode2["IDENTIFY"] = 3] = "IDENTIFY";
	Opcode2[Opcode2["READY"] = 4] = "READY";
	Opcode2[Opcode2["META"] = 5] = "META";
	return Opcode2;
})(Opcode || {});
var WebSocket$2;
((WebSocket2) => {
	WebSocket2.CONNECTING = 0;
	WebSocket2.OPEN = 1;
	WebSocket2.CLOSING = 2;
	WebSocket2.CLOSED = 3;
})(WebSocket$2 || (WebSocket$2 = {}));
//#endregion
//#region src/satori/api/channel/get.ts
var getChannel = async (ctx, payload) => {
	const info = await ctx.ntGroupApi.getGroup(+payload.channel_id, true);
	return {
		id: payload.channel_id,
		type: Channel.Type.TEXT,
		name: info.groupName
	};
};
//#endregion
//#region src/satori/api/channel/list.ts
var getChannelList = async (ctx, payload) => {
	const info = await ctx.ntGroupApi.getGroup(+payload.guild_id, true);
	return { data: [{
		id: payload.guild_id,
		type: Channel.Type.TEXT,
		name: info.groupName
	}] };
};
//#endregion
//#region src/satori/api/channel/update.ts
var updateChannel = async (ctx, payload) => {
	if (payload.data.name) {
		const result = await ctx.ntGroupApi.setGroupName(+payload.channel_id, payload.data.name);
		if (result.errorCode !== 0) throw new Error(result.errorMsg);
	}
	return {};
};
//#endregion
//#region src/satori/api/channel/delete.ts
var deleteChannel = async (ctx, payload) => {
	const result = await ctx.ntGroupApi.quitGroup(+payload.channel_id);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/channel/mute.ts
var muteChannel = async (ctx, payload) => {
	const result = await ctx.ntGroupApi.muteGroup(+payload.channel_id, payload.duration !== 0);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/channel/user/create.ts
var createDirectChannel = async (ctx, payload) => {
	return {
		id: "private:" + payload.user_id,
		type: Channel.Type.DIRECT
	};
};
//#endregion
//#region src/satori/utils.ts
var robotUinRanges = [
	{
		minUin: 3328144510,
		maxUin: 3328144510
	},
	{
		minUin: 2854196301,
		maxUin: 2854216399
	},
	{
		minUin: 666e5,
		maxUin: 666e5
	},
	{
		minUin: 3889e6,
		maxUin: 3889999999
	},
	{
		minUin: 401e7,
		maxUin: 4019999999
	}
];
function decodeUser(user) {
	return {
		id: user.uin.toString(),
		name: user.nick,
		avatar: `http://q.qlogo.cn/headimg_dl?dst_uin=${user.uin}&spec=640`,
		is_bot: robotUinRanges.some((e) => +user.uin >= +e.minUin && +user.uin <= +e.maxUin)
	};
}
function decodeGuildChannelId(data) {
	if (data.chatType === ChatType.Group) return [data.peerUid, data.peerUid];
	else return [void 0, "private:" + data.peerUin];
}
async function decodeElement(ctx, data, quoted = false) {
	const buffer = [];
	for (const v of data.elements) if (v.textElement && v.textElement.atType !== AtType.Unknown) {
		const { atUin, atType, content } = v.textElement;
		if (atType === AtType.All) buffer.push(lib_default.at(void 0, { type: "all" }));
		else if (atType === AtType.One) buffer.push(lib_default.at(atUin.toString(), { name: content.replace("@", "") }));
	} else if (v.textElement && v.textElement.content) buffer.push(lib_default.text(v.textElement.content));
	else if (v.replyElement && !quoted) {
		const peer = {
			chatType: data.chatType,
			peerUid: data.peerUid,
			guildId: ""
		};
		try {
			const { replyMsgSeq, replyMsgTime, replyMsgClientSeq } = v.replyElement;
			let replyMsg = ctx.store.getMsgBySeq(peer.peerUid, replyMsgSeq);
			if (!replyMsg) {
				const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, replyMsgSeq);
				replyMsg = msgList[0];
			}
			if (!replyMsg && peer.chatType !== ChatType.Group) {
				const { msgList } = await ctx.ntMsgApi.getC2CMsgsByTimeAndCount(peer, replyMsgTime + 1, 3, true);
				replyMsg = msgList.find((e) => e.clientSeq === replyMsgClientSeq);
			}
			if (!replyMsg) {
				ctx.logger.warn("引用消息获取失败", v.replyElement);
				continue;
			}
			const elements = await decodeElement(ctx, replyMsg, true);
			buffer.push(lib_default("quote", { id: encodeMessageId(peer.chatType, peer.peerUid, replyMsg.msgSeq) }, elements));
		} catch (e) {
			ctx.logger.error("获取不到引用的消息", e, v.replyElement, e.stack);
		}
	} else if (v.picElement) {
		const src = await ctx.ntFileApi.getImageUrl(v.picElement.originImageUrl, v.picElement.md5HexStr);
		buffer.push(lib_default.img(src, {
			width: v.picElement.picWidth,
			height: v.picElement.picHeight,
			subType: v.picElement.picSubType
		}));
	} else if (v.pttElement) {
		const src = await ctx.ntFileApi.getPttUrl(v.pttElement.fileUuid, data.chatType === ChatType.Group);
		buffer.push(lib_default.audio(src, { duration: v.pttElement.duration }));
	} else if (v.videoElement) {
		const src = await ctx.ntFileApi.getVideoUrl(v.videoElement.fileUuid, data.chatType === ChatType.Group);
		buffer.push(lib_default.video(src));
	} else if (v.marketFaceElement) {
		const { emojiId, imageWidth, imageHeight } = v.marketFaceElement;
		const src = `https://gxh.vip.qq.com/club/item/parcel/item/${emojiId.substring(0, 2)}/${emojiId}/raw${imageWidth}.gif`;
		buffer.push(lib_default("llonebot:market-face", {
			emojiPackageId: v.marketFaceElement.emojiPackageId,
			emojiId,
			key: v.marketFaceElement.key,
			summary: v.marketFaceElement.faceName
		}, [lib_default.image(src, {
			width: imageWidth,
			height: imageHeight
		})]));
	} else if (v.faceElement) {
		const { faceIndex, faceType } = v.faceElement;
		buffer.push(lib_default("face", {
			id: String(faceIndex),
			type: String(faceType),
			platform: "llonebot"
		}));
	} else if (v.arkElement) buffer.push(lib_default("llonebot:ark", { data: v.arkElement.bytesData }));
	return buffer;
}
async function decodeMessage(ctx, data, message = {}) {
	const [guildId, channelId] = decodeGuildChannelId(data);
	const elements = await decodeElement(ctx, data);
	if (elements.length === 0) return;
	message.id = encodeMessageId(data.chatType, data.peerUid, data.msgSeq);
	message.content = elements.join("");
	message.channel = {
		id: channelId,
		name: data.peerName,
		type: guildId ? Channel.Type.TEXT : Channel.Type.DIRECT
	};
	message.user = {
		id: data.senderUin.toString(),
		name: data.sendNickName,
		avatar: `http://q.qlogo.cn/headimg_dl?dst_uin=${data.senderUin}&spec=640`,
		is_bot: robotUinRanges.some((e) => data.senderUin >= e.minUin && data.senderUin <= e.maxUin)
	};
	message.created_at = +data.msgTime * 1e3;
	if (!message.user.name) {
		const u = await ctx.ntUserApi.getUserByUid(data.senderUid);
		message.user.name = u.nick;
	}
	if (!message.channel.name && message.channel.type === Channel.Type.DIRECT) {
		const u = await ctx.ntUserApi.getUserByUid(data.peerUid);
		message.channel.name = u.nick;
	}
	if (guildId) {
		message.guild = {
			id: guildId,
			name: data.peerName,
			avatar: `https://p.qlogo.cn/gh/${guildId}/${guildId}/640`
		};
		message.member = {
			user: message.user,
			nick: data.sendMemberName
		};
	}
	return message;
}
function decodeGuildMember(data) {
	return {
		user: decodeUser(data),
		nick: data.cardName || data.nick,
		avatar: `http://q.qlogo.cn/headimg_dl?dst_uin=${data.uin}&spec=640`,
		joined_at: data.joinedAt * 1e3,
		roles: [{
			id: data.role.toString(),
			name: {
				[GroupMemberRole.Owner]: "owner",
				[GroupMemberRole.Admin]: "admin",
				[GroupMemberRole.Normal]: "member",
				[GroupMemberRole.NotApplicable]: "member"
			}[data.role]
		}]
	};
}
function decodeGuild(data) {
	return {
		id: data.groupCode.toString(),
		name: data.groupName,
		avatar: `https://p.qlogo.cn/gh/${data.groupCode}/${data.groupCode}/640`
	};
}
async function getPeer(ctx, channelId) {
	if (channelId.startsWith("private:")) {
		const uin = channelId.replace("private:", "");
		const uid = await ctx.ntUserApi.getUidByUin(+uin);
		if (!uid) throw new Error("无法获取用户信息");
		if (!await ctx.ntFriendApi.isFriend(uid)) return {
			chatType: ChatType.TempC2CFromGroup,
			peerUid: uid
		};
		return {
			chatType: ChatType.C2C,
			peerUid: uid
		};
	} else return {
		chatType: ChatType.Group,
		peerUid: channelId
	};
}
function encodeMessageId(chatType, peerUid, msgSeq) {
	return `${chatType}|${peerUid}|${msgSeq}`;
}
function decodeMessageId(messageId) {
	const [chatType, peerUid, msgSeq] = messageId.split("|");
	return {
		chatType: +chatType,
		peerUid,
		msgSeq: +msgSeq
	};
}
function encodeGroupRequestFlag$1(groupCode, seq, type, doubt) {
	return `${groupCode}|${seq}|${type}|${doubt ? 1 : 0}`;
}
function decodeGroupRequestFlag$1(flag) {
	const flagitem = flag.split("|");
	return {
		groupCode: +flagitem[0],
		seq: +flagitem[1],
		type: +flagitem[2],
		doubt: flagitem[3] === "1"
	};
}
//#endregion
//#region src/satori/api/guild/get.ts
var getGuild = async (ctx, payload) => {
	return decodeGuild(await ctx.ntGroupApi.getGroup(+payload.guild_id, true));
};
//#endregion
//#region src/satori/api/guild/list.ts
var getGuildList = async (ctx) => {
	return { data: (await ctx.ntGroupApi.getGroups(true)).map(decodeGuild) };
};
//#endregion
//#region src/satori/api/guild/approve.ts
var handleGuildRequest = async (ctx, payload) => {
	const info = decodeGroupRequestFlag$1(payload.message_id);
	const result = await ctx.ntGroupApi.setGroupRequest(info.doubt, info.groupCode, info.seq, info.type, payload.approve, payload.comment);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/login/get.ts
var getLogin = async (ctx) => {
	const features = [];
	for (const [feature, info] of Object.entries(Methods)) if (info.name in handlers) features.push(feature);
	features.push("guild.plain");
	await ctx.ntUserApi.getSelfNick();
	return {
		sn: ctx.get("satori")._loginSeq,
		user: decodeUser(selfInfo),
		adapter: "llonebot",
		platform: "llonebot",
		status: selfInfo.online ? Status.ONLINE : Status.OFFLINE,
		features,
		proxy_urls: []
	};
};
//#endregion
//#region src/satori/api/member/get.ts
var getGuildMember = async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.guild_id);
	if (!uid) throw new Error("无法获取用户信息");
	const member = await ctx.ntGroupApi.getGroupMemberByUid(+payload.guild_id, uid, true);
	if (!member) throw new Error("群组成员未找到");
	return decodeGuildMember(member);
};
//#endregion
//#region src/satori/api/member/list.ts
var getGuildMemberList = async (ctx, payload) => {
	return { data: (await ctx.ntGroupApi.getGroupMembers(+payload.guild_id, true)).map(decodeGuildMember) };
};
//#endregion
//#region src/satori/api/member/kick.ts
var kickGuildMember = async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.guild_id);
	if (!uid) throw new Error("无法获取用户信息");
	const result = await ctx.ntGroupApi.kickGroupMember(+payload.guild_id, [uid], Boolean(payload.permanent));
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/member/mute.ts
var muteGuildMember = async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.guild_id);
	if (!uid) throw new Error("无法获取用户信息");
	const result = await ctx.ntGroupApi.muteGroupMember(+payload.guild_id, [{
		uid,
		duration: payload.duration / 1e3
	}]);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/member/approve.ts
var handleGuildMemberRequest = async (ctx, payload) => {
	const info = decodeGroupRequestFlag$1(payload.message_id);
	const result = await ctx.ntGroupApi.setGroupRequest(info.doubt, info.groupCode, info.seq, info.type, payload.approve, payload.comment);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/message.ts
var State = class {
	type;
	author = {};
	children = [];
	constructor(type) {
		this.type = type;
	}
};
var MessageEncoder = class {
	ctx;
	channelId;
	errors = [];
	results = [];
	elements = [];
	deleteAfterSentFiles = [];
	stack = [new State("message")];
	peer;
	pLength;
	constructor(ctx, channelId) {
		this.ctx = ctx;
		this.channelId = channelId;
	}
	async flush() {
		if (this.elements.length === 0) return;
		if (this.pLength === this.elements.length) this.elements.pop();
		if (this.stack[0].type === "multiForward") {
			this.stack[0].children.push([...this.elements]);
			this.elements = [];
			this.pLength = void 0;
			return;
		}
		this.peer ??= await getPeer(this.ctx, this.channelId);
		const sent = await this.ctx.app.sendMessage(this.ctx, this.peer, this.elements, this.deleteAfterSentFiles);
		this.ctx.logger.info("消息发送", this.peer);
		const result = await decodeMessage(this.ctx, sent);
		if (result) this.results.push(result);
		this.deleteAfterSentFiles = [];
		this.elements = [];
		this.pLength = void 0;
	}
	async fetchFile(url) {
		const res = await uri2local(this.ctx, url);
		if (!res.success) {
			this.ctx.logger.error(res.errMsg);
			throw Error(res.errMsg);
		}
		if (!res.isLocal) this.deleteAfterSentFiles.push(res.path);
		return res.path;
	}
	async getPeerAndElementsFromMsgSeq(peerUid, msgSeq) {
		this.peer ??= await getPeer(this.ctx, this.channelId);
		const cacheMsg = this.ctx.store.getMsgBySeq(peerUid, msgSeq);
		if (cacheMsg) return {
			peer: {
				peerUid: cacheMsg.peerUid,
				chatType: cacheMsg.chatType
			},
			elements: cacheMsg.elements
		};
		const { msgList } = await this.ctx.ntMsgApi.getSingleMsg(this.peer, msgSeq);
		if (msgList[0]) return {
			peer: {
				peerUid: msgList[0].peerUid,
				chatType: msgList[0].chatType
			},
			elements: msgList[0].elements
		};
	}
	async multiForward() {
		if (!this.stack[0].children.length) return;
		this.peer ??= await getPeer(this.ctx, this.channelId);
		const nodes = [];
		let seq = Math.trunc(Math.random() * 65430);
		for (const item of this.stack[0].children) {
			let ntElems = [];
			if (typeof item === "string") {
				const { peerUid, msgSeq } = decodeMessageId(item);
				const info = await this.getPeerAndElementsFromMsgSeq(peerUid, msgSeq);
				if (!info) {
					this.ctx.logger.warn("转发消息失败，未找到消息", item);
					continue;
				}
				const isGroup = this.peer.chatType === ChatType.Group;
				for (const element of info.elements) if (element.elementType === ElementType.Text) ntElems.push(element);
				else if (element.elementType === ElementType.Pic) {
					const { originImageUrl, md5HexStr } = element.picElement;
					const url = await this.ctx.ntFileApi.getImageUrl(originImageUrl, md5HexStr);
					const path = await this.fetchFile(url);
					ntElems.push(await SendElement.pic(this.ctx, path));
				} else if (element.elementType === ElementType.Ptt) {
					const { fileUuid } = element.pttElement;
					const url = await this.ctx.ntFileApi.getPttUrl(fileUuid, isGroup);
					const path = await this.fetchFile(url);
					ntElems.push(await SendElement.ptt(this.ctx, path));
				} else if (element.elementType === ElementType.Video) {
					const { fileUuid } = element.videoElement;
					const url = await this.ctx.ntFileApi.getVideoUrl(fileUuid, isGroup);
					const path = await this.fetchFile(url);
					ntElems.push(await SendElement.video(this.ctx, path));
				} else if (element.elementType === ElementType.Reply) ntElems.push(element);
				else if (element.elementType === ElementType.Face) ntElems.push(element);
				else if (element.elementType === ElementType.MarketFace) ntElems.push(element);
			} else ntElems = item;
			const nick = this.stack[0].author.name ?? selfInfo.nick;
			const uin = this.stack[0].author.id ?? selfInfo.uin;
			nodes.push({
				senderUin: +uin,
				senderName: nick,
				elements: ntElems,
				msgSeq: seq++
			});
		}
		const forward = SendElement.forward(nodes);
		if (this.stack[1].type === "multiForward") this.stack[1].children.push([forward]);
		else {
			const sent = await this.ctx.app.sendMessage(this.ctx, this.peer, [forward], this.deleteAfterSentFiles);
			const result = await decodeMessage(this.ctx, sent);
			if (result) this.results.push(result);
			this.deleteAfterSentFiles = [];
		}
	}
	async visit(element) {
		const { type, attrs, children } = element;
		if (type === "text") this.elements.push(SendElement.text(attrs.content));
		else if (type === "at") {
			this.peer ??= await getPeer(this.ctx, this.channelId);
			if (this.peer.chatType !== ChatType.Group) return;
			if (attrs.type === "all") this.elements.push(SendElement.at(0, AtType.All, "@全体成员"));
			else {
				const uin = +attrs.id;
				let display;
				if (attrs.name) display = `@${attrs.name}`;
				else {
					const info = await this.ctx.ntGroupApi.getGroupMemberByUin(+this.peer.peerUid, uin, false);
					display = `@${info?.cardName || info?.nick || ""}`;
				}
				this.elements.push(SendElement.at(uin, AtType.One, display));
			}
		} else if (type === "a") {
			await this.render(children);
			const prev = this.elements.at(-1);
			if (prev?.elementType === 1 && prev.textElement.atType === 0) prev.textElement.content += ` ( ${attrs.href} )`;
		} else if (type === "img" || type === "image") {
			const url = attrs.src ?? attrs.url;
			const path = await this.fetchFile(url);
			const element = await SendElement.pic(this.ctx, path);
			this.elements.push(element);
		} else if (type === "audio") {
			await this.flush();
			const url = attrs.src ?? attrs.url;
			const path = await this.fetchFile(url);
			this.elements.push(await SendElement.ptt(this.ctx, path));
			await this.flush();
		} else if (type === "video") {
			await this.flush();
			const url = attrs.src ?? attrs.url;
			const path = await this.fetchFile(url);
			let thumb;
			if (attrs.poster) thumb = await this.fetchFile(attrs.poster);
			const element = await SendElement.video(this.ctx, path, thumb);
			this.elements.push(element);
			await this.flush();
		} else if (type === "file") {
			await this.flush();
			const url = attrs.src ?? attrs.url;
			const path$10 = await this.fetchFile(url);
			attrs.title ?? path.basename(path$10);
			await this.flush();
		} else if (type === "br") this.elements.push(SendElement.text("\n"));
		else if (type === "p") {
			const prev = this.elements.at(-1);
			if (prev?.elementType === 1 && prev.textElement.atType === 0) {
				if (!prev.textElement.content.endsWith("\n")) prev.textElement.content += "\n";
			} else if (prev) this.elements.push(SendElement.text("\n"));
			await this.render(children);
			this.pLength = this.elements.push(SendElement.text("\n"));
		} else if (type === "message") if (attrs.forward) {
			await this.flush();
			this.stack.unshift(new State("multiForward"));
			await this.render(children);
			await this.flush();
			await this.multiForward();
			this.stack.shift();
		} else if (attrs.id && this.stack[0].type === "multiForward") this.stack[0].children.push(attrs.id);
		else {
			await this.render(children);
			await this.flush();
		}
		else if (type === "quote") {
			this.peer ??= await getPeer(this.ctx, this.channelId);
			const { peerUid, msgSeq } = decodeMessageId(attrs.id);
			let source = this.ctx.store.getMsgBySeq(peerUid, msgSeq);
			if (!source) {
				const { msgList } = await this.ctx.ntMsgApi.getSingleMsg(this.peer, msgSeq);
				source = msgList[0];
			}
			if (source) this.elements.push(SendElement.reply(source.msgSeq, source.senderUin, source.senderUid, source.msgTime, source.clientSeq));
		} else if (type === "face") this.elements.push(SendElement.face(+attrs.id, +attrs.type));
		else if (type === "author") Object.assign(this.stack[0].author, attrs);
		else if (type === "llonebot:market-face") this.elements.push(SendElement.mface(+attrs.emojiPackageId, attrs.emojiId, attrs.key, attrs.summary));
		else await this.render(children);
	}
	async render(elements, flush) {
		for (const element of elements) await this.visit(element);
		if (flush) await this.flush();
	}
	async send(content) {
		const elements = lib_default.normalize(content);
		await this.render(elements);
		await this.flush();
		if (this.errors.length) throw new AggregateError(this.errors);
		else return this.results;
	}
};
//#endregion
//#region src/satori/api/message/create.ts
var createMessage = async (ctx, payload) => {
	return await new MessageEncoder(ctx, payload.channel_id).send(payload.content);
};
//#endregion
//#region src/satori/api/message/get.ts
var getMessage = async (ctx, payload) => {
	const info = decodeMessageId(payload.message_id);
	let msg = ctx.store.getMsgBySeq(info.peerUid, info.msgSeq);
	if (!msg) {
		const { msgList } = await ctx.ntMsgApi.getSingleMsg(info, info.msgSeq);
		msg = msgList[0];
	}
	if (!msg) throw new Error("获取不到消息");
	const result = await decodeMessage(ctx, msg);
	if (!result) throw new Error("消息为空");
	return result;
};
//#endregion
//#region src/satori/api/message/delete.ts
var deleteMessage = async (ctx, payload) => {
	const info = decodeMessageId(payload.message_id);
	if (info.chatType === ChatType.Group) await ctx.ntMsgApi.recallMsg(info, info.msgSeq);
	else {
		let msg = ctx.store.getMsgBySeq(info.peerUid, info.msgSeq);
		if (!msg) {
			const { msgList } = await ctx.ntMsgApi.getSingleMsg(info, info.msgSeq);
			msg = msgList[0];
		}
		await ctx.ntMsgApi.recallMsg(info, msg.msgSeq, msg.clientSeq, msg.msgRandom, msg.msgTime);
	}
	return {};
};
//#endregion
//#region src/satori/api/message/list.ts
var getMessageList = async (ctx, payload) => {
	const count = payload.limit ?? 50;
	const peer = await getPeer(ctx, payload.channel_id);
	let msgList;
	if (!payload.next) {
		const latestSeq = await ctx.ntMsgApi.getLatestMsgSeq(peer);
		msgList = (await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, latestSeq, count, true)).msgList;
	} else msgList = (await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, +payload.next, count, true)).msgList;
	const data = filterNullable(await Promise.all(msgList.map((e) => decodeMessage(ctx, e))));
	if (payload.order === "desc") data.reverse();
	const finallyMsg = msgList.at(-1);
	return {
		data,
		next: finallyMsg ? encodeMessageId(finallyMsg.chatType, finallyMsg.peerUid, finallyMsg.msgSeq) : void 0
	};
};
//#endregion
//#region src/satori/api/reaction/create.ts
var createReaction = async (ctx, payload) => {
	const info = decodeMessageId(payload.message_id);
	if (info.chatType !== ChatType.Group) throw new Error("暂不支持私聊消息回应");
	const result = await ctx.ntMsgApi.setGroupMsgReaction(+info.peerUid, info.msgSeq, payload.emoji_id, true);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/reaction/delete.ts
var deleteReaction = async (ctx, payload) => {
	const info = decodeMessageId(payload.message_id);
	if (info.chatType !== ChatType.Group) throw new Error("暂不支持私聊消息回应");
	const result = await ctx.ntMsgApi.setGroupMsgReaction(+info.peerUid, info.msgSeq, payload.emoji_id, false);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/reaction/list.ts
var getReactionList = async (ctx, payload) => {
	const info = decodeMessageId(payload.message_id);
	if (info.chatType !== ChatType.Group) throw new Error("暂不支持私聊消息回应");
	const data = await ctx.ntMsgApi.getMsgReactionList(info, info.msgSeq, payload.emoji_id, 15, payload.next ?? "");
	return {
		data: (await Promise.all(data.users.map((e) => ctx.ntUserApi.getUserByUin(e.uin)))).map((u) => decodeUser(u)),
		next: data.cookie || void 0
	};
};
//#endregion
//#region src/satori/api/role/member/set.ts
var setGuildMemberRole = async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id, +payload.guild_id);
	if (!uid) throw new Error("无法获取用户信息");
	const result = await ctx.ntGroupApi.setGroupMemberAdmin(+payload.guild_id, uid, payload.role_id === "2");
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/role/list.ts
var getGuildRoleList = () => {
	return { data: [
		{
			id: "1",
			name: "owner"
		},
		{
			id: "2",
			name: "admin"
		},
		{
			id: "0",
			name: "member"
		}
	] };
};
//#endregion
//#region src/satori/api/user/get.ts
var getUser = async (ctx, payload) => {
	return decodeUser(await ctx.ntUserApi.getUserByUin(+payload.user_id));
};
//#endregion
//#region src/satori/api/friend/list.ts
var getFriendList = async (ctx) => {
	return { data: (await ctx.ntFriendApi.getFriends(true)).friends.map((e) => ({
		user: decodeUser(e),
		nick: e.remark
	})) };
};
//#endregion
//#region src/satori/api/friend/approve.ts
var handleFriendRequest = async (ctx, payload) => {
	await ctx.ntFriendApi.approvalFriendRequest(payload.message_id, payload.approve);
	return {};
};
//#endregion
//#region src/satori/api/friend/delete.ts
var deleteFriend = async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(+payload.user_id);
	if (!uid) throw new Error("无法获取用户信息");
	const result = await ctx.ntFriendApi.deleteFriend(uid);
	if (result.errorCode !== 0) throw new Error(result.errorMsg);
	return {};
};
//#endregion
//#region src/satori/api/index.ts
var handlers = {
	getChannel,
	getChannelList,
	updateChannel,
	deleteChannel,
	muteChannel,
	createDirectChannel,
	getGuild,
	getGuildList,
	handleGuildRequest,
	getLogin,
	getGuildMember,
	getGuildMemberList,
	kickGuildMember,
	muteGuildMember,
	handleGuildMemberRequest,
	createMessage,
	getMessage,
	deleteMessage,
	getMessageList,
	createReaction,
	deleteReaction,
	getReactionList,
	setGuildMemberRole,
	getGuildRoleList,
	getUser,
	getFriendList,
	handleFriendRequest,
	deleteFriend
};
//#endregion
//#region src/satori/server.ts
var SatoriServer = class {
	ctx;
	config;
	app;
	httpServer;
	wsServer;
	wsClients = [];
	actionMap;
	routesRegistered = false;
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
		this.app = new Hono();
	}
	async callOneBot11API(action, params) {
		const onebotAdapter = this.ctx.get("onebot");
		if (onebotAdapter) this.actionMap ??= initActionMap(onebotAdapter);
		else throw new Error(`OB11 service has not started`);
		const handler = this.actionMap.get(action);
		if (!handler) throw new Error(`Unsupported OB11 action: ${action}`);
		return await handler.handle(params, {
			messageFormat: "array",
			debug: false
		});
	}
	async handleOneBotRequest(c, next) {
		const action = c.req.param("action");
		const payload = c.req.method === "POST" ? await c.req.json() : c.req.query();
		let result;
		try {
			result = await this.callOneBot11API(action, payload);
		} catch (e) {
			result = OB11Response.error(e.message, 200);
		}
		return c.json(result);
	}
	start() {
		if (!this.routesRegistered) {
			this.registerRoutes();
			this.routesRegistered = true;
		}
		const { host, port } = this.config;
		const wss = new WebSocketServer({
			noServer: true,
			maxPayload: constants$1.MAX_STRING_LENGTH
		});
		this.httpServer = serve({
			fetch: this.app.fetch,
			websocket: { server: wss },
			port,
			hostname: host
		}, () => {
			this.ctx.logger.info(`Satori server started ${host || "0.0.0.0"}:${port}`);
		});
	}
	registerRoutes() {
		this.app.get("/v1/events", upgradeWebSocket((c) => {
			return {
				onMessage: async (event, ws) => {
					let payload;
					try {
						payload = JSON.parse(event.data.toString());
					} catch {
						return ws.close(4e3, "invalid message");
					}
					if (payload.op === Opcode.IDENTIFY) {
						if (this.config.token && payload.body?.token !== this.config.token) return ws.close(4004, "invalid token");
						this.ctx.logger.info("ws connect", c.req.path);
						ws.send(JSON.stringify({
							op: Opcode.READY,
							body: {
								logins: [await handlers.getLogin(this.ctx, {})],
								proxy_urls: []
							}
						}));
						this.wsClients.push(ws);
					} else if (payload.op === Opcode.PING) ws.send(JSON.stringify({
						op: Opcode.PONG,
						body: {}
					}));
				},
				onClose: (_evt, ws) => {
					this.wsClients = this.wsClients.filter((c) => c !== ws);
				}
			};
		}));
		this.app.use("/v1/*", cors());
		this.app.use("/v1/*", this.checkAuth.bind(this));
		this.app.use("/v1/internal/onebot11/:action", this.handleOneBotRequest.bind(this));
		this.app.get("/v1/*", async (c) => {
			return c.text("Please use POST method to send requests.", 405);
		});
		this.app.post("/v1/:name", async (c) => {
			const selfId = c.req.header("Satori-User-ID");
			const platform = c.req.header("Satori-Platform");
			if (selfId !== selfInfo.uin || !platform) return c.text("login not found", 403);
			const method = Methods[c.req.param("name")];
			if (!method) return c.text("method not found", 404);
			const handle = handlers[method.name];
			if (!handle) return c.text("method not found", 404);
			try {
				const result = await handle(this.ctx, await c.req.json());
				return c.json(result);
			} catch (e) {
				this.ctx.logger.error(e);
				return c.text(e.message, 500);
			}
		});
	}
	async stop() {
		for (const socket of this.wsClients) try {
			if (socket.readyState === WebSocket$1.OPEN) socket.close();
		} catch {}
		this.wsClients = [];
		if (this.wsServer) {
			await new Promise((resolve) => {
				this.wsServer.close(() => resolve());
			});
			this.wsServer = void 0;
		}
		if (this.httpServer) {
			await new Promise((resolve) => {
				this.httpServer.close(() => resolve());
			});
			this.httpServer = void 0;
		}
	}
	async checkAuth(c, next) {
		if (!this.config.token) return await next();
		if (c.req.header("Authorization") !== `Bearer ${this.config.token}`) return c.text("invalid token", 403);
		await next();
	}
	async dispatch(body) {
		this.wsClients.forEach((socket) => {
			if (socket.readyState === WebSocket$1.OPEN) {
				socket.send(JSON.stringify({
					op: Opcode.EVENT,
					body
				}));
				this.ctx.logger.info("WebSocket 事件上报", body.type);
			}
		});
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
};
//#endregion
//#region src/satori/event/message.ts
async function parseMessageCreated(bot, data) {
	const message = await decodeMessage(bot.ctx, data.message);
	if (!message) return;
	return bot.event("message-created", {
		message: omit$1(message, [
			"member",
			"user",
			"channel",
			"guild"
		]),
		member: message.member,
		user: message.user,
		channel: message.channel,
		guild: message.guild
	});
}
async function parseMessageDeleted(bot, data) {
	const [guildId, channelId] = decodeGuildChannelId({
		chatType: data.chatType,
		peerUid: data.peerUid,
		peerUin: data.peerUin
	});
	return bot.event("message-deleted", {
		message: { id: encodeMessageId(data.chatType, data.peerUid, data.msgSeq) },
		member: guildId ? { user: { id: data.senderUin.toString() } } : void 0,
		user: { id: data.senderUin.toString() },
		channel: {
			id: channelId,
			type: guildId ? Channel.Type.TEXT : Channel.Type.DIRECT
		},
		guild: guildId ? { id: guildId } : void 0,
		operator: { id: data.operatorUin.toString() }
	});
}
//#endregion
//#region src/satori/event/guild.ts
async function parseGuildAdded(bot, data) {
	return bot.event("guild-added", { guild: { id: data.groupCode.toString() } });
}
async function parseGuildUpdated(bot, data) {
	return bot.event("guild-updated", { guild: {
		id: data.groupCode.toString(),
		name: data.newGroupName
	} });
}
async function parseGuildRemoved(bot, data) {
	return bot.event("guild-removed", { guild: { id: data.groupCode.toString() } });
}
async function parseGuildRequest(bot, data) {
	return bot.event("guild-request", {
		guild: { id: data.groupCode.toString() },
		message: { id: encodeGroupRequestFlag$1(data.groupCode, data.invitationSeq, GroupNotificationType.Invitation, false) },
		operator: { id: data.initiatorUin.toString() }
	});
}
//#endregion
//#region src/satori/event/member.ts
async function parseGuildMemberAdded(bot, data) {
	return bot.event("guild-member-added", {
		guild: { id: data.groupCode.toString() },
		user: { id: data.memberUin.toString() },
		member: { user: { id: data.memberUin.toString() } }
	});
}
async function parseGuildMemberRemoved(bot, data) {
	return bot.event("guild-member-removed", {
		guild: { id: data.groupCode.toString() },
		user: { id: data.memberUin.toString() },
		member: { user: { id: data.memberUin.toString() } }
	});
}
async function parseGuildMemberRequest(bot, data, type) {
	return bot.event("guild-member-request", {
		guild: { id: data.groupCode.toString() },
		member: { user: { id: data.initiatorUin.toString() } },
		user: { id: data.initiatorUin.toString() },
		message: {
			id: encodeGroupRequestFlag$1(data.groupCode, data.notificationSeq, type, "isDoubt" in data ? data.isDoubt : false),
			content: "comment" in data ? data.comment : ""
		}
	});
}
//#endregion
//#region src/satori/event/friend.ts
async function parseFriendRequest(bot, data) {
	return bot.event("friend-request", {
		user: { id: data.initiatorUin.toString() },
		message: {
			id: data.initiatorUid,
			content: data.comment
		}
	});
}
//#endregion
//#region src/satori/event/reaction.ts
function buildReactionPayload(data) {
	return {
		message: { id: encodeMessageId(ChatType.Group, data.groupCode.toString(), data.msgSeq) },
		channel: {
			id: data.groupCode.toString(),
			type: Channel.Type.TEXT
		},
		guild: { id: data.groupCode.toString() },
		user: { id: data.operatorUin?.toString() ?? "" },
		member: { user: { id: data.operatorUin?.toString() ?? "" } },
		emoji: { id: data.faceId }
	};
}
async function parseReactionAdded(bot, data) {
	return bot.event("reaction-added", buildReactionPayload(data));
}
async function parseReactionRemoved(bot, data) {
	return bot.event("reaction-removed", buildReactionPayload(data));
}
//#endregion
//#region src/satori/adapter.ts
var SatoriAdapter = class extends Service {
	ctx;
	config;
	static inject = [
		"ntMsgApi",
		"ntFileApi",
		"ntFriendApi",
		"ntGroupApi",
		"ntUserApi",
		"ntWebApi",
		"store",
		"app"
	];
	selfId;
	server;
	_eventSeq;
	_loginSeq;
	listenedEvent = false;
	constructor(ctx, config) {
		super(ctx, "satori");
		this.ctx = ctx;
		this.config = config;
		this.selfId = selfInfo.uin;
		this.server = new SatoriServer(ctx, config);
		this._eventSeq = 0;
		this._loginSeq = 1;
	}
	async [Service.init]() {
		this.start();
		return noop;
	}
	start() {
		this.ctx.on("llob/config-updated", async (input) => {
			const old = omit$1(this.config, ["ffmpeg"]);
			const inputSatoriConfig = input.satori;
			if (!isDeepStrictEqual(old, inputSatoriConfig)) {
				await this.server.stop();
				this.server.updateConfig(inputSatoriConfig);
				if (inputSatoriConfig.enable) {
					this.server.start();
					this.listenEvent();
				}
			}
			Object.assign(this.config, {
				...inputSatoriConfig,
				ffmpeg: input.ffmpeg
			});
		});
		if (this.config.enable) this.server.start();
		else return;
		this.listenEvent();
	}
	listenEvent() {
		if (this.listenedEvent) return;
		this.listenedEvent = true;
		this.ctx.on("nt/message-created", async (data) => {
			const event = await parseMessageCreated(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/message-deleted", async (data) => {
			const event = await parseMessageDeleted(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-join-request", async (data) => {
			const type = GroupNotificationType.JoinRequest;
			const event = await parseGuildMemberRequest(this, data, type).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-invited-join-request", async (data) => {
			const type = GroupNotificationType.InvitedJoinRequest;
			const event = await parseGuildMemberRequest(this, data, type).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-invitation", async (data) => {
			const event = await parseGuildRequest(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-added", async (data) => {
			const event = await parseGuildAdded(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-removed", async (data) => {
			const event = await parseGuildRemoved(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-name-changed", async (data) => {
			const event = await parseGuildUpdated(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-message-reaction", async (data) => {
			const event = data.isAdd ? await parseReactionAdded(this, data).catch((e) => this.ctx.logger.error(e)) : await parseReactionRemoved(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-member-added", async (data) => {
			const event = await parseGuildMemberAdded(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/group-member-removed", async (data) => {
			const event = await parseGuildMemberRemoved(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
		this.ctx.on("nt/friend-request", async (data) => {
			const event = await parseFriendRequest(this, data).catch((e) => this.ctx.logger.error(e));
			if (event) this.server.dispatch(event);
		});
	}
	event(type, data) {
		const sn = ++this._eventSeq;
		return {
			id: sn,
			sn,
			type,
			self_id: this.selfId,
			platform: "llonebot",
			timestamp: Date.now(),
			login: {
				sn: this._loginSeq,
				user: decodeUser(selfInfo),
				platform: "llonebot"
			},
			...data
		};
	}
};
//#endregion
//#region node_modules/zod/v4/core/core.js
var _a$1;
/** A special constant with type `never` */
var NEVER = /*@__PURE__*/ Object.freeze({ status: "aborted" });
function $constructor(name, initializer, params) {
	function init(inst, def) {
		if (!inst._zod) Object.defineProperty(inst, "_zod", {
			value: {
				def,
				constr: _,
				traits: /* @__PURE__ */ new Set()
			},
			enumerable: false
		});
		if (inst._zod.traits.has(name)) return;
		inst._zod.traits.add(name);
		initializer(inst, def);
		const proto = _.prototype;
		const keys = Object.keys(proto);
		for (let i = 0; i < keys.length; i++) {
			const k = keys[i];
			if (!(k in inst)) inst[k] = proto[k].bind(inst);
		}
	}
	const Parent = params?.Parent ?? Object;
	class Definition extends Parent {}
	Object.defineProperty(Definition, "name", { value: name });
	function _(def) {
		var _a;
		const inst = params?.Parent ? new Definition() : this;
		init(inst, def);
		(_a = inst._zod).deferred ?? (_a.deferred = []);
		for (const fn of inst._zod.deferred) fn();
		return inst;
	}
	Object.defineProperty(_, "init", { value: init });
	Object.defineProperty(_, Symbol.hasInstance, { value: (inst) => {
		if (params?.Parent && inst instanceof params.Parent) return true;
		return inst?._zod?.traits?.has(name);
	} });
	Object.defineProperty(_, "name", { value: name });
	return _;
}
var $brand = Symbol("zod_brand");
var $ZodAsyncError = class extends Error {
	constructor() {
		super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
	}
};
var $ZodEncodeError = class extends Error {
	constructor(name) {
		super(`Encountered unidirectional transform during encode: ${name}`);
		this.name = "ZodEncodeError";
	}
};
(_a$1 = globalThis).__zod_globalConfig ?? (_a$1.__zod_globalConfig = {});
var globalConfig = globalThis.__zod_globalConfig;
function config(newConfig) {
	if (newConfig) Object.assign(globalConfig, newConfig);
	return globalConfig;
}
//#endregion
//#region node_modules/zod/v4/core/util.js
var util_exports = /* @__PURE__ */ __exportAll({
	BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
	Class: () => Class,
	NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
	aborted: () => aborted,
	allowsEval: () => allowsEval,
	assert: () => assert$1,
	assertEqual: () => assertEqual,
	assertIs: () => assertIs,
	assertNever: () => assertNever,
	assertNotEqual: () => assertNotEqual,
	assignProp: () => assignProp,
	base64ToUint8Array: () => base64ToUint8Array,
	base64urlToUint8Array: () => base64urlToUint8Array,
	cached: () => cached,
	captureStackTrace: () => captureStackTrace,
	cleanEnum: () => cleanEnum,
	cleanRegex: () => cleanRegex,
	clone: () => clone,
	cloneDef: () => cloneDef,
	createTransparentProxy: () => createTransparentProxy,
	defineLazy: () => defineLazy,
	esc: () => esc,
	escapeRegex: () => escapeRegex,
	explicitlyAborted: () => explicitlyAborted,
	extend: () => extend,
	finalizeIssue: () => finalizeIssue,
	floatSafeRemainder: () => floatSafeRemainder,
	getElementAtPath: () => getElementAtPath,
	getEnumValues: () => getEnumValues,
	getLengthableOrigin: () => getLengthableOrigin,
	getParsedType: () => getParsedType,
	getSizableOrigin: () => getSizableOrigin,
	hexToUint8Array: () => hexToUint8Array,
	isObject: () => isObject,
	isPlainObject: () => isPlainObject,
	issue: () => issue,
	joinValues: () => joinValues,
	jsonStringifyReplacer: () => jsonStringifyReplacer,
	merge: () => merge,
	mergeDefs: () => mergeDefs,
	normalizeParams: () => normalizeParams,
	nullish: () => nullish$1,
	numKeys: () => numKeys,
	objectClone: () => objectClone,
	omit: () => omit,
	optionalKeys: () => optionalKeys,
	parsedType: () => parsedType,
	partial: () => partial,
	pick: () => pick,
	prefixIssues: () => prefixIssues,
	primitiveTypes: () => primitiveTypes,
	promiseAllObject: () => promiseAllObject,
	propertyKeyTypes: () => propertyKeyTypes,
	randomString: () => randomString,
	required: () => required,
	safeExtend: () => safeExtend,
	shallowClone: () => shallowClone,
	slugify: () => slugify,
	stringifyPrimitive: () => stringifyPrimitive,
	uint8ArrayToBase64: () => uint8ArrayToBase64,
	uint8ArrayToBase64url: () => uint8ArrayToBase64url,
	uint8ArrayToHex: () => uint8ArrayToHex,
	unwrapMessage: () => unwrapMessage
});
function assertEqual(val) {
	return val;
}
function assertNotEqual(val) {
	return val;
}
function assertIs(_arg) {}
function assertNever(_x) {
	throw new Error("Unexpected value in exhaustive check");
}
function assert$1(_) {}
function getEnumValues(entries) {
	const numericValues = Object.values(entries).filter((v) => typeof v === "number");
	return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
}
function joinValues(array, separator = "|") {
	return array.map((val) => stringifyPrimitive(val)).join(separator);
}
function jsonStringifyReplacer(_, value) {
	if (typeof value === "bigint") return value.toString();
	return value;
}
function cached(getter) {
	return { get value() {
		{
			const value = getter();
			Object.defineProperty(this, "value", { value });
			return value;
		}
	} };
}
function nullish$1(input) {
	return input === null || input === void 0;
}
function cleanRegex(source) {
	const start = source.startsWith("^") ? 1 : 0;
	const end = source.endsWith("$") ? source.length - 1 : source.length;
	return source.slice(start, end);
}
function floatSafeRemainder(val, step) {
	const ratio = val / step;
	const roundedRatio = Math.round(ratio);
	const tolerance = Number.EPSILON * Math.max(Math.abs(ratio), 1);
	if (Math.abs(ratio - roundedRatio) < tolerance) return 0;
	return ratio - roundedRatio;
}
var EVALUATING = /* @__PURE__*/ Symbol("evaluating");
function defineLazy(object, key, getter) {
	let value = void 0;
	Object.defineProperty(object, key, {
		get() {
			if (value === EVALUATING) return;
			if (value === void 0) {
				value = EVALUATING;
				value = getter();
			}
			return value;
		},
		set(v) {
			Object.defineProperty(object, key, { value: v });
		},
		configurable: true
	});
}
function objectClone(obj) {
	return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
}
function assignProp(target, prop, value) {
	Object.defineProperty(target, prop, {
		value,
		writable: true,
		enumerable: true,
		configurable: true
	});
}
function mergeDefs(...defs) {
	const mergedDescriptors = {};
	for (const def of defs) {
		const descriptors = Object.getOwnPropertyDescriptors(def);
		Object.assign(mergedDescriptors, descriptors);
	}
	return Object.defineProperties({}, mergedDescriptors);
}
function cloneDef(schema) {
	return mergeDefs(schema._zod.def);
}
function getElementAtPath(obj, path) {
	if (!path) return obj;
	return path.reduce((acc, key) => acc?.[key], obj);
}
function promiseAllObject(promisesObj) {
	const keys = Object.keys(promisesObj);
	const promises = keys.map((key) => promisesObj[key]);
	return Promise.all(promises).then((results) => {
		const resolvedObj = {};
		for (let i = 0; i < keys.length; i++) resolvedObj[keys[i]] = results[i];
		return resolvedObj;
	});
}
function randomString(length = 10) {
	const chars = "abcdefghijklmnopqrstuvwxyz";
	let str = "";
	for (let i = 0; i < length; i++) str += chars[Math.floor(Math.random() * 26)];
	return str;
}
function esc(str) {
	return JSON.stringify(str);
}
function slugify(input) {
	return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
}
var captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
function isObject(data) {
	return typeof data === "object" && data !== null && !Array.isArray(data);
}
var allowsEval = /* @__PURE__*/ cached(() => {
	if (globalConfig.jitless) return false;
	if (typeof navigator !== "undefined" && navigator?.userAgent?.includes("Cloudflare")) return false;
	try {
		new Function("");
		return true;
	} catch (_) {
		return false;
	}
});
function isPlainObject(o) {
	if (isObject(o) === false) return false;
	const ctor = o.constructor;
	if (ctor === void 0) return true;
	if (typeof ctor !== "function") return true;
	const prot = ctor.prototype;
	if (isObject(prot) === false) return false;
	if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) return false;
	return true;
}
function shallowClone(o) {
	if (isPlainObject(o)) return { ...o };
	if (Array.isArray(o)) return [...o];
	if (o instanceof Map) return new Map(o);
	if (o instanceof Set) return new Set(o);
	return o;
}
function numKeys(data) {
	let keyCount = 0;
	for (const key in data) if (Object.prototype.hasOwnProperty.call(data, key)) keyCount++;
	return keyCount;
}
var getParsedType = (data) => {
	const t = typeof data;
	switch (t) {
		case "undefined": return "undefined";
		case "string": return "string";
		case "number": return Number.isNaN(data) ? "nan" : "number";
		case "boolean": return "boolean";
		case "function": return "function";
		case "bigint": return "bigint";
		case "symbol": return "symbol";
		case "object":
			if (Array.isArray(data)) return "array";
			if (data === null) return "null";
			if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") return "promise";
			if (typeof Map !== "undefined" && data instanceof Map) return "map";
			if (typeof Set !== "undefined" && data instanceof Set) return "set";
			if (typeof Date !== "undefined" && data instanceof Date) return "date";
			if (typeof File !== "undefined" && data instanceof File) return "file";
			return "object";
		default: throw new Error(`Unknown data type: ${t}`);
	}
};
var propertyKeyTypes = /* @__PURE__*/ new Set([
	"string",
	"number",
	"symbol"
]);
var primitiveTypes = /* @__PURE__*/ new Set([
	"string",
	"number",
	"bigint",
	"boolean",
	"symbol",
	"undefined"
]);
function escapeRegex(str) {
	return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function clone(inst, def, params) {
	const cl = new inst._zod.constr(def ?? inst._zod.def);
	if (!def || params?.parent) cl._zod.parent = inst;
	return cl;
}
function normalizeParams(_params) {
	const params = _params;
	if (!params) return {};
	if (typeof params === "string") return { error: () => params };
	if (params?.message !== void 0) {
		if (params?.error !== void 0) throw new Error("Cannot specify both `message` and `error` params");
		params.error = params.message;
	}
	delete params.message;
	if (typeof params.error === "string") return {
		...params,
		error: () => params.error
	};
	return params;
}
function createTransparentProxy(getter) {
	let target;
	return new Proxy({}, {
		get(_, prop, receiver) {
			target ?? (target = getter());
			return Reflect.get(target, prop, receiver);
		},
		set(_, prop, value, receiver) {
			target ?? (target = getter());
			return Reflect.set(target, prop, value, receiver);
		},
		has(_, prop) {
			target ?? (target = getter());
			return Reflect.has(target, prop);
		},
		deleteProperty(_, prop) {
			target ?? (target = getter());
			return Reflect.deleteProperty(target, prop);
		},
		ownKeys(_) {
			target ?? (target = getter());
			return Reflect.ownKeys(target);
		},
		getOwnPropertyDescriptor(_, prop) {
			target ?? (target = getter());
			return Reflect.getOwnPropertyDescriptor(target, prop);
		},
		defineProperty(_, prop, descriptor) {
			target ?? (target = getter());
			return Reflect.defineProperty(target, prop, descriptor);
		}
	});
}
function stringifyPrimitive(value) {
	if (typeof value === "bigint") return value.toString() + "n";
	if (typeof value === "string") return `"${value}"`;
	return `${value}`;
}
function optionalKeys(shape) {
	return Object.keys(shape).filter((k) => {
		return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
	});
}
var NUMBER_FORMAT_RANGES = {
	safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],
	int32: [-2147483648, 2147483647],
	uint32: [0, 4294967295],
	float32: [-34028234663852886e22, 34028234663852886e22],
	float64: [-Number.MAX_VALUE, Number.MAX_VALUE]
};
var BIGINT_FORMAT_RANGES = {
	int64: [/* @__PURE__*/ BigInt("-9223372036854775808"), /* @__PURE__*/ BigInt("9223372036854775807")],
	uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt("18446744073709551615")]
};
function pick(schema, mask) {
	const currDef = schema._zod.def;
	const checks = currDef.checks;
	if (checks && checks.length > 0) throw new Error(".pick() cannot be used on object schemas containing refinements");
	return clone(schema, mergeDefs(schema._zod.def, {
		get shape() {
			const newShape = {};
			for (const key in mask) {
				if (!(key in currDef.shape)) throw new Error(`Unrecognized key: "${key}"`);
				if (!mask[key]) continue;
				newShape[key] = currDef.shape[key];
			}
			assignProp(this, "shape", newShape);
			return newShape;
		},
		checks: []
	}));
}
function omit(schema, mask) {
	const currDef = schema._zod.def;
	const checks = currDef.checks;
	if (checks && checks.length > 0) throw new Error(".omit() cannot be used on object schemas containing refinements");
	return clone(schema, mergeDefs(schema._zod.def, {
		get shape() {
			const newShape = { ...schema._zod.def.shape };
			for (const key in mask) {
				if (!(key in currDef.shape)) throw new Error(`Unrecognized key: "${key}"`);
				if (!mask[key]) continue;
				delete newShape[key];
			}
			assignProp(this, "shape", newShape);
			return newShape;
		},
		checks: []
	}));
}
function extend(schema, shape) {
	if (!isPlainObject(shape)) throw new Error("Invalid input to extend: expected a plain object");
	const checks = schema._zod.def.checks;
	if (checks && checks.length > 0) {
		const existingShape = schema._zod.def.shape;
		for (const key in shape) if (Object.getOwnPropertyDescriptor(existingShape, key) !== void 0) throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
	}
	return clone(schema, mergeDefs(schema._zod.def, { get shape() {
		const _shape = {
			...schema._zod.def.shape,
			...shape
		};
		assignProp(this, "shape", _shape);
		return _shape;
	} }));
}
function safeExtend(schema, shape) {
	if (!isPlainObject(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
	return clone(schema, mergeDefs(schema._zod.def, { get shape() {
		const _shape = {
			...schema._zod.def.shape,
			...shape
		};
		assignProp(this, "shape", _shape);
		return _shape;
	} }));
}
function merge(a, b) {
	if (a._zod.def.checks?.length) throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");
	return clone(a, mergeDefs(a._zod.def, {
		get shape() {
			const _shape = {
				...a._zod.def.shape,
				...b._zod.def.shape
			};
			assignProp(this, "shape", _shape);
			return _shape;
		},
		get catchall() {
			return b._zod.def.catchall;
		},
		checks: b._zod.def.checks ?? []
	}));
}
function partial(Class, schema, mask) {
	const checks = schema._zod.def.checks;
	if (checks && checks.length > 0) throw new Error(".partial() cannot be used on object schemas containing refinements");
	return clone(schema, mergeDefs(schema._zod.def, {
		get shape() {
			const oldShape = schema._zod.def.shape;
			const shape = { ...oldShape };
			if (mask) for (const key in mask) {
				if (!(key in oldShape)) throw new Error(`Unrecognized key: "${key}"`);
				if (!mask[key]) continue;
				shape[key] = Class ? new Class({
					type: "optional",
					innerType: oldShape[key]
				}) : oldShape[key];
			}
			else for (const key in oldShape) shape[key] = Class ? new Class({
				type: "optional",
				innerType: oldShape[key]
			}) : oldShape[key];
			assignProp(this, "shape", shape);
			return shape;
		},
		checks: []
	}));
}
function required(Class, schema, mask) {
	return clone(schema, mergeDefs(schema._zod.def, { get shape() {
		const oldShape = schema._zod.def.shape;
		const shape = { ...oldShape };
		if (mask) for (const key in mask) {
			if (!(key in shape)) throw new Error(`Unrecognized key: "${key}"`);
			if (!mask[key]) continue;
			shape[key] = new Class({
				type: "nonoptional",
				innerType: oldShape[key]
			});
		}
		else for (const key in oldShape) shape[key] = new Class({
			type: "nonoptional",
			innerType: oldShape[key]
		});
		assignProp(this, "shape", shape);
		return shape;
	} }));
}
function aborted(x, startIndex = 0) {
	if (x.aborted === true) return true;
	for (let i = startIndex; i < x.issues.length; i++) if (x.issues[i]?.continue !== true) return true;
	return false;
}
function explicitlyAborted(x, startIndex = 0) {
	if (x.aborted === true) return true;
	for (let i = startIndex; i < x.issues.length; i++) if (x.issues[i]?.continue === false) return true;
	return false;
}
function prefixIssues(path, issues) {
	return issues.map((iss) => {
		var _a;
		(_a = iss).path ?? (_a.path = []);
		iss.path.unshift(path);
		return iss;
	});
}
function unwrapMessage(message) {
	return typeof message === "string" ? message : message?.message;
}
function finalizeIssue(iss, ctx, config) {
	const message = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config.customError?.(iss)) ?? unwrapMessage(config.localeError?.(iss)) ?? "Invalid input";
	const { inst: _inst, continue: _continue, input: _input, ...rest } = iss;
	rest.path ?? (rest.path = []);
	rest.message = message;
	if (ctx?.reportInput) rest.input = _input;
	return rest;
}
function getSizableOrigin(input) {
	if (input instanceof Set) return "set";
	if (input instanceof Map) return "map";
	if (input instanceof File) return "file";
	return "unknown";
}
function getLengthableOrigin(input) {
	if (Array.isArray(input)) return "array";
	if (typeof input === "string") return "string";
	return "unknown";
}
function parsedType(data) {
	const t = typeof data;
	switch (t) {
		case "number": return Number.isNaN(data) ? "nan" : "number";
		case "object": {
			if (data === null) return "null";
			if (Array.isArray(data)) return "array";
			const obj = data;
			if (obj && Object.getPrototypeOf(obj) !== Object.prototype && "constructor" in obj && obj.constructor) return obj.constructor.name;
		}
	}
	return t;
}
function issue(...args) {
	const [iss, input, inst] = args;
	if (typeof iss === "string") return {
		message: iss,
		code: "custom",
		input,
		inst
	};
	return { ...iss };
}
function cleanEnum(obj) {
	return Object.entries(obj).filter(([k, _]) => {
		return Number.isNaN(Number.parseInt(k, 10));
	}).map((el) => el[1]);
}
function base64ToUint8Array(base64) {
	const binaryString = atob(base64);
	const bytes = new Uint8Array(binaryString.length);
	for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
	return bytes;
}
function uint8ArrayToBase64(bytes) {
	let binaryString = "";
	for (let i = 0; i < bytes.length; i++) binaryString += String.fromCharCode(bytes[i]);
	return btoa(binaryString);
}
function base64urlToUint8Array(base64url) {
	const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
	return base64ToUint8Array(base64 + "=".repeat((4 - base64.length % 4) % 4));
}
function uint8ArrayToBase64url(bytes) {
	return uint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
}
function hexToUint8Array(hex) {
	const cleanHex = hex.replace(/^0x/, "");
	if (cleanHex.length % 2 !== 0) throw new Error("Invalid hex string length");
	const bytes = new Uint8Array(cleanHex.length / 2);
	for (let i = 0; i < cleanHex.length; i += 2) bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16);
	return bytes;
}
function uint8ArrayToHex(bytes) {
	return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
}
var Class = class {
	constructor(..._args) {}
};
//#endregion
//#region node_modules/zod/v4/core/errors.js
var initializer$1 = (inst, def) => {
	inst.name = "$ZodError";
	Object.defineProperty(inst, "_zod", {
		value: inst._zod,
		enumerable: false
	});
	Object.defineProperty(inst, "issues", {
		value: def,
		enumerable: false
	});
	inst.message = JSON.stringify(def, jsonStringifyReplacer, 2);
	Object.defineProperty(inst, "toString", {
		value: () => inst.message,
		enumerable: false
	});
};
var $ZodError = $constructor("$ZodError", initializer$1);
var $ZodRealError = $constructor("$ZodError", initializer$1, { Parent: Error });
function flattenError(error, mapper = (issue) => issue.message) {
	const fieldErrors = {};
	const formErrors = [];
	for (const sub of error.issues) if (sub.path.length > 0) {
		fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
		fieldErrors[sub.path[0]].push(mapper(sub));
	} else formErrors.push(mapper(sub));
	return {
		formErrors,
		fieldErrors
	};
}
function formatError(error, mapper = (issue) => issue.message) {
	const fieldErrors = { _errors: [] };
	const processError = (error, path = []) => {
		for (const issue of error.issues) if (issue.code === "invalid_union" && issue.errors.length) issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
		else if (issue.code === "invalid_key") processError({ issues: issue.issues }, [...path, ...issue.path]);
		else if (issue.code === "invalid_element") processError({ issues: issue.issues }, [...path, ...issue.path]);
		else {
			const fullpath = [...path, ...issue.path];
			if (fullpath.length === 0) fieldErrors._errors.push(mapper(issue));
			else {
				let curr = fieldErrors;
				let i = 0;
				while (i < fullpath.length) {
					const el = fullpath[i];
					if (!(i === fullpath.length - 1)) curr[el] = curr[el] || { _errors: [] };
					else {
						curr[el] = curr[el] || { _errors: [] };
						curr[el]._errors.push(mapper(issue));
					}
					curr = curr[el];
					i++;
				}
			}
		}
	};
	processError(error);
	return fieldErrors;
}
function treeifyError(error, mapper = (issue) => issue.message) {
	const result = { errors: [] };
	const processError = (error, path = []) => {
		var _a, _b;
		for (const issue of error.issues) if (issue.code === "invalid_union" && issue.errors.length) issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
		else if (issue.code === "invalid_key") processError({ issues: issue.issues }, [...path, ...issue.path]);
		else if (issue.code === "invalid_element") processError({ issues: issue.issues }, [...path, ...issue.path]);
		else {
			const fullpath = [...path, ...issue.path];
			if (fullpath.length === 0) {
				result.errors.push(mapper(issue));
				continue;
			}
			let curr = result;
			let i = 0;
			while (i < fullpath.length) {
				const el = fullpath[i];
				const terminal = i === fullpath.length - 1;
				if (typeof el === "string") {
					curr.properties ?? (curr.properties = {});
					(_a = curr.properties)[el] ?? (_a[el] = { errors: [] });
					curr = curr.properties[el];
				} else {
					curr.items ?? (curr.items = []);
					(_b = curr.items)[el] ?? (_b[el] = { errors: [] });
					curr = curr.items[el];
				}
				if (terminal) curr.errors.push(mapper(issue));
				i++;
			}
		}
	};
	processError(error);
	return result;
}
/** Format a ZodError as a human-readable string in the following form.
*
* From
*
* ```ts
* ZodError {
*   issues: [
*     {
*       expected: 'string',
*       code: 'invalid_type',
*       path: [ 'username' ],
*       message: 'Invalid input: expected string'
*     },
*     {
*       expected: 'number',
*       code: 'invalid_type',
*       path: [ 'favoriteNumbers', 1 ],
*       message: 'Invalid input: expected number'
*     }
*   ];
* }
* ```
*
* to
*
* ```
* username
*   ✖ Expected number, received string at "username
* favoriteNumbers[0]
*   ✖ Invalid input: expected number
* ```
*/
function toDotPath(_path) {
	const segs = [];
	const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
	for (const seg of path) if (typeof seg === "number") segs.push(`[${seg}]`);
	else if (typeof seg === "symbol") segs.push(`[${JSON.stringify(String(seg))}]`);
	else if (/[^\w$]/.test(seg)) segs.push(`[${JSON.stringify(seg)}]`);
	else {
		if (segs.length) segs.push(".");
		segs.push(seg);
	}
	return segs.join("");
}
function prettifyError(error) {
	const lines = [];
	const issues = [...error.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);
	for (const issue of issues) {
		lines.push(`✖ ${issue.message}`);
		if (issue.path?.length) lines.push(`  → at ${toDotPath(issue.path)}`);
	}
	return lines.join("\n");
}
//#endregion
//#region node_modules/zod/v4/core/parse.js
var _parse = (_Err) => (schema, value, _ctx, _params) => {
	const ctx = _ctx ? {
		..._ctx,
		async: false
	} : { async: false };
	const result = schema._zod.run({
		value,
		issues: []
	}, ctx);
	if (result instanceof Promise) throw new $ZodAsyncError();
	if (result.issues.length) {
		const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
		captureStackTrace(e, _params?.callee);
		throw e;
	}
	return result.value;
};
var parse$1 = /* @__PURE__*/ _parse($ZodRealError);
var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
	const ctx = _ctx ? {
		..._ctx,
		async: true
	} : { async: true };
	let result = schema._zod.run({
		value,
		issues: []
	}, ctx);
	if (result instanceof Promise) result = await result;
	if (result.issues.length) {
		const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
		captureStackTrace(e, params?.callee);
		throw e;
	}
	return result.value;
};
var parseAsync$1 = /* @__PURE__*/ _parseAsync($ZodRealError);
var _safeParse = (_Err) => (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		async: false
	} : { async: false };
	const result = schema._zod.run({
		value,
		issues: []
	}, ctx);
	if (result instanceof Promise) throw new $ZodAsyncError();
	return result.issues.length ? {
		success: false,
		error: new (_Err ?? $ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
	} : {
		success: true,
		data: result.value
	};
};
var safeParse$1 = /* @__PURE__*/ _safeParse($ZodRealError);
var _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		async: true
	} : { async: true };
	let result = schema._zod.run({
		value,
		issues: []
	}, ctx);
	if (result instanceof Promise) result = await result;
	return result.issues.length ? {
		success: false,
		error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
	} : {
		success: true,
		data: result.value
	};
};
var safeParseAsync$1 = /* @__PURE__*/ _safeParseAsync($ZodRealError);
var _encode = (_Err) => (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		direction: "backward"
	} : { direction: "backward" };
	return _parse(_Err)(schema, value, ctx);
};
var encode$2 = /* @__PURE__*/ _encode($ZodRealError);
var _decode = (_Err) => (schema, value, _ctx) => {
	return _parse(_Err)(schema, value, _ctx);
};
var decode$2 = /* @__PURE__*/ _decode($ZodRealError);
var _encodeAsync = (_Err) => async (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		direction: "backward"
	} : { direction: "backward" };
	return _parseAsync(_Err)(schema, value, ctx);
};
var encodeAsync$1 = /* @__PURE__*/ _encodeAsync($ZodRealError);
var _decodeAsync = (_Err) => async (schema, value, _ctx) => {
	return _parseAsync(_Err)(schema, value, _ctx);
};
var decodeAsync$1 = /* @__PURE__*/ _decodeAsync($ZodRealError);
var _safeEncode = (_Err) => (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		direction: "backward"
	} : { direction: "backward" };
	return _safeParse(_Err)(schema, value, ctx);
};
var safeEncode$1 = /* @__PURE__*/ _safeEncode($ZodRealError);
var _safeDecode = (_Err) => (schema, value, _ctx) => {
	return _safeParse(_Err)(schema, value, _ctx);
};
var safeDecode$1 = /* @__PURE__*/ _safeDecode($ZodRealError);
var _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {
	const ctx = _ctx ? {
		..._ctx,
		direction: "backward"
	} : { direction: "backward" };
	return _safeParseAsync(_Err)(schema, value, ctx);
};
var safeEncodeAsync$1 = /* @__PURE__*/ _safeEncodeAsync($ZodRealError);
var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
	return _safeParseAsync(_Err)(schema, value, _ctx);
};
var safeDecodeAsync$1 = /* @__PURE__*/ _safeDecodeAsync($ZodRealError);
//#endregion
//#region node_modules/zod/v4/core/regexes.js
var regexes_exports = /* @__PURE__ */ __exportAll({
	base64: () => base64$1,
	base64url: () => base64url$1,
	bigint: () => bigint$2,
	boolean: () => boolean$2,
	browserEmail: () => browserEmail,
	cidrv4: () => cidrv4$1,
	cidrv6: () => cidrv6$1,
	cuid: () => cuid$1,
	cuid2: () => cuid2$1,
	date: () => date$3,
	datetime: () => datetime$1,
	domain: () => domain,
	duration: () => duration$1,
	e164: () => e164$1,
	email: () => email$1,
	emoji: () => emoji$1,
	extendedDuration: () => extendedDuration,
	guid: () => guid$1,
	hex: () => hex$1,
	hostname: () => hostname$1,
	html5Email: () => html5Email,
	httpProtocol: () => httpProtocol,
	idnEmail: () => idnEmail,
	integer: () => integer,
	ipv4: () => ipv4$1,
	ipv6: () => ipv6$1,
	ksuid: () => ksuid$1,
	lowercase: () => lowercase,
	mac: () => mac$1,
	md5_base64: () => md5_base64,
	md5_base64url: () => md5_base64url,
	md5_hex: () => md5_hex,
	nanoid: () => nanoid$1,
	null: () => _null$2,
	number: () => number$2,
	rfc5322Email: () => rfc5322Email,
	sha1_base64: () => sha1_base64,
	sha1_base64url: () => sha1_base64url,
	sha1_hex: () => sha1_hex,
	sha256_base64: () => sha256_base64,
	sha256_base64url: () => sha256_base64url,
	sha256_hex: () => sha256_hex,
	sha384_base64: () => sha384_base64,
	sha384_base64url: () => sha384_base64url,
	sha384_hex: () => sha384_hex,
	sha512_base64: () => sha512_base64,
	sha512_base64url: () => sha512_base64url,
	sha512_hex: () => sha512_hex,
	string: () => string$2,
	time: () => time$1,
	ulid: () => ulid$1,
	undefined: () => _undefined$2,
	unicodeEmail: () => unicodeEmail,
	uppercase: () => uppercase,
	uuid: () => uuid$1,
	uuid4: () => uuid4,
	uuid6: () => uuid6,
	uuid7: () => uuid7,
	xid: () => xid$1
});
/**
* @deprecated CUID v1 is deprecated by its authors due to information leakage
* (timestamps embedded in the id). Use {@link cuid2} instead.
* See https://github.com/paralleldrive/cuid.
*/
var cuid$1 = /^[cC][0-9a-z]{6,}$/;
var cuid2$1 = /^[0-9a-z]+$/;
var ulid$1 = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
var xid$1 = /^[0-9a-vA-V]{20}$/;
var ksuid$1 = /^[A-Za-z0-9]{27}$/;
var nanoid$1 = /^[a-zA-Z0-9_-]{21}$/;
/** ISO 8601-1 duration regex. Does not support the 8601-2 extensions like negative durations or fractional/negative components. */
var duration$1 = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
/** Implements ISO 8601-2 extensions like explicit +- prefixes, mixing weeks with other units, and fractional/negative components. */
var extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
/** A regex for any UUID-like identifier: 8-4-4-4-12 hex pattern */
var guid$1 = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
/** Returns a regex for validating an RFC 9562/4122 UUID.
*
* @param version Optionally specify a version 1-8. If no version is specified, all versions are supported. */
var uuid$1 = (version) => {
	if (!version) return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
	return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
};
var uuid4 = /*@__PURE__*/ uuid$1(4);
var uuid6 = /*@__PURE__*/ uuid$1(6);
var uuid7 = /*@__PURE__*/ uuid$1(7);
/** Practical email validation */
var email$1 = /^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;
/** Equivalent to the HTML5 input[type=email] validation implemented by browsers. Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email */
var html5Email = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
/** The classic emailregex.com regex for RFC 5322-compliant emails */
var rfc5322Email = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
/** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */
var unicodeEmail = /^[^\s@"]{1,64}@[^\s@]{1,255}$/u;
var idnEmail = unicodeEmail;
var browserEmail = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
var _emoji$1 = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
function emoji$1() {
	return new RegExp(_emoji$1, "u");
}
var ipv4$1 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
var ipv6$1 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
var mac$1 = (delimiter) => {
	const escapedDelim = escapeRegex(delimiter ?? ":");
	return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
};
var cidrv4$1 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
var cidrv6$1 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
var base64$1 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
var base64url$1 = /^[A-Za-z0-9_-]*$/;
var hostname$1 = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
var domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
var httpProtocol = /^https?$/;
var e164$1 = /^\+[1-9]\d{6,14}$/;
var dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
var date$3 = /*@__PURE__*/ new RegExp(`^${dateSource}$`);
function timeSource(args) {
	const hhmm = `(?:[01]\\d|2[0-3]):[0-5]\\d`;
	return typeof args.precision === "number" ? args.precision === -1 ? `${hhmm}` : args.precision === 0 ? `${hhmm}:[0-5]\\d` : `${hhmm}:[0-5]\\d\\.\\d{${args.precision}}` : `${hhmm}(?::[0-5]\\d(?:\\.\\d+)?)?`;
}
function time$1(args) {
	return new RegExp(`^${timeSource(args)}$`);
}
function datetime$1(args) {
	const time = timeSource({ precision: args.precision });
	const opts = ["Z"];
	if (args.local) opts.push("");
	if (args.offset) opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
	const timeRegex = `${time}(?:${opts.join("|")})`;
	return new RegExp(`^${dateSource}T(?:${timeRegex})$`);
}
var string$2 = (params) => {
	const regex = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
	return new RegExp(`^${regex}$`);
};
var bigint$2 = /^-?\d+n?$/;
var integer = /^-?\d+$/;
var number$2 = /^-?\d+(?:\.\d+)?$/;
var boolean$2 = /^(?:true|false)$/i;
var _null$2 = /^null$/i;
var _undefined$2 = /^undefined$/i;
var lowercase = /^[^A-Z]*$/;
var uppercase = /^[^a-z]*$/;
var hex$1 = /^[0-9a-fA-F]*$/;
function fixedBase64(bodyLength, padding) {
	return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);
}
function fixedBase64url(length) {
	return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);
}
var md5_hex = /^[0-9a-fA-F]{32}$/;
var md5_base64 = /*@__PURE__*/ fixedBase64(22, "==");
var md5_base64url = /*@__PURE__*/ fixedBase64url(22);
var sha1_hex = /^[0-9a-fA-F]{40}$/;
var sha1_base64 = /*@__PURE__*/ fixedBase64(27, "=");
var sha1_base64url = /*@__PURE__*/ fixedBase64url(27);
var sha256_hex = /^[0-9a-fA-F]{64}$/;
var sha256_base64 = /*@__PURE__*/ fixedBase64(43, "=");
var sha256_base64url = /*@__PURE__*/ fixedBase64url(43);
var sha384_hex = /^[0-9a-fA-F]{96}$/;
var sha384_base64 = /*@__PURE__*/ fixedBase64(64, "");
var sha384_base64url = /*@__PURE__*/ fixedBase64url(64);
var sha512_hex = /^[0-9a-fA-F]{128}$/;
var sha512_base64 = /*@__PURE__*/ fixedBase64(86, "==");
var sha512_base64url = /*@__PURE__*/ fixedBase64url(86);
//#endregion
//#region node_modules/zod/v4/core/checks.js
var $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => {
	var _a;
	inst._zod ?? (inst._zod = {});
	inst._zod.def = def;
	(_a = inst._zod).onattach ?? (_a.onattach = []);
});
var numericOriginMap = {
	number: "number",
	bigint: "bigint",
	object: "date"
};
var $ZodCheckLessThan = /*@__PURE__*/ $constructor("$ZodCheckLessThan", (inst, def) => {
	$ZodCheck.init(inst, def);
	const origin = numericOriginMap[typeof def.value];
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
		if (def.value < curr) if (def.inclusive) bag.maximum = def.value;
		else bag.exclusiveMaximum = def.value;
	});
	inst._zod.check = (payload) => {
		if (def.inclusive ? payload.value <= def.value : payload.value < def.value) return;
		payload.issues.push({
			origin,
			code: "too_big",
			maximum: typeof def.value === "object" ? def.value.getTime() : def.value,
			input: payload.value,
			inclusive: def.inclusive,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckGreaterThan = /*@__PURE__*/ $constructor("$ZodCheckGreaterThan", (inst, def) => {
	$ZodCheck.init(inst, def);
	const origin = numericOriginMap[typeof def.value];
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
		if (def.value > curr) if (def.inclusive) bag.minimum = def.value;
		else bag.exclusiveMinimum = def.value;
	});
	inst._zod.check = (payload) => {
		if (def.inclusive ? payload.value >= def.value : payload.value > def.value) return;
		payload.issues.push({
			origin,
			code: "too_small",
			minimum: typeof def.value === "object" ? def.value.getTime() : def.value,
			input: payload.value,
			inclusive: def.inclusive,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckMultipleOf = /*@__PURE__*/ $constructor("$ZodCheckMultipleOf", (inst, def) => {
	$ZodCheck.init(inst, def);
	inst._zod.onattach.push((inst) => {
		var _a;
		(_a = inst._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
	});
	inst._zod.check = (payload) => {
		if (typeof payload.value !== typeof def.value) throw new Error("Cannot mix number and bigint in multiple_of check.");
		if (typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0) return;
		payload.issues.push({
			origin: typeof payload.value,
			code: "not_multiple_of",
			divisor: def.value,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckNumberFormat = /*@__PURE__*/ $constructor("$ZodCheckNumberFormat", (inst, def) => {
	$ZodCheck.init(inst, def);
	def.format = def.format || "float64";
	const isInt = def.format?.includes("int");
	const origin = isInt ? "int" : "number";
	const [minimum, maximum] = NUMBER_FORMAT_RANGES[def.format];
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.format = def.format;
		bag.minimum = minimum;
		bag.maximum = maximum;
		if (isInt) bag.pattern = integer;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (isInt) {
			if (!Number.isInteger(input)) {
				payload.issues.push({
					expected: origin,
					format: def.format,
					code: "invalid_type",
					continue: false,
					input,
					inst
				});
				return;
			}
			if (!Number.isSafeInteger(input)) {
				if (input > 0) payload.issues.push({
					input,
					code: "too_big",
					maximum: Number.MAX_SAFE_INTEGER,
					note: "Integers must be within the safe integer range.",
					inst,
					origin,
					inclusive: true,
					continue: !def.abort
				});
				else payload.issues.push({
					input,
					code: "too_small",
					minimum: Number.MIN_SAFE_INTEGER,
					note: "Integers must be within the safe integer range.",
					inst,
					origin,
					inclusive: true,
					continue: !def.abort
				});
				return;
			}
		}
		if (input < minimum) payload.issues.push({
			origin: "number",
			input,
			code: "too_small",
			minimum,
			inclusive: true,
			inst,
			continue: !def.abort
		});
		if (input > maximum) payload.issues.push({
			origin: "number",
			input,
			code: "too_big",
			maximum,
			inclusive: true,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckBigIntFormat = /*@__PURE__*/ $constructor("$ZodCheckBigIntFormat", (inst, def) => {
	$ZodCheck.init(inst, def);
	const [minimum, maximum] = BIGINT_FORMAT_RANGES[def.format];
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.format = def.format;
		bag.minimum = minimum;
		bag.maximum = maximum;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (input < minimum) payload.issues.push({
			origin: "bigint",
			input,
			code: "too_small",
			minimum,
			inclusive: true,
			inst,
			continue: !def.abort
		});
		if (input > maximum) payload.issues.push({
			origin: "bigint",
			input,
			code: "too_big",
			maximum,
			inclusive: true,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckMaxSize = /*@__PURE__*/ $constructor("$ZodCheckMaxSize", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.size !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const curr = inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY;
		if (def.maximum < curr) inst._zod.bag.maximum = def.maximum;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (input.size <= def.maximum) return;
		payload.issues.push({
			origin: getSizableOrigin(input),
			code: "too_big",
			maximum: def.maximum,
			inclusive: true,
			input,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckMinSize = /*@__PURE__*/ $constructor("$ZodCheckMinSize", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.size !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const curr = inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY;
		if (def.minimum > curr) inst._zod.bag.minimum = def.minimum;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (input.size >= def.minimum) return;
		payload.issues.push({
			origin: getSizableOrigin(input),
			code: "too_small",
			minimum: def.minimum,
			inclusive: true,
			input,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckSizeEquals = /*@__PURE__*/ $constructor("$ZodCheckSizeEquals", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.size !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.minimum = def.size;
		bag.maximum = def.size;
		bag.size = def.size;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		const size = input.size;
		if (size === def.size) return;
		const tooBig = size > def.size;
		payload.issues.push({
			origin: getSizableOrigin(input),
			...tooBig ? {
				code: "too_big",
				maximum: def.size
			} : {
				code: "too_small",
				minimum: def.size
			},
			inclusive: true,
			exact: true,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckMaxLength = /*@__PURE__*/ $constructor("$ZodCheckMaxLength", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.length !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const curr = inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY;
		if (def.maximum < curr) inst._zod.bag.maximum = def.maximum;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (input.length <= def.maximum) return;
		const origin = getLengthableOrigin(input);
		payload.issues.push({
			origin,
			code: "too_big",
			maximum: def.maximum,
			inclusive: true,
			input,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckMinLength = /*@__PURE__*/ $constructor("$ZodCheckMinLength", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.length !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const curr = inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY;
		if (def.minimum > curr) inst._zod.bag.minimum = def.minimum;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		if (input.length >= def.minimum) return;
		const origin = getLengthableOrigin(input);
		payload.issues.push({
			origin,
			code: "too_small",
			minimum: def.minimum,
			inclusive: true,
			input,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckLengthEquals = /*@__PURE__*/ $constructor("$ZodCheckLengthEquals", (inst, def) => {
	var _a;
	$ZodCheck.init(inst, def);
	(_a = inst._zod.def).when ?? (_a.when = (payload) => {
		const val = payload.value;
		return !nullish$1(val) && val.length !== void 0;
	});
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.minimum = def.length;
		bag.maximum = def.length;
		bag.length = def.length;
	});
	inst._zod.check = (payload) => {
		const input = payload.value;
		const length = input.length;
		if (length === def.length) return;
		const origin = getLengthableOrigin(input);
		const tooBig = length > def.length;
		payload.issues.push({
			origin,
			...tooBig ? {
				code: "too_big",
				maximum: def.length
			} : {
				code: "too_small",
				minimum: def.length
			},
			inclusive: true,
			exact: true,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckStringFormat = /*@__PURE__*/ $constructor("$ZodCheckStringFormat", (inst, def) => {
	var _a, _b;
	$ZodCheck.init(inst, def);
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.format = def.format;
		if (def.pattern) {
			bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
			bag.patterns.add(def.pattern);
		}
	});
	if (def.pattern) (_a = inst._zod).check ?? (_a.check = (payload) => {
		def.pattern.lastIndex = 0;
		if (def.pattern.test(payload.value)) return;
		payload.issues.push({
			origin: "string",
			code: "invalid_format",
			format: def.format,
			input: payload.value,
			...def.pattern ? { pattern: def.pattern.toString() } : {},
			inst,
			continue: !def.abort
		});
	});
	else (_b = inst._zod).check ?? (_b.check = () => {});
});
var $ZodCheckRegex = /*@__PURE__*/ $constructor("$ZodCheckRegex", (inst, def) => {
	$ZodCheckStringFormat.init(inst, def);
	inst._zod.check = (payload) => {
		def.pattern.lastIndex = 0;
		if (def.pattern.test(payload.value)) return;
		payload.issues.push({
			origin: "string",
			code: "invalid_format",
			format: "regex",
			input: payload.value,
			pattern: def.pattern.toString(),
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckLowerCase = /*@__PURE__*/ $constructor("$ZodCheckLowerCase", (inst, def) => {
	def.pattern ?? (def.pattern = lowercase);
	$ZodCheckStringFormat.init(inst, def);
});
var $ZodCheckUpperCase = /*@__PURE__*/ $constructor("$ZodCheckUpperCase", (inst, def) => {
	def.pattern ?? (def.pattern = uppercase);
	$ZodCheckStringFormat.init(inst, def);
});
var $ZodCheckIncludes = /*@__PURE__*/ $constructor("$ZodCheckIncludes", (inst, def) => {
	$ZodCheck.init(inst, def);
	const escapedRegex = escapeRegex(def.includes);
	const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
	def.pattern = pattern;
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
		bag.patterns.add(pattern);
	});
	inst._zod.check = (payload) => {
		if (payload.value.includes(def.includes, def.position)) return;
		payload.issues.push({
			origin: "string",
			code: "invalid_format",
			format: "includes",
			includes: def.includes,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckStartsWith = /*@__PURE__*/ $constructor("$ZodCheckStartsWith", (inst, def) => {
	$ZodCheck.init(inst, def);
	const pattern = new RegExp(`^${escapeRegex(def.prefix)}.*`);
	def.pattern ?? (def.pattern = pattern);
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
		bag.patterns.add(pattern);
	});
	inst._zod.check = (payload) => {
		if (payload.value.startsWith(def.prefix)) return;
		payload.issues.push({
			origin: "string",
			code: "invalid_format",
			format: "starts_with",
			prefix: def.prefix,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckEndsWith = /*@__PURE__*/ $constructor("$ZodCheckEndsWith", (inst, def) => {
	$ZodCheck.init(inst, def);
	const pattern = new RegExp(`.*${escapeRegex(def.suffix)}$`);
	def.pattern ?? (def.pattern = pattern);
	inst._zod.onattach.push((inst) => {
		const bag = inst._zod.bag;
		bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
		bag.patterns.add(pattern);
	});
	inst._zod.check = (payload) => {
		if (payload.value.endsWith(def.suffix)) return;
		payload.issues.push({
			origin: "string",
			code: "invalid_format",
			format: "ends_with",
			suffix: def.suffix,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
function handleCheckPropertyResult(result, payload, property) {
	if (result.issues.length) payload.issues.push(...prefixIssues(property, result.issues));
}
var $ZodCheckProperty = /*@__PURE__*/ $constructor("$ZodCheckProperty", (inst, def) => {
	$ZodCheck.init(inst, def);
	inst._zod.check = (payload) => {
		const result = def.schema._zod.run({
			value: payload.value[def.property],
			issues: []
		}, {});
		if (result instanceof Promise) return result.then((result) => handleCheckPropertyResult(result, payload, def.property));
		handleCheckPropertyResult(result, payload, def.property);
	};
});
var $ZodCheckMimeType = /*@__PURE__*/ $constructor("$ZodCheckMimeType", (inst, def) => {
	$ZodCheck.init(inst, def);
	const mimeSet = new Set(def.mime);
	inst._zod.onattach.push((inst) => {
		inst._zod.bag.mime = def.mime;
	});
	inst._zod.check = (payload) => {
		if (mimeSet.has(payload.value.type)) return;
		payload.issues.push({
			code: "invalid_value",
			values: def.mime,
			input: payload.value.type,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (inst, def) => {
	$ZodCheck.init(inst, def);
	inst._zod.check = (payload) => {
		payload.value = def.tx(payload.value);
	};
});
//#endregion
//#region node_modules/zod/v4/core/doc.js
var Doc = class {
	constructor(args = []) {
		this.content = [];
		this.indent = 0;
		if (this) this.args = args;
	}
	indented(fn) {
		this.indent += 1;
		fn(this);
		this.indent -= 1;
	}
	write(arg) {
		if (typeof arg === "function") {
			arg(this, { execution: "sync" });
			arg(this, { execution: "async" });
			return;
		}
		const lines = arg.split("\n").filter((x) => x);
		const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length));
		const dedented = lines.map((x) => x.slice(minIndent)).map((x) => " ".repeat(this.indent * 2) + x);
		for (const line of dedented) this.content.push(line);
	}
	compile() {
		const F = Function;
		const args = this?.args;
		const lines = [...(this?.content ?? [``]).map((x) => `  ${x}`)];
		return new F(...args, lines.join("\n"));
	}
};
//#endregion
//#region node_modules/zod/v4/core/versions.js
var version$2 = {
	major: 4,
	minor: 4,
	patch: 3
};
//#endregion
//#region node_modules/zod/v4/core/schemas.js
var $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
	var _a;
	inst ?? (inst = {});
	inst._zod.def = def;
	inst._zod.bag = inst._zod.bag || {};
	inst._zod.version = version$2;
	const checks = [...inst._zod.def.checks ?? []];
	if (inst._zod.traits.has("$ZodCheck")) checks.unshift(inst);
	for (const ch of checks) for (const fn of ch._zod.onattach) fn(inst);
	if (checks.length === 0) {
		(_a = inst._zod).deferred ?? (_a.deferred = []);
		inst._zod.deferred?.push(() => {
			inst._zod.run = inst._zod.parse;
		});
	} else {
		const runChecks = (payload, checks, ctx) => {
			let isAborted = aborted(payload);
			let asyncResult;
			for (const ch of checks) {
				if (ch._zod.def.when) {
					if (explicitlyAborted(payload)) continue;
					if (!ch._zod.def.when(payload)) continue;
				} else if (isAborted) continue;
				const currLen = payload.issues.length;
				const _ = ch._zod.check(payload);
				if (_ instanceof Promise && ctx?.async === false) throw new $ZodAsyncError();
				if (asyncResult || _ instanceof Promise) asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {
					await _;
					if (payload.issues.length === currLen) return;
					if (!isAborted) isAborted = aborted(payload, currLen);
				});
				else {
					if (payload.issues.length === currLen) continue;
					if (!isAborted) isAborted = aborted(payload, currLen);
				}
			}
			if (asyncResult) return asyncResult.then(() => {
				return payload;
			});
			return payload;
		};
		const handleCanaryResult = (canary, payload, ctx) => {
			if (aborted(canary)) {
				canary.aborted = true;
				return canary;
			}
			const checkResult = runChecks(payload, checks, ctx);
			if (checkResult instanceof Promise) {
				if (ctx.async === false) throw new $ZodAsyncError();
				return checkResult.then((checkResult) => inst._zod.parse(checkResult, ctx));
			}
			return inst._zod.parse(checkResult, ctx);
		};
		inst._zod.run = (payload, ctx) => {
			if (ctx.skipChecks) return inst._zod.parse(payload, ctx);
			if (ctx.direction === "backward") {
				const canary = inst._zod.parse({
					value: payload.value,
					issues: []
				}, {
					...ctx,
					skipChecks: true
				});
				if (canary instanceof Promise) return canary.then((canary) => {
					return handleCanaryResult(canary, payload, ctx);
				});
				return handleCanaryResult(canary, payload, ctx);
			}
			const result = inst._zod.parse(payload, ctx);
			if (result instanceof Promise) {
				if (ctx.async === false) throw new $ZodAsyncError();
				return result.then((result) => runChecks(result, checks, ctx));
			}
			return runChecks(result, checks, ctx);
		};
	}
	defineLazy(inst, "~standard", () => ({
		validate: (value) => {
			try {
				const r = safeParse$1(inst, value);
				return r.success ? { value: r.data } : { issues: r.error?.issues };
			} catch (_) {
				return safeParseAsync$1(inst, value).then((r) => r.success ? { value: r.data } : { issues: r.error?.issues });
			}
		},
		vendor: "zod",
		version: 1
	}));
});
var $ZodString = /*@__PURE__*/ $constructor("$ZodString", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string$2(inst._zod.bag);
	inst._zod.parse = (payload, _) => {
		if (def.coerce) try {
			payload.value = String(payload.value);
		} catch (_) {}
		if (typeof payload.value === "string") return payload;
		payload.issues.push({
			expected: "string",
			code: "invalid_type",
			input: payload.value,
			inst
		});
		return payload;
	};
});
var $ZodStringFormat = /*@__PURE__*/ $constructor("$ZodStringFormat", (inst, def) => {
	$ZodCheckStringFormat.init(inst, def);
	$ZodString.init(inst, def);
});
var $ZodGUID = /*@__PURE__*/ $constructor("$ZodGUID", (inst, def) => {
	def.pattern ?? (def.pattern = guid$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodUUID = /*@__PURE__*/ $constructor("$ZodUUID", (inst, def) => {
	if (def.version) {
		const v = {
			v1: 1,
			v2: 2,
			v3: 3,
			v4: 4,
			v5: 5,
			v6: 6,
			v7: 7,
			v8: 8
		}[def.version];
		if (v === void 0) throw new Error(`Invalid UUID version: "${def.version}"`);
		def.pattern ?? (def.pattern = uuid$1(v));
	} else def.pattern ?? (def.pattern = uuid$1());
	$ZodStringFormat.init(inst, def);
});
var $ZodEmail = /*@__PURE__*/ $constructor("$ZodEmail", (inst, def) => {
	def.pattern ?? (def.pattern = email$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodURL = /*@__PURE__*/ $constructor("$ZodURL", (inst, def) => {
	$ZodStringFormat.init(inst, def);
	inst._zod.check = (payload) => {
		try {
			const trimmed = payload.value.trim();
			if (!def.normalize && def.protocol?.source === httpProtocol.source) {
				if (!/^https?:\/\//i.test(trimmed)) {
					payload.issues.push({
						code: "invalid_format",
						format: "url",
						note: "Invalid URL format",
						input: payload.value,
						inst,
						continue: !def.abort
					});
					return;
				}
			}
			const url = new URL(trimmed);
			if (def.hostname) {
				def.hostname.lastIndex = 0;
				if (!def.hostname.test(url.hostname)) payload.issues.push({
					code: "invalid_format",
					format: "url",
					note: "Invalid hostname",
					pattern: def.hostname.source,
					input: payload.value,
					inst,
					continue: !def.abort
				});
			}
			if (def.protocol) {
				def.protocol.lastIndex = 0;
				if (!def.protocol.test(url.protocol.endsWith(":") ? url.protocol.slice(0, -1) : url.protocol)) payload.issues.push({
					code: "invalid_format",
					format: "url",
					note: "Invalid protocol",
					pattern: def.protocol.source,
					input: payload.value,
					inst,
					continue: !def.abort
				});
			}
			if (def.normalize) payload.value = url.href;
			else payload.value = trimmed;
			return;
		} catch (_) {
			payload.issues.push({
				code: "invalid_format",
				format: "url",
				input: payload.value,
				inst,
				continue: !def.abort
			});
		}
	};
});
var $ZodEmoji = /*@__PURE__*/ $constructor("$ZodEmoji", (inst, def) => {
	def.pattern ?? (def.pattern = emoji$1());
	$ZodStringFormat.init(inst, def);
});
var $ZodNanoID = /*@__PURE__*/ $constructor("$ZodNanoID", (inst, def) => {
	def.pattern ?? (def.pattern = nanoid$1);
	$ZodStringFormat.init(inst, def);
});
/**
* @deprecated CUID v1 is deprecated by its authors due to information leakage
* (timestamps embedded in the id). Use {@link $ZodCUID2} instead.
* See https://github.com/paralleldrive/cuid.
*/
var $ZodCUID = /*@__PURE__*/ $constructor("$ZodCUID", (inst, def) => {
	def.pattern ?? (def.pattern = cuid$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodCUID2 = /*@__PURE__*/ $constructor("$ZodCUID2", (inst, def) => {
	def.pattern ?? (def.pattern = cuid2$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodULID = /*@__PURE__*/ $constructor("$ZodULID", (inst, def) => {
	def.pattern ?? (def.pattern = ulid$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodXID = /*@__PURE__*/ $constructor("$ZodXID", (inst, def) => {
	def.pattern ?? (def.pattern = xid$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodKSUID = /*@__PURE__*/ $constructor("$ZodKSUID", (inst, def) => {
	def.pattern ?? (def.pattern = ksuid$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodISODateTime = /*@__PURE__*/ $constructor("$ZodISODateTime", (inst, def) => {
	def.pattern ?? (def.pattern = datetime$1(def));
	$ZodStringFormat.init(inst, def);
});
var $ZodISODate = /*@__PURE__*/ $constructor("$ZodISODate", (inst, def) => {
	def.pattern ?? (def.pattern = date$3);
	$ZodStringFormat.init(inst, def);
});
var $ZodISOTime = /*@__PURE__*/ $constructor("$ZodISOTime", (inst, def) => {
	def.pattern ?? (def.pattern = time$1(def));
	$ZodStringFormat.init(inst, def);
});
var $ZodISODuration = /*@__PURE__*/ $constructor("$ZodISODuration", (inst, def) => {
	def.pattern ?? (def.pattern = duration$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodIPv4 = /*@__PURE__*/ $constructor("$ZodIPv4", (inst, def) => {
	def.pattern ?? (def.pattern = ipv4$1);
	$ZodStringFormat.init(inst, def);
	inst._zod.bag.format = `ipv4`;
});
var $ZodIPv6 = /*@__PURE__*/ $constructor("$ZodIPv6", (inst, def) => {
	def.pattern ?? (def.pattern = ipv6$1);
	$ZodStringFormat.init(inst, def);
	inst._zod.bag.format = `ipv6`;
	inst._zod.check = (payload) => {
		try {
			new URL(`http://[${payload.value}]`);
		} catch {
			payload.issues.push({
				code: "invalid_format",
				format: "ipv6",
				input: payload.value,
				inst,
				continue: !def.abort
			});
		}
	};
});
var $ZodMAC = /*@__PURE__*/ $constructor("$ZodMAC", (inst, def) => {
	def.pattern ?? (def.pattern = mac$1(def.delimiter));
	$ZodStringFormat.init(inst, def);
	inst._zod.bag.format = `mac`;
});
var $ZodCIDRv4 = /*@__PURE__*/ $constructor("$ZodCIDRv4", (inst, def) => {
	def.pattern ?? (def.pattern = cidrv4$1);
	$ZodStringFormat.init(inst, def);
});
var $ZodCIDRv6 = /*@__PURE__*/ $constructor("$ZodCIDRv6", (inst, def) => {
	def.pattern ?? (def.pattern = cidrv6$1);
	$ZodStringFormat.init(inst, def);
	inst._zod.check = (payload) => {
		const parts = payload.value.split("/");
		try {
			if (parts.length !== 2) throw new Error();
			const [address, prefix] = parts;
			if (!prefix) throw new Error();
			const prefixNum = Number(prefix);
			if (`${prefixNum}` !== prefix) throw new Error();
			if (prefixNum < 0 || prefixNum > 128) throw new Error();
			new URL(`http://[${address}]`);
		} catch {
			payload.issues.push({
				code: "invalid_format",
				format: "cidrv6",
				input: payload.value,
				inst,
				continue: !def.abort
			});
		}
	};
});
function isValidBase64(data) {
	if (data === "") return true;
	if (/\s/.test(data)) return false;
	if (data.length % 4 !== 0) return false;
	try {
		atob(data);
		return true;
	} catch {
		return false;
	}
}
var $ZodBase64 = /*@__PURE__*/ $constructor("$ZodBase64", (inst, def) => {
	def.pattern ?? (def.pattern = base64$1);
	$ZodStringFormat.init(inst, def);
	inst._zod.bag.contentEncoding = "base64";
	inst._zod.check = (payload) => {
		if (isValidBase64(payload.value)) return;
		payload.issues.push({
			code: "invalid_format",
			format: "base64",
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
function isValidBase64URL(data) {
	if (!base64url$1.test(data)) return false;
	const base64 = data.replace(/[-_]/g, (c) => c === "-" ? "+" : "/");
	return isValidBase64(base64.padEnd(Math.ceil(base64.length / 4) * 4, "="));
}
var $ZodBase64URL = /*@__PURE__*/ $constructor("$ZodBase64URL", (inst, def) => {
	def.pattern ?? (def.pattern = base64url$1);
	$ZodStringFormat.init(inst, def);
	inst._zod.bag.contentEncoding = "base64url";
	inst._zod.check = (payload) => {
		if (isValidBase64URL(payload.value)) return;
		payload.issues.push({
			code: "invalid_format",
			format: "base64url",
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodE164 = /*@__PURE__*/ $constructor("$ZodE164", (inst, def) => {
	def.pattern ?? (def.pattern = e164$1);
	$ZodStringFormat.init(inst, def);
});
function isValidJWT(token, algorithm = null) {
	try {
		const tokensParts = token.split(".");
		if (tokensParts.length !== 3) return false;
		const [header] = tokensParts;
		if (!header) return false;
		const parsedHeader = JSON.parse(atob(header));
		if ("typ" in parsedHeader && parsedHeader?.typ !== "JWT") return false;
		if (!parsedHeader.alg) return false;
		if (algorithm && (!("alg" in parsedHeader) || parsedHeader.alg !== algorithm)) return false;
		return true;
	} catch {
		return false;
	}
}
var $ZodJWT = /*@__PURE__*/ $constructor("$ZodJWT", (inst, def) => {
	$ZodStringFormat.init(inst, def);
	inst._zod.check = (payload) => {
		if (isValidJWT(payload.value, def.alg)) return;
		payload.issues.push({
			code: "invalid_format",
			format: "jwt",
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodCustomStringFormat = /*@__PURE__*/ $constructor("$ZodCustomStringFormat", (inst, def) => {
	$ZodStringFormat.init(inst, def);
	inst._zod.check = (payload) => {
		if (def.fn(payload.value)) return;
		payload.issues.push({
			code: "invalid_format",
			format: def.format,
			input: payload.value,
			inst,
			continue: !def.abort
		});
	};
});
var $ZodNumber = /*@__PURE__*/ $constructor("$ZodNumber", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = inst._zod.bag.pattern ?? number$2;
	inst._zod.parse = (payload, _ctx) => {
		if (def.coerce) try {
			payload.value = Number(payload.value);
		} catch (_) {}
		const input = payload.value;
		if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) return payload;
		const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
		payload.issues.push({
			expected: "number",
			code: "invalid_type",
			input,
			inst,
			...received ? { received } : {}
		});
		return payload;
	};
});
var $ZodNumberFormat = /*@__PURE__*/ $constructor("$ZodNumberFormat", (inst, def) => {
	$ZodCheckNumberFormat.init(inst, def);
	$ZodNumber.init(inst, def);
});
var $ZodBoolean = /*@__PURE__*/ $constructor("$ZodBoolean", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = boolean$2;
	inst._zod.parse = (payload, _ctx) => {
		if (def.coerce) try {
			payload.value = Boolean(payload.value);
		} catch (_) {}
		const input = payload.value;
		if (typeof input === "boolean") return payload;
		payload.issues.push({
			expected: "boolean",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodBigInt = /*@__PURE__*/ $constructor("$ZodBigInt", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = bigint$2;
	inst._zod.parse = (payload, _ctx) => {
		if (def.coerce) try {
			payload.value = BigInt(payload.value);
		} catch (_) {}
		if (typeof payload.value === "bigint") return payload;
		payload.issues.push({
			expected: "bigint",
			code: "invalid_type",
			input: payload.value,
			inst
		});
		return payload;
	};
});
var $ZodBigIntFormat = /*@__PURE__*/ $constructor("$ZodBigIntFormat", (inst, def) => {
	$ZodCheckBigIntFormat.init(inst, def);
	$ZodBigInt.init(inst, def);
});
var $ZodSymbol = /*@__PURE__*/ $constructor("$ZodSymbol", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (typeof input === "symbol") return payload;
		payload.issues.push({
			expected: "symbol",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodUndefined = /*@__PURE__*/ $constructor("$ZodUndefined", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = _undefined$2;
	inst._zod.values = /* @__PURE__ */ new Set([void 0]);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (typeof input === "undefined") return payload;
		payload.issues.push({
			expected: "undefined",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodNull = /*@__PURE__*/ $constructor("$ZodNull", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.pattern = _null$2;
	inst._zod.values = /* @__PURE__ */ new Set([null]);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (input === null) return payload;
		payload.issues.push({
			expected: "null",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodAny = /*@__PURE__*/ $constructor("$ZodAny", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload) => payload;
});
var $ZodUnknown = /*@__PURE__*/ $constructor("$ZodUnknown", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload) => payload;
});
var $ZodNever = /*@__PURE__*/ $constructor("$ZodNever", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		payload.issues.push({
			expected: "never",
			code: "invalid_type",
			input: payload.value,
			inst
		});
		return payload;
	};
});
var $ZodVoid = /*@__PURE__*/ $constructor("$ZodVoid", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (typeof input === "undefined") return payload;
		payload.issues.push({
			expected: "void",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodDate = /*@__PURE__*/ $constructor("$ZodDate", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		if (def.coerce) try {
			payload.value = new Date(payload.value);
		} catch (_err) {}
		const input = payload.value;
		const isDate = input instanceof Date;
		if (isDate && !Number.isNaN(input.getTime())) return payload;
		payload.issues.push({
			expected: "date",
			code: "invalid_type",
			input,
			...isDate ? { received: "Invalid Date" } : {},
			inst
		});
		return payload;
	};
});
function handleArrayResult(result, final, index) {
	if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues));
	final.value[index] = result.value;
}
var $ZodArray = /*@__PURE__*/ $constructor("$ZodArray", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!Array.isArray(input)) {
			payload.issues.push({
				expected: "array",
				code: "invalid_type",
				input,
				inst
			});
			return payload;
		}
		payload.value = Array(input.length);
		const proms = [];
		for (let i = 0; i < input.length; i++) {
			const item = input[i];
			const result = def.element._zod.run({
				value: item,
				issues: []
			}, ctx);
			if (result instanceof Promise) proms.push(result.then((result) => handleArrayResult(result, payload, i)));
			else handleArrayResult(result, payload, i);
		}
		if (proms.length) return Promise.all(proms).then(() => payload);
		return payload;
	};
});
function handlePropertyResult(result, final, key, input, isOptionalIn, isOptionalOut) {
	const isPresent = key in input;
	if (result.issues.length) {
		if (isOptionalIn && isOptionalOut && !isPresent) return;
		final.issues.push(...prefixIssues(key, result.issues));
	}
	if (!isPresent && !isOptionalIn) {
		if (!result.issues.length) final.issues.push({
			code: "invalid_type",
			expected: "nonoptional",
			input: void 0,
			path: [key]
		});
		return;
	}
	if (result.value === void 0) {
		if (isPresent) final.value[key] = void 0;
	} else final.value[key] = result.value;
}
function normalizeDef(def) {
	const keys = Object.keys(def.shape);
	for (const k of keys) if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) throw new Error(`Invalid element at key "${k}": expected a Zod schema`);
	const okeys = optionalKeys(def.shape);
	return {
		...def,
		keys,
		keySet: new Set(keys),
		numKeys: keys.length,
		optionalKeys: new Set(okeys)
	};
}
function handleCatchall(proms, input, payload, ctx, def, inst) {
	const unrecognized = [];
	const keySet = def.keySet;
	const _catchall = def.catchall._zod;
	const t = _catchall.def.type;
	const isOptionalIn = _catchall.optin === "optional";
	const isOptionalOut = _catchall.optout === "optional";
	for (const key in input) {
		if (key === "__proto__") continue;
		if (keySet.has(key)) continue;
		if (t === "never") {
			unrecognized.push(key);
			continue;
		}
		const r = _catchall.run({
			value: input[key],
			issues: []
		}, ctx);
		if (r instanceof Promise) proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut)));
		else handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut);
	}
	if (unrecognized.length) payload.issues.push({
		code: "unrecognized_keys",
		keys: unrecognized,
		input,
		inst
	});
	if (!proms.length) return payload;
	return Promise.all(proms).then(() => {
		return payload;
	});
}
var $ZodObject = /*@__PURE__*/ $constructor("$ZodObject", (inst, def) => {
	$ZodType.init(inst, def);
	if (!Object.getOwnPropertyDescriptor(def, "shape")?.get) {
		const sh = def.shape;
		Object.defineProperty(def, "shape", { get: () => {
			const newSh = { ...sh };
			Object.defineProperty(def, "shape", { value: newSh });
			return newSh;
		} });
	}
	const _normalized = cached(() => normalizeDef(def));
	defineLazy(inst._zod, "propValues", () => {
		const shape = def.shape;
		const propValues = {};
		for (const key in shape) {
			const field = shape[key]._zod;
			if (field.values) {
				propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
				for (const v of field.values) propValues[key].add(v);
			}
		}
		return propValues;
	});
	const isObject$4 = isObject;
	const catchall = def.catchall;
	let value;
	inst._zod.parse = (payload, ctx) => {
		value ?? (value = _normalized.value);
		const input = payload.value;
		if (!isObject$4(input)) {
			payload.issues.push({
				expected: "object",
				code: "invalid_type",
				input,
				inst
			});
			return payload;
		}
		payload.value = {};
		const proms = [];
		const shape = value.shape;
		for (const key of value.keys) {
			const el = shape[key];
			const isOptionalIn = el._zod.optin === "optional";
			const isOptionalOut = el._zod.optout === "optional";
			const r = el._zod.run({
				value: input[key],
				issues: []
			}, ctx);
			if (r instanceof Promise) proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut)));
			else handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut);
		}
		if (!catchall) return proms.length ? Promise.all(proms).then(() => payload) : payload;
		return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
	};
});
var $ZodObjectJIT = /*@__PURE__*/ $constructor("$ZodObjectJIT", (inst, def) => {
	$ZodObject.init(inst, def);
	const superParse = inst._zod.parse;
	const _normalized = cached(() => normalizeDef(def));
	const generateFastpass = (shape) => {
		const doc = new Doc([
			"shape",
			"payload",
			"ctx"
		]);
		const normalized = _normalized.value;
		const parseStr = (key) => {
			const k = esc(key);
			return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
		};
		doc.write(`const input = payload.value;`);
		const ids = Object.create(null);
		let counter = 0;
		for (const key of normalized.keys) ids[key] = `key_${counter++}`;
		doc.write(`const newResult = {};`);
		for (const key of normalized.keys) {
			const id = ids[key];
			const k = esc(key);
			const schema = shape[key];
			const isOptionalIn = schema?._zod?.optin === "optional";
			const isOptionalOut = schema?._zod?.optout === "optional";
			doc.write(`const ${id} = ${parseStr(key)};`);
			if (isOptionalIn && isOptionalOut) doc.write(`
        if (${id}.issues.length) {
          if (${k} in input) {
            payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
              ...iss,
              path: iss.path ? [${k}, ...iss.path] : [${k}]
            })));
          }
        }
        
        if (${id}.value === undefined) {
          if (${k} in input) {
            newResult[${k}] = undefined;
          }
        } else {
          newResult[${k}] = ${id}.value;
        }
        
      `);
			else if (!isOptionalIn) doc.write(`
        const ${id}_present = ${k} in input;
        if (${id}.issues.length) {
          payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
            ...iss,
            path: iss.path ? [${k}, ...iss.path] : [${k}]
          })));
        }
        if (!${id}_present && !${id}.issues.length) {
          payload.issues.push({
            code: "invalid_type",
            expected: "nonoptional",
            input: undefined,
            path: [${k}]
          });
        }

        if (${id}_present) {
          if (${id}.value === undefined) {
            newResult[${k}] = undefined;
          } else {
            newResult[${k}] = ${id}.value;
          }
        }

      `);
			else doc.write(`
        if (${id}.issues.length) {
          payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
            ...iss,
            path: iss.path ? [${k}, ...iss.path] : [${k}]
          })));
        }
        
        if (${id}.value === undefined) {
          if (${k} in input) {
            newResult[${k}] = undefined;
          }
        } else {
          newResult[${k}] = ${id}.value;
        }
        
      `);
		}
		doc.write(`payload.value = newResult;`);
		doc.write(`return payload;`);
		const fn = doc.compile();
		return (payload, ctx) => fn(shape, payload, ctx);
	};
	let fastpass;
	const isObject$3 = isObject;
	const jit = !globalConfig.jitless;
	const fastEnabled = jit && allowsEval.value;
	const catchall = def.catchall;
	let value;
	inst._zod.parse = (payload, ctx) => {
		value ?? (value = _normalized.value);
		const input = payload.value;
		if (!isObject$3(input)) {
			payload.issues.push({
				expected: "object",
				code: "invalid_type",
				input,
				inst
			});
			return payload;
		}
		if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
			if (!fastpass) fastpass = generateFastpass(def.shape);
			payload = fastpass(payload, ctx);
			if (!catchall) return payload;
			return handleCatchall([], input, payload, ctx, value, inst);
		}
		return superParse(payload, ctx);
	};
});
function handleUnionResults(results, final, inst, ctx) {
	for (const result of results) if (result.issues.length === 0) {
		final.value = result.value;
		return final;
	}
	const nonaborted = results.filter((r) => !aborted(r));
	if (nonaborted.length === 1) {
		final.value = nonaborted[0].value;
		return nonaborted[0];
	}
	final.issues.push({
		code: "invalid_union",
		input: final.value,
		inst,
		errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
	});
	return final;
}
var $ZodUnion = /*@__PURE__*/ $constructor("$ZodUnion", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "optin", () => def.options.some((o) => o._zod.optin === "optional") ? "optional" : void 0);
	defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : void 0);
	defineLazy(inst._zod, "values", () => {
		if (def.options.every((o) => o._zod.values)) return new Set(def.options.flatMap((option) => Array.from(option._zod.values)));
	});
	defineLazy(inst._zod, "pattern", () => {
		if (def.options.every((o) => o._zod.pattern)) {
			const patterns = def.options.map((o) => o._zod.pattern);
			return new RegExp(`^(${patterns.map((p) => cleanRegex(p.source)).join("|")})$`);
		}
	});
	const first = def.options.length === 1 ? def.options[0]._zod.run : null;
	inst._zod.parse = (payload, ctx) => {
		if (first) return first(payload, ctx);
		let async = false;
		const results = [];
		for (const option of def.options) {
			const result = option._zod.run({
				value: payload.value,
				issues: []
			}, ctx);
			if (result instanceof Promise) {
				results.push(result);
				async = true;
			} else {
				if (result.issues.length === 0) return result;
				results.push(result);
			}
		}
		if (!async) return handleUnionResults(results, payload, inst, ctx);
		return Promise.all(results).then((results) => {
			return handleUnionResults(results, payload, inst, ctx);
		});
	};
});
function handleExclusiveUnionResults(results, final, inst, ctx) {
	const successes = results.filter((r) => r.issues.length === 0);
	if (successes.length === 1) {
		final.value = successes[0].value;
		return final;
	}
	if (successes.length === 0) final.issues.push({
		code: "invalid_union",
		input: final.value,
		inst,
		errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
	});
	else final.issues.push({
		code: "invalid_union",
		input: final.value,
		inst,
		errors: [],
		inclusive: false
	});
	return final;
}
var $ZodXor = /*@__PURE__*/ $constructor("$ZodXor", (inst, def) => {
	$ZodUnion.init(inst, def);
	def.inclusive = false;
	const first = def.options.length === 1 ? def.options[0]._zod.run : null;
	inst._zod.parse = (payload, ctx) => {
		if (first) return first(payload, ctx);
		let async = false;
		const results = [];
		for (const option of def.options) {
			const result = option._zod.run({
				value: payload.value,
				issues: []
			}, ctx);
			if (result instanceof Promise) {
				results.push(result);
				async = true;
			} else results.push(result);
		}
		if (!async) return handleExclusiveUnionResults(results, payload, inst, ctx);
		return Promise.all(results).then((results) => {
			return handleExclusiveUnionResults(results, payload, inst, ctx);
		});
	};
});
var $ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
	def.inclusive = false;
	$ZodUnion.init(inst, def);
	const _super = inst._zod.parse;
	defineLazy(inst._zod, "propValues", () => {
		const propValues = {};
		for (const option of def.options) {
			const pv = option._zod.propValues;
			if (!pv || Object.keys(pv).length === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
			for (const [k, v] of Object.entries(pv)) {
				if (!propValues[k]) propValues[k] = /* @__PURE__ */ new Set();
				for (const val of v) propValues[k].add(val);
			}
		}
		return propValues;
	});
	const disc = cached(() => {
		const opts = def.options;
		const map = /* @__PURE__ */ new Map();
		for (const o of opts) {
			const values = o._zod.propValues?.[def.discriminator];
			if (!values || values.size === 0) throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
			for (const v of values) {
				if (map.has(v)) throw new Error(`Duplicate discriminator value "${String(v)}"`);
				map.set(v, o);
			}
		}
		return map;
	});
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!isObject(input)) {
			payload.issues.push({
				code: "invalid_type",
				expected: "object",
				input,
				inst
			});
			return payload;
		}
		const opt = disc.value.get(input?.[def.discriminator]);
		if (opt) return opt._zod.run(payload, ctx);
		if (def.unionFallback || ctx.direction === "backward") return _super(payload, ctx);
		payload.issues.push({
			code: "invalid_union",
			errors: [],
			note: "No matching discriminator",
			discriminator: def.discriminator,
			options: Array.from(disc.value.keys()),
			input,
			path: [def.discriminator],
			inst
		});
		return payload;
	};
});
var $ZodIntersection = /*@__PURE__*/ $constructor("$ZodIntersection", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		const left = def.left._zod.run({
			value: input,
			issues: []
		}, ctx);
		const right = def.right._zod.run({
			value: input,
			issues: []
		}, ctx);
		if (left instanceof Promise || right instanceof Promise) return Promise.all([left, right]).then(([left, right]) => {
			return handleIntersectionResults(payload, left, right);
		});
		return handleIntersectionResults(payload, left, right);
	};
});
function mergeValues(a, b) {
	if (a === b) return {
		valid: true,
		data: a
	};
	if (a instanceof Date && b instanceof Date && +a === +b) return {
		valid: true,
		data: a
	};
	if (isPlainObject(a) && isPlainObject(b)) {
		const bKeys = Object.keys(b);
		const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
		const newObj = {
			...a,
			...b
		};
		for (const key of sharedKeys) {
			const sharedValue = mergeValues(a[key], b[key]);
			if (!sharedValue.valid) return {
				valid: false,
				mergeErrorPath: [key, ...sharedValue.mergeErrorPath]
			};
			newObj[key] = sharedValue.data;
		}
		return {
			valid: true,
			data: newObj
		};
	}
	if (Array.isArray(a) && Array.isArray(b)) {
		if (a.length !== b.length) return {
			valid: false,
			mergeErrorPath: []
		};
		const newArray = [];
		for (let index = 0; index < a.length; index++) {
			const itemA = a[index];
			const itemB = b[index];
			const sharedValue = mergeValues(itemA, itemB);
			if (!sharedValue.valid) return {
				valid: false,
				mergeErrorPath: [index, ...sharedValue.mergeErrorPath]
			};
			newArray.push(sharedValue.data);
		}
		return {
			valid: true,
			data: newArray
		};
	}
	return {
		valid: false,
		mergeErrorPath: []
	};
}
function handleIntersectionResults(result, left, right) {
	const unrecKeys = /* @__PURE__ */ new Map();
	let unrecIssue;
	for (const iss of left.issues) if (iss.code === "unrecognized_keys") {
		unrecIssue ?? (unrecIssue = iss);
		for (const k of iss.keys) {
			if (!unrecKeys.has(k)) unrecKeys.set(k, {});
			unrecKeys.get(k).l = true;
		}
	} else result.issues.push(iss);
	for (const iss of right.issues) if (iss.code === "unrecognized_keys") for (const k of iss.keys) {
		if (!unrecKeys.has(k)) unrecKeys.set(k, {});
		unrecKeys.get(k).r = true;
	}
	else result.issues.push(iss);
	const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
	if (bothKeys.length && unrecIssue) result.issues.push({
		...unrecIssue,
		keys: bothKeys
	});
	if (aborted(result)) return result;
	const merged = mergeValues(left.value, right.value);
	if (!merged.valid) throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(merged.mergeErrorPath)}`);
	result.value = merged.data;
	return result;
}
var $ZodTuple = /*@__PURE__*/ $constructor("$ZodTuple", (inst, def) => {
	$ZodType.init(inst, def);
	const items = def.items;
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!Array.isArray(input)) {
			payload.issues.push({
				input,
				inst,
				expected: "tuple",
				code: "invalid_type"
			});
			return payload;
		}
		payload.value = [];
		const proms = [];
		const optinStart = getTupleOptStart(items, "optin");
		const optoutStart = getTupleOptStart(items, "optout");
		if (!def.rest) {
			if (input.length < optinStart) {
				payload.issues.push({
					code: "too_small",
					minimum: optinStart,
					inclusive: true,
					input,
					inst,
					origin: "array"
				});
				return payload;
			}
			if (input.length > items.length) payload.issues.push({
				code: "too_big",
				maximum: items.length,
				inclusive: true,
				input,
				inst,
				origin: "array"
			});
		}
		const itemResults = new Array(items.length);
		for (let i = 0; i < items.length; i++) {
			const r = items[i]._zod.run({
				value: input[i],
				issues: []
			}, ctx);
			if (r instanceof Promise) proms.push(r.then((rr) => {
				itemResults[i] = rr;
			}));
			else itemResults[i] = r;
		}
		if (def.rest) {
			let i = items.length - 1;
			const rest = input.slice(items.length);
			for (const el of rest) {
				i++;
				const result = def.rest._zod.run({
					value: el,
					issues: []
				}, ctx);
				if (result instanceof Promise) proms.push(result.then((r) => handleTupleResult(r, payload, i)));
				else handleTupleResult(result, payload, i);
			}
		}
		if (proms.length) return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
		return handleTupleResults(itemResults, payload, items, input, optoutStart);
	};
});
function getTupleOptStart(items, key) {
	for (let i = items.length - 1; i >= 0; i--) if (items[i]._zod[key] !== "optional") return i + 1;
	return 0;
}
function handleTupleResult(result, final, index) {
	if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues));
	final.value[index] = result.value;
}
function handleTupleResults(itemResults, final, items, input, optoutStart) {
	for (let i = 0; i < items.length; i++) {
		const r = itemResults[i];
		const isPresent = i < input.length;
		if (r.issues.length) {
			if (!isPresent && i >= optoutStart) {
				final.value.length = i;
				break;
			}
			final.issues.push(...prefixIssues(i, r.issues));
		}
		final.value[i] = r.value;
	}
	for (let i = final.value.length - 1; i >= input.length; i--) if (items[i]._zod.optout === "optional" && final.value[i] === void 0) final.value.length = i;
	else break;
	return final;
}
var $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!isPlainObject(input)) {
			payload.issues.push({
				expected: "record",
				code: "invalid_type",
				input,
				inst
			});
			return payload;
		}
		const proms = [];
		const values = def.keyType._zod.values;
		if (values) {
			payload.value = {};
			const recordKeys = /* @__PURE__ */ new Set();
			for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
				recordKeys.add(typeof key === "number" ? key.toString() : key);
				const keyResult = def.keyType._zod.run({
					value: key,
					issues: []
				}, ctx);
				if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
				if (keyResult.issues.length) {
					payload.issues.push({
						code: "invalid_key",
						origin: "record",
						issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
						input: key,
						path: [key],
						inst
					});
					continue;
				}
				const outKey = keyResult.value;
				const result = def.valueType._zod.run({
					value: input[key],
					issues: []
				}, ctx);
				if (result instanceof Promise) proms.push(result.then((result) => {
					if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
					payload.value[outKey] = result.value;
				}));
				else {
					if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
					payload.value[outKey] = result.value;
				}
			}
			let unrecognized;
			for (const key in input) if (!recordKeys.has(key)) {
				unrecognized = unrecognized ?? [];
				unrecognized.push(key);
			}
			if (unrecognized && unrecognized.length > 0) payload.issues.push({
				code: "unrecognized_keys",
				input,
				inst,
				keys: unrecognized
			});
		} else {
			payload.value = {};
			for (const key of Reflect.ownKeys(input)) {
				if (key === "__proto__") continue;
				if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue;
				let keyResult = def.keyType._zod.run({
					value: key,
					issues: []
				}, ctx);
				if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
				if (typeof key === "string" && number$2.test(key) && keyResult.issues.length) {
					const retryResult = def.keyType._zod.run({
						value: Number(key),
						issues: []
					}, ctx);
					if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
					if (retryResult.issues.length === 0) keyResult = retryResult;
				}
				if (keyResult.issues.length) {
					if (def.mode === "loose") payload.value[key] = input[key];
					else payload.issues.push({
						code: "invalid_key",
						origin: "record",
						issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
						input: key,
						path: [key],
						inst
					});
					continue;
				}
				const result = def.valueType._zod.run({
					value: input[key],
					issues: []
				}, ctx);
				if (result instanceof Promise) proms.push(result.then((result) => {
					if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
					payload.value[keyResult.value] = result.value;
				}));
				else {
					if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
					payload.value[keyResult.value] = result.value;
				}
			}
		}
		if (proms.length) return Promise.all(proms).then(() => payload);
		return payload;
	};
});
var $ZodMap = /*@__PURE__*/ $constructor("$ZodMap", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!(input instanceof Map)) {
			payload.issues.push({
				expected: "map",
				code: "invalid_type",
				input,
				inst
			});
			return payload;
		}
		const proms = [];
		payload.value = /* @__PURE__ */ new Map();
		for (const [key, value] of input) {
			const keyResult = def.keyType._zod.run({
				value: key,
				issues: []
			}, ctx);
			const valueResult = def.valueType._zod.run({
				value,
				issues: []
			}, ctx);
			if (keyResult instanceof Promise || valueResult instanceof Promise) proms.push(Promise.all([keyResult, valueResult]).then(([keyResult, valueResult]) => {
				handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);
			}));
			else handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);
		}
		if (proms.length) return Promise.all(proms).then(() => payload);
		return payload;
	};
});
function handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {
	if (keyResult.issues.length) if (propertyKeyTypes.has(typeof key)) final.issues.push(...prefixIssues(key, keyResult.issues));
	else final.issues.push({
		code: "invalid_key",
		origin: "map",
		input,
		inst,
		issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
	});
	if (valueResult.issues.length) if (propertyKeyTypes.has(typeof key)) final.issues.push(...prefixIssues(key, valueResult.issues));
	else final.issues.push({
		origin: "map",
		code: "invalid_element",
		input,
		inst,
		key,
		issues: valueResult.issues.map((iss) => finalizeIssue(iss, ctx, config()))
	});
	final.value.set(keyResult.value, valueResult.value);
}
var $ZodSet = /*@__PURE__*/ $constructor("$ZodSet", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		const input = payload.value;
		if (!(input instanceof Set)) {
			payload.issues.push({
				input,
				inst,
				expected: "set",
				code: "invalid_type"
			});
			return payload;
		}
		const proms = [];
		payload.value = /* @__PURE__ */ new Set();
		for (const item of input) {
			const result = def.valueType._zod.run({
				value: item,
				issues: []
			}, ctx);
			if (result instanceof Promise) proms.push(result.then((result) => handleSetResult(result, payload)));
			else handleSetResult(result, payload);
		}
		if (proms.length) return Promise.all(proms).then(() => payload);
		return payload;
	};
});
function handleSetResult(result, final) {
	if (result.issues.length) final.issues.push(...result.issues);
	final.value.add(result.value);
}
var $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
	$ZodType.init(inst, def);
	const values = getEnumValues(def.entries);
	const valuesSet = new Set(values);
	inst._zod.values = valuesSet;
	inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (valuesSet.has(input)) return payload;
		payload.issues.push({
			code: "invalid_value",
			values,
			input,
			inst
		});
		return payload;
	};
});
var $ZodLiteral = /*@__PURE__*/ $constructor("$ZodLiteral", (inst, def) => {
	$ZodType.init(inst, def);
	if (def.values.length === 0) throw new Error("Cannot create literal schema with no valid values");
	const values = new Set(def.values);
	inst._zod.values = values;
	inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? escapeRegex(o.toString()) : String(o)).join("|")})$`);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (values.has(input)) return payload;
		payload.issues.push({
			code: "invalid_value",
			values: def.values,
			input,
			inst
		});
		return payload;
	};
});
var $ZodFile = /*@__PURE__*/ $constructor("$ZodFile", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		const input = payload.value;
		if (input instanceof File) return payload;
		payload.issues.push({
			expected: "file",
			code: "invalid_type",
			input,
			inst
		});
		return payload;
	};
});
var $ZodTransform = /*@__PURE__*/ $constructor("$ZodTransform", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.optin = "optional";
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") throw new $ZodEncodeError(inst.constructor.name);
		const _out = def.transform(payload.value, payload);
		if (ctx.async) return (_out instanceof Promise ? _out : Promise.resolve(_out)).then((output) => {
			payload.value = output;
			payload.fallback = true;
			return payload;
		});
		if (_out instanceof Promise) throw new $ZodAsyncError();
		payload.value = _out;
		payload.fallback = true;
		return payload;
	};
});
function handleOptionalResult(result, input) {
	if (input === void 0 && (result.issues.length || result.fallback)) return {
		issues: [],
		value: void 0
	};
	return result;
}
var $ZodOptional = /*@__PURE__*/ $constructor("$ZodOptional", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.optin = "optional";
	inst._zod.optout = "optional";
	defineLazy(inst._zod, "values", () => {
		return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, void 0]) : void 0;
	});
	defineLazy(inst._zod, "pattern", () => {
		const pattern = def.innerType._zod.pattern;
		return pattern ? new RegExp(`^(${cleanRegex(pattern.source)})?$`) : void 0;
	});
	inst._zod.parse = (payload, ctx) => {
		if (def.innerType._zod.optin === "optional") {
			const input = payload.value;
			const result = def.innerType._zod.run(payload, ctx);
			if (result instanceof Promise) return result.then((r) => handleOptionalResult(r, input));
			return handleOptionalResult(result, input);
		}
		if (payload.value === void 0) return payload;
		return def.innerType._zod.run(payload, ctx);
	};
});
var $ZodExactOptional = /*@__PURE__*/ $constructor("$ZodExactOptional", (inst, def) => {
	$ZodOptional.init(inst, def);
	defineLazy(inst._zod, "values", () => def.innerType._zod.values);
	defineLazy(inst._zod, "pattern", () => def.innerType._zod.pattern);
	inst._zod.parse = (payload, ctx) => {
		return def.innerType._zod.run(payload, ctx);
	};
});
var $ZodNullable = /*@__PURE__*/ $constructor("$ZodNullable", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
	defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
	defineLazy(inst._zod, "pattern", () => {
		const pattern = def.innerType._zod.pattern;
		return pattern ? new RegExp(`^(${cleanRegex(pattern.source)}|null)$`) : void 0;
	});
	defineLazy(inst._zod, "values", () => {
		return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
	});
	inst._zod.parse = (payload, ctx) => {
		if (payload.value === null) return payload;
		return def.innerType._zod.run(payload, ctx);
	};
});
var $ZodDefault = /*@__PURE__*/ $constructor("$ZodDefault", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.optin = "optional";
	defineLazy(inst._zod, "values", () => def.innerType._zod.values);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx);
		if (payload.value === void 0) {
			payload.value = def.defaultValue;
			/**
			* $ZodDefault returns the default value immediately in forward direction.
			* It doesn't pass the default value into the validator ("prefault"). There's no reason to pass the default value through validation. The validity of the default is enforced by TypeScript statically. Otherwise, it's the responsibility of the user to ensure the default is valid. In the case of pipes with divergent in/out types, you can specify the default on the `in` schema of your ZodPipe to set a "prefault" for the pipe.   */
			return payload;
		}
		const result = def.innerType._zod.run(payload, ctx);
		if (result instanceof Promise) return result.then((result) => handleDefaultResult(result, def));
		return handleDefaultResult(result, def);
	};
});
function handleDefaultResult(payload, def) {
	if (payload.value === void 0) payload.value = def.defaultValue;
	return payload;
}
var $ZodPrefault = /*@__PURE__*/ $constructor("$ZodPrefault", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.optin = "optional";
	defineLazy(inst._zod, "values", () => def.innerType._zod.values);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx);
		if (payload.value === void 0) payload.value = def.defaultValue;
		return def.innerType._zod.run(payload, ctx);
	};
});
var $ZodNonOptional = /*@__PURE__*/ $constructor("$ZodNonOptional", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "values", () => {
		const v = def.innerType._zod.values;
		return v ? new Set([...v].filter((x) => x !== void 0)) : void 0;
	});
	inst._zod.parse = (payload, ctx) => {
		const result = def.innerType._zod.run(payload, ctx);
		if (result instanceof Promise) return result.then((result) => handleNonOptionalResult(result, inst));
		return handleNonOptionalResult(result, inst);
	};
});
function handleNonOptionalResult(payload, inst) {
	if (!payload.issues.length && payload.value === void 0) payload.issues.push({
		code: "invalid_type",
		expected: "nonoptional",
		input: payload.value,
		inst
	});
	return payload;
}
var $ZodSuccess = /*@__PURE__*/ $constructor("$ZodSuccess", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") throw new $ZodEncodeError("ZodSuccess");
		const result = def.innerType._zod.run(payload, ctx);
		if (result instanceof Promise) return result.then((result) => {
			payload.value = result.issues.length === 0;
			return payload;
		});
		payload.value = result.issues.length === 0;
		return payload;
	};
});
var $ZodCatch = /*@__PURE__*/ $constructor("$ZodCatch", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.optin = "optional";
	defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
	defineLazy(inst._zod, "values", () => def.innerType._zod.values);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx);
		const result = def.innerType._zod.run(payload, ctx);
		if (result instanceof Promise) return result.then((result) => {
			payload.value = result.value;
			if (result.issues.length) {
				payload.value = def.catchValue({
					...payload,
					error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
					input: payload.value
				});
				payload.issues = [];
				payload.fallback = true;
			}
			return payload;
		});
		payload.value = result.value;
		if (result.issues.length) {
			payload.value = def.catchValue({
				...payload,
				error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
				input: payload.value
			});
			payload.issues = [];
			payload.fallback = true;
		}
		return payload;
	};
});
var $ZodNaN = /*@__PURE__*/ $constructor("$ZodNaN", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _ctx) => {
		if (typeof payload.value !== "number" || !Number.isNaN(payload.value)) {
			payload.issues.push({
				input: payload.value,
				inst,
				expected: "nan",
				code: "invalid_type"
			});
			return payload;
		}
		return payload;
	};
});
var $ZodPipe = /*@__PURE__*/ $constructor("$ZodPipe", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "values", () => def.in._zod.values);
	defineLazy(inst._zod, "optin", () => def.in._zod.optin);
	defineLazy(inst._zod, "optout", () => def.out._zod.optout);
	defineLazy(inst._zod, "propValues", () => def.in._zod.propValues);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") {
			const right = def.out._zod.run(payload, ctx);
			if (right instanceof Promise) return right.then((right) => handlePipeResult(right, def.in, ctx));
			return handlePipeResult(right, def.in, ctx);
		}
		const left = def.in._zod.run(payload, ctx);
		if (left instanceof Promise) return left.then((left) => handlePipeResult(left, def.out, ctx));
		return handlePipeResult(left, def.out, ctx);
	};
});
function handlePipeResult(left, next, ctx) {
	if (left.issues.length) {
		left.aborted = true;
		return left;
	}
	return next._zod.run({
		value: left.value,
		issues: left.issues,
		fallback: left.fallback
	}, ctx);
}
var $ZodCodec = /*@__PURE__*/ $constructor("$ZodCodec", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "values", () => def.in._zod.values);
	defineLazy(inst._zod, "optin", () => def.in._zod.optin);
	defineLazy(inst._zod, "optout", () => def.out._zod.optout);
	defineLazy(inst._zod, "propValues", () => def.in._zod.propValues);
	inst._zod.parse = (payload, ctx) => {
		if ((ctx.direction || "forward") === "forward") {
			const left = def.in._zod.run(payload, ctx);
			if (left instanceof Promise) return left.then((left) => handleCodecAResult(left, def, ctx));
			return handleCodecAResult(left, def, ctx);
		} else {
			const right = def.out._zod.run(payload, ctx);
			if (right instanceof Promise) return right.then((right) => handleCodecAResult(right, def, ctx));
			return handleCodecAResult(right, def, ctx);
		}
	};
});
function handleCodecAResult(result, def, ctx) {
	if (result.issues.length) {
		result.aborted = true;
		return result;
	}
	if ((ctx.direction || "forward") === "forward") {
		const transformed = def.transform(result.value, result);
		if (transformed instanceof Promise) return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx));
		return handleCodecTxResult(result, transformed, def.out, ctx);
	} else {
		const transformed = def.reverseTransform(result.value, result);
		if (transformed instanceof Promise) return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx));
		return handleCodecTxResult(result, transformed, def.in, ctx);
	}
}
function handleCodecTxResult(left, value, nextSchema, ctx) {
	if (left.issues.length) {
		left.aborted = true;
		return left;
	}
	return nextSchema._zod.run({
		value,
		issues: left.issues
	}, ctx);
}
var $ZodPreprocess = /*@__PURE__*/ $constructor("$ZodPreprocess", (inst, def) => {
	$ZodPipe.init(inst, def);
});
var $ZodReadonly = /*@__PURE__*/ $constructor("$ZodReadonly", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "propValues", () => def.innerType._zod.propValues);
	defineLazy(inst._zod, "values", () => def.innerType._zod.values);
	defineLazy(inst._zod, "optin", () => def.innerType?._zod?.optin);
	defineLazy(inst._zod, "optout", () => def.innerType?._zod?.optout);
	inst._zod.parse = (payload, ctx) => {
		if (ctx.direction === "backward") return def.innerType._zod.run(payload, ctx);
		const result = def.innerType._zod.run(payload, ctx);
		if (result instanceof Promise) return result.then(handleReadonlyResult);
		return handleReadonlyResult(result);
	};
});
function handleReadonlyResult(payload) {
	payload.value = Object.freeze(payload.value);
	return payload;
}
var $ZodTemplateLiteral = /*@__PURE__*/ $constructor("$ZodTemplateLiteral", (inst, def) => {
	$ZodType.init(inst, def);
	const regexParts = [];
	for (const part of def.parts) if (typeof part === "object" && part !== null) {
		if (!part._zod.pattern) throw new Error(`Invalid template literal part, no pattern found: ${[...part._zod.traits].shift()}`);
		const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern;
		if (!source) throw new Error(`Invalid template literal part: ${part._zod.traits}`);
		const start = source.startsWith("^") ? 1 : 0;
		const end = source.endsWith("$") ? source.length - 1 : source.length;
		regexParts.push(source.slice(start, end));
	} else if (part === null || primitiveTypes.has(typeof part)) regexParts.push(escapeRegex(`${part}`));
	else throw new Error(`Invalid template literal part: ${part}`);
	inst._zod.pattern = new RegExp(`^${regexParts.join("")}$`);
	inst._zod.parse = (payload, _ctx) => {
		if (typeof payload.value !== "string") {
			payload.issues.push({
				input: payload.value,
				inst,
				expected: "string",
				code: "invalid_type"
			});
			return payload;
		}
		inst._zod.pattern.lastIndex = 0;
		if (!inst._zod.pattern.test(payload.value)) {
			payload.issues.push({
				input: payload.value,
				inst,
				code: "invalid_format",
				format: def.format ?? "template_literal",
				pattern: inst._zod.pattern.source
			});
			return payload;
		}
		return payload;
	};
});
var $ZodFunction = /*@__PURE__*/ $constructor("$ZodFunction", (inst, def) => {
	$ZodType.init(inst, def);
	inst._def = def;
	inst._zod.def = def;
	inst.implement = (func) => {
		if (typeof func !== "function") throw new Error("implement() must be called with a function");
		return function(...args) {
			const parsedArgs = inst._def.input ? parse$1(inst._def.input, args) : args;
			const result = Reflect.apply(func, this, parsedArgs);
			if (inst._def.output) return parse$1(inst._def.output, result);
			return result;
		};
	};
	inst.implementAsync = (func) => {
		if (typeof func !== "function") throw new Error("implementAsync() must be called with a function");
		return async function(...args) {
			const parsedArgs = inst._def.input ? await parseAsync$1(inst._def.input, args) : args;
			const result = await Reflect.apply(func, this, parsedArgs);
			if (inst._def.output) return await parseAsync$1(inst._def.output, result);
			return result;
		};
	};
	inst._zod.parse = (payload, _ctx) => {
		if (typeof payload.value !== "function") {
			payload.issues.push({
				code: "invalid_type",
				expected: "function",
				input: payload.value,
				inst
			});
			return payload;
		}
		if (inst._def.output && inst._def.output._zod.def.type === "promise") payload.value = inst.implementAsync(payload.value);
		else payload.value = inst.implement(payload.value);
		return payload;
	};
	inst.input = (...args) => {
		const F = inst.constructor;
		if (Array.isArray(args[0])) return new F({
			type: "function",
			input: new $ZodTuple({
				type: "tuple",
				items: args[0],
				rest: args[1]
			}),
			output: inst._def.output
		});
		return new F({
			type: "function",
			input: args[0],
			output: inst._def.output
		});
	};
	inst.output = (output) => {
		const F = inst.constructor;
		return new F({
			type: "function",
			input: inst._def.input,
			output
		});
	};
	return inst;
});
var $ZodPromise = /*@__PURE__*/ $constructor("$ZodPromise", (inst, def) => {
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, ctx) => {
		return Promise.resolve(payload.value).then((inner) => def.innerType._zod.run({
			value: inner,
			issues: []
		}, ctx));
	};
});
var $ZodLazy = /*@__PURE__*/ $constructor("$ZodLazy", (inst, def) => {
	$ZodType.init(inst, def);
	defineLazy(inst._zod, "innerType", () => {
		const d = def;
		if (!d._cachedInner) d._cachedInner = def.getter();
		return d._cachedInner;
	});
	defineLazy(inst._zod, "pattern", () => inst._zod.innerType?._zod?.pattern);
	defineLazy(inst._zod, "propValues", () => inst._zod.innerType?._zod?.propValues);
	defineLazy(inst._zod, "optin", () => inst._zod.innerType?._zod?.optin ?? void 0);
	defineLazy(inst._zod, "optout", () => inst._zod.innerType?._zod?.optout ?? void 0);
	inst._zod.parse = (payload, ctx) => {
		return inst._zod.innerType._zod.run(payload, ctx);
	};
});
var $ZodCustom = /*@__PURE__*/ $constructor("$ZodCustom", (inst, def) => {
	$ZodCheck.init(inst, def);
	$ZodType.init(inst, def);
	inst._zod.parse = (payload, _) => {
		return payload;
	};
	inst._zod.check = (payload) => {
		const input = payload.value;
		const r = def.fn(input);
		if (r instanceof Promise) return r.then((r) => handleRefineResult(r, payload, input, inst));
		handleRefineResult(r, payload, input, inst);
	};
});
function handleRefineResult(result, payload, input, inst) {
	if (!result) {
		const _iss = {
			code: "custom",
			input,
			inst,
			path: [...inst._zod.def.path ?? []],
			continue: !inst._zod.def.abort
		};
		if (inst._zod.def.params) _iss.params = inst._zod.def.params;
		payload.issues.push(issue(_iss));
	}
}
//#endregion
//#region node_modules/zod/v4/locales/ar.js
var error$49 = () => {
	const Sizable = {
		string: {
			unit: "حرف",
			verb: "أن يحوي"
		},
		file: {
			unit: "بايت",
			verb: "أن يحوي"
		},
		array: {
			unit: "عنصر",
			verb: "أن يحوي"
		},
		set: {
			unit: "عنصر",
			verb: "أن يحوي"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "مدخل",
		email: "بريد إلكتروني",
		url: "رابط",
		emoji: "إيموجي",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "تاريخ ووقت بمعيار ISO",
		date: "تاريخ بمعيار ISO",
		time: "وقت بمعيار ISO",
		duration: "مدة بمعيار ISO",
		ipv4: "عنوان IPv4",
		ipv6: "عنوان IPv6",
		cidrv4: "مدى عناوين بصيغة IPv4",
		cidrv6: "مدى عناوين بصيغة IPv6",
		base64: "نَص بترميز base64-encoded",
		base64url: "نَص بترميز base64url-encoded",
		json_string: "نَص على هيئة JSON",
		e164: "رقم هاتف بمعيار E.164",
		jwt: "JWT",
		template_literal: "مدخل"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `مدخلات غير مقبولة: يفترض إدخال instanceof ${issue.expected}، ولكن تم إدخال ${received}`;
				return `مدخلات غير مقبولة: يفترض إدخال ${expected}، ولكن تم إدخال ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `مدخلات غير مقبولة: يفترض إدخال ${stringifyPrimitive(issue.values[0])}`;
				return `اختيار غير مقبول: يتوقع انتقاء أحد هذه الخيارات: ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return ` أكبر من اللازم: يفترض أن تكون ${issue.origin ?? "القيمة"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "عنصر"}`;
				return `أكبر من اللازم: يفترض أن تكون ${issue.origin ?? "القيمة"} ${adj} ${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `أصغر من اللازم: يفترض لـ ${issue.origin} أن يكون ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
				return `أصغر من اللازم: يفترض لـ ${issue.origin} أن يكون ${adj} ${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `نَص غير مقبول: يجب أن يبدأ بـ "${issue.prefix}"`;
				if (_issue.format === "ends_with") return `نَص غير مقبول: يجب أن ينتهي بـ "${_issue.suffix}"`;
				if (_issue.format === "includes") return `نَص غير مقبول: يجب أن يتضمَّن "${_issue.includes}"`;
				if (_issue.format === "regex") return `نَص غير مقبول: يجب أن يطابق النمط ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} غير مقبول`;
			}
			case "not_multiple_of": return `رقم غير مقبول: يجب أن يكون من مضاعفات ${issue.divisor}`;
			case "unrecognized_keys": return `معرف${issue.keys.length > 1 ? "ات" : ""} غريب${issue.keys.length > 1 ? "ة" : ""}: ${joinValues(issue.keys, "، ")}`;
			case "invalid_key": return `معرف غير مقبول في ${issue.origin}`;
			case "invalid_union": return "مدخل غير مقبول";
			case "invalid_element": return `مدخل غير مقبول في ${issue.origin}`;
			default: return "مدخل غير مقبول";
		}
	};
};
function ar_default() {
	return { localeError: error$49() };
}
//#endregion
//#region node_modules/zod/v4/locales/az.js
var error$48 = () => {
	const Sizable = {
		string: {
			unit: "simvol",
			verb: "olmalıdır"
		},
		file: {
			unit: "bayt",
			verb: "olmalıdır"
		},
		array: {
			unit: "element",
			verb: "olmalıdır"
		},
		set: {
			unit: "element",
			verb: "olmalıdır"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "email address",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO datetime",
		date: "ISO date",
		time: "ISO time",
		duration: "ISO duration",
		ipv4: "IPv4 address",
		ipv6: "IPv6 address",
		cidrv4: "IPv4 range",
		cidrv6: "IPv6 range",
		base64: "base64-encoded string",
		base64url: "base64url-encoded string",
		json_string: "JSON string",
		e164: "E.164 number",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Yanlış dəyər: gözlənilən instanceof ${issue.expected}, daxil olan ${received}`;
				return `Yanlış dəyər: gözlənilən ${expected}, daxil olan ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Yanlış dəyər: gözlənilən ${stringifyPrimitive(issue.values[0])}`;
				return `Yanlış seçim: aşağıdakılardan biri olmalıdır: ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Çox böyük: gözlənilən ${issue.origin ?? "dəyər"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "element"}`;
				return `Çox böyük: gözlənilən ${issue.origin ?? "dəyər"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Çox kiçik: gözlənilən ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Çox kiçik: gözlənilən ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Yanlış mətn: "${_issue.prefix}" ilə başlamalıdır`;
				if (_issue.format === "ends_with") return `Yanlış mətn: "${_issue.suffix}" ilə bitməlidir`;
				if (_issue.format === "includes") return `Yanlış mətn: "${_issue.includes}" daxil olmalıdır`;
				if (_issue.format === "regex") return `Yanlış mətn: ${_issue.pattern} şablonuna uyğun olmalıdır`;
				return `Yanlış ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Yanlış ədəd: ${issue.divisor} ilə bölünə bilən olmalıdır`;
			case "unrecognized_keys": return `Tanınmayan açar${issue.keys.length > 1 ? "lar" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} daxilində yanlış açar`;
			case "invalid_union": return "Yanlış dəyər";
			case "invalid_element": return `${issue.origin} daxilində yanlış dəyər`;
			default: return `Yanlış dəyər`;
		}
	};
};
function az_default() {
	return { localeError: error$48() };
}
//#endregion
//#region node_modules/zod/v4/locales/be.js
function getBelarusianPlural(count, one, few, many) {
	const absCount = Math.abs(count);
	const lastDigit = absCount % 10;
	const lastTwoDigits = absCount % 100;
	if (lastTwoDigits >= 11 && lastTwoDigits <= 19) return many;
	if (lastDigit === 1) return one;
	if (lastDigit >= 2 && lastDigit <= 4) return few;
	return many;
}
var error$47 = () => {
	const Sizable = {
		string: {
			unit: {
				one: "сімвал",
				few: "сімвалы",
				many: "сімвалаў"
			},
			verb: "мець"
		},
		array: {
			unit: {
				one: "элемент",
				few: "элементы",
				many: "элементаў"
			},
			verb: "мець"
		},
		set: {
			unit: {
				one: "элемент",
				few: "элементы",
				many: "элементаў"
			},
			verb: "мець"
		},
		file: {
			unit: {
				one: "байт",
				few: "байты",
				many: "байтаў"
			},
			verb: "мець"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "увод",
		email: "email адрас",
		url: "URL",
		emoji: "эмодзі",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO дата і час",
		date: "ISO дата",
		time: "ISO час",
		duration: "ISO працягласць",
		ipv4: "IPv4 адрас",
		ipv6: "IPv6 адрас",
		cidrv4: "IPv4 дыяпазон",
		cidrv6: "IPv6 дыяпазон",
		base64: "радок у фармаце base64",
		base64url: "радок у фармаце base64url",
		json_string: "JSON радок",
		e164: "нумар E.164",
		jwt: "JWT",
		template_literal: "увод"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "лік",
		array: "масіў"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Няправільны ўвод: чакаўся instanceof ${issue.expected}, атрымана ${received}`;
				return `Няправільны ўвод: чакаўся ${expected}, атрымана ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Няправільны ўвод: чакалася ${stringifyPrimitive(issue.values[0])}`;
				return `Няправільны варыянт: чакаўся адзін з ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getBelarusianPlural(Number(issue.maximum), sizing.unit.one, sizing.unit.few, sizing.unit.many);
					return `Занадта вялікі: чакалася, што ${issue.origin ?? "значэнне"} павінна ${sizing.verb} ${adj}${issue.maximum.toString()} ${unit}`;
				}
				return `Занадта вялікі: чакалася, што ${issue.origin ?? "значэнне"} павінна быць ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getBelarusianPlural(Number(issue.minimum), sizing.unit.one, sizing.unit.few, sizing.unit.many);
					return `Занадта малы: чакалася, што ${issue.origin} павінна ${sizing.verb} ${adj}${issue.minimum.toString()} ${unit}`;
				}
				return `Занадта малы: чакалася, што ${issue.origin} павінна быць ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Няправільны радок: павінен пачынацца з "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Няправільны радок: павінен заканчвацца на "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Няправільны радок: павінен змяшчаць "${_issue.includes}"`;
				if (_issue.format === "regex") return `Няправільны радок: павінен адпавядаць шаблону ${_issue.pattern}`;
				return `Няправільны ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Няправільны лік: павінен быць кратным ${issue.divisor}`;
			case "unrecognized_keys": return `Нераспазнаны ${issue.keys.length > 1 ? "ключы" : "ключ"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Няправільны ключ у ${issue.origin}`;
			case "invalid_union": return "Няправільны ўвод";
			case "invalid_element": return `Няправільнае значэнне ў ${issue.origin}`;
			default: return `Няправільны ўвод`;
		}
	};
};
function be_default() {
	return { localeError: error$47() };
}
//#endregion
//#region node_modules/zod/v4/locales/bg.js
var error$46 = () => {
	const Sizable = {
		string: {
			unit: "символа",
			verb: "да съдържа"
		},
		file: {
			unit: "байта",
			verb: "да съдържа"
		},
		array: {
			unit: "елемента",
			verb: "да съдържа"
		},
		set: {
			unit: "елемента",
			verb: "да съдържа"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "вход",
		email: "имейл адрес",
		url: "URL",
		emoji: "емоджи",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO време",
		date: "ISO дата",
		time: "ISO време",
		duration: "ISO продължителност",
		ipv4: "IPv4 адрес",
		ipv6: "IPv6 адрес",
		cidrv4: "IPv4 диапазон",
		cidrv6: "IPv6 диапазон",
		base64: "base64-кодиран низ",
		base64url: "base64url-кодиран низ",
		json_string: "JSON низ",
		e164: "E.164 номер",
		jwt: "JWT",
		template_literal: "вход"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "число",
		array: "масив"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Невалиден вход: очакван instanceof ${issue.expected}, получен ${received}`;
				return `Невалиден вход: очакван ${expected}, получен ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Невалиден вход: очакван ${stringifyPrimitive(issue.values[0])}`;
				return `Невалидна опция: очаквано едно от ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Твърде голямо: очаква се ${issue.origin ?? "стойност"} да съдържа ${adj}${issue.maximum.toString()} ${sizing.unit ?? "елемента"}`;
				return `Твърде голямо: очаква се ${issue.origin ?? "стойност"} да бъде ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Твърде малко: очаква се ${issue.origin} да съдържа ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Твърде малко: очаква се ${issue.origin} да бъде ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Невалиден низ: трябва да започва с "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Невалиден низ: трябва да завършва с "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Невалиден низ: трябва да включва "${_issue.includes}"`;
				if (_issue.format === "regex") return `Невалиден низ: трябва да съвпада с ${_issue.pattern}`;
				let invalid_adj = "Невалиден";
				if (_issue.format === "emoji") invalid_adj = "Невалидно";
				if (_issue.format === "datetime") invalid_adj = "Невалидно";
				if (_issue.format === "date") invalid_adj = "Невалидна";
				if (_issue.format === "time") invalid_adj = "Невалидно";
				if (_issue.format === "duration") invalid_adj = "Невалидна";
				return `${invalid_adj} ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Невалидно число: трябва да бъде кратно на ${issue.divisor}`;
			case "unrecognized_keys": return `Неразпознат${issue.keys.length > 1 ? "и" : ""} ключ${issue.keys.length > 1 ? "ове" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Невалиден ключ в ${issue.origin}`;
			case "invalid_union": return "Невалиден вход";
			case "invalid_element": return `Невалидна стойност в ${issue.origin}`;
			default: return `Невалиден вход`;
		}
	};
};
function bg_default() {
	return { localeError: error$46() };
}
//#endregion
//#region node_modules/zod/v4/locales/ca.js
var error$45 = () => {
	const Sizable = {
		string: {
			unit: "caràcters",
			verb: "contenir"
		},
		file: {
			unit: "bytes",
			verb: "contenir"
		},
		array: {
			unit: "elements",
			verb: "contenir"
		},
		set: {
			unit: "elements",
			verb: "contenir"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "entrada",
		email: "adreça electrònica",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "data i hora ISO",
		date: "data ISO",
		time: "hora ISO",
		duration: "durada ISO",
		ipv4: "adreça IPv4",
		ipv6: "adreça IPv6",
		cidrv4: "rang IPv4",
		cidrv6: "rang IPv6",
		base64: "cadena codificada en base64",
		base64url: "cadena codificada en base64url",
		json_string: "cadena JSON",
		e164: "número E.164",
		jwt: "JWT",
		template_literal: "entrada"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Tipus invàlid: s'esperava instanceof ${issue.expected}, s'ha rebut ${received}`;
				return `Tipus invàlid: s'esperava ${expected}, s'ha rebut ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Valor invàlid: s'esperava ${stringifyPrimitive(issue.values[0])}`;
				return `Opció invàlida: s'esperava una de ${joinValues(issue.values, " o ")}`;
			case "too_big": {
				const adj = issue.inclusive ? "com a màxim" : "menys de";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} contingués ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "elements"}`;
				return `Massa gran: s'esperava que ${issue.origin ?? "el valor"} fos ${adj} ${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? "com a mínim" : "més de";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Massa petit: s'esperava que ${issue.origin} contingués ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
				return `Massa petit: s'esperava que ${issue.origin} fos ${adj} ${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Format invàlid: ha de començar amb "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Format invàlid: ha d'acabar amb "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Format invàlid: ha d'incloure "${_issue.includes}"`;
				if (_issue.format === "regex") return `Format invàlid: ha de coincidir amb el patró ${_issue.pattern}`;
				return `Format invàlid per a ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Número invàlid: ha de ser múltiple de ${issue.divisor}`;
			case "unrecognized_keys": return `Clau${issue.keys.length > 1 ? "s" : ""} no reconeguda${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Clau invàlida a ${issue.origin}`;
			case "invalid_union": return "Entrada invàlida";
			case "invalid_element": return `Element invàlid a ${issue.origin}`;
			default: return `Entrada invàlida`;
		}
	};
};
function ca_default() {
	return { localeError: error$45() };
}
//#endregion
//#region node_modules/zod/v4/locales/cs.js
var error$44 = () => {
	const Sizable = {
		string: {
			unit: "znaků",
			verb: "mít"
		},
		file: {
			unit: "bajtů",
			verb: "mít"
		},
		array: {
			unit: "prvků",
			verb: "mít"
		},
		set: {
			unit: "prvků",
			verb: "mít"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "regulární výraz",
		email: "e-mailová adresa",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "datum a čas ve formátu ISO",
		date: "datum ve formátu ISO",
		time: "čas ve formátu ISO",
		duration: "doba trvání ISO",
		ipv4: "IPv4 adresa",
		ipv6: "IPv6 adresa",
		cidrv4: "rozsah IPv4",
		cidrv6: "rozsah IPv6",
		base64: "řetězec zakódovaný ve formátu base64",
		base64url: "řetězec zakódovaný ve formátu base64url",
		json_string: "řetězec ve formátu JSON",
		e164: "číslo E.164",
		jwt: "JWT",
		template_literal: "vstup"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "číslo",
		string: "řetězec",
		function: "funkce",
		array: "pole"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Neplatný vstup: očekáváno instanceof ${issue.expected}, obdrženo ${received}`;
				return `Neplatný vstup: očekáváno ${expected}, obdrženo ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Neplatný vstup: očekáváno ${stringifyPrimitive(issue.values[0])}`;
				return `Neplatná možnost: očekávána jedna z hodnot ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Hodnota je příliš velká: ${issue.origin ?? "hodnota"} musí mít ${adj}${issue.maximum.toString()} ${sizing.unit ?? "prvků"}`;
				return `Hodnota je příliš velká: ${issue.origin ?? "hodnota"} musí být ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Hodnota je příliš malá: ${issue.origin ?? "hodnota"} musí mít ${adj}${issue.minimum.toString()} ${sizing.unit ?? "prvků"}`;
				return `Hodnota je příliš malá: ${issue.origin ?? "hodnota"} musí být ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Neplatný řetězec: musí začínat na "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Neplatný řetězec: musí končit na "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Neplatný řetězec: musí obsahovat "${_issue.includes}"`;
				if (_issue.format === "regex") return `Neplatný řetězec: musí odpovídat vzoru ${_issue.pattern}`;
				return `Neplatný formát ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Neplatné číslo: musí být násobkem ${issue.divisor}`;
			case "unrecognized_keys": return `Neznámé klíče: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Neplatný klíč v ${issue.origin}`;
			case "invalid_union": return "Neplatný vstup";
			case "invalid_element": return `Neplatná hodnota v ${issue.origin}`;
			default: return `Neplatný vstup`;
		}
	};
};
function cs_default() {
	return { localeError: error$44() };
}
//#endregion
//#region node_modules/zod/v4/locales/da.js
var error$43 = () => {
	const Sizable = {
		string: {
			unit: "tegn",
			verb: "havde"
		},
		file: {
			unit: "bytes",
			verb: "havde"
		},
		array: {
			unit: "elementer",
			verb: "indeholdt"
		},
		set: {
			unit: "elementer",
			verb: "indeholdt"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "e-mailadresse",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO dato- og klokkeslæt",
		date: "ISO-dato",
		time: "ISO-klokkeslæt",
		duration: "ISO-varighed",
		ipv4: "IPv4-område",
		ipv6: "IPv6-område",
		cidrv4: "IPv4-spektrum",
		cidrv6: "IPv6-spektrum",
		base64: "base64-kodet streng",
		base64url: "base64url-kodet streng",
		json_string: "JSON-streng",
		e164: "E.164-nummer",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = {
		nan: "NaN",
		string: "streng",
		number: "tal",
		boolean: "boolean",
		array: "liste",
		object: "objekt",
		set: "sæt",
		file: "fil"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ugyldigt input: forventede instanceof ${issue.expected}, fik ${received}`;
				return `Ugyldigt input: forventede ${expected}, fik ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ugyldig værdi: forventede ${stringifyPrimitive(issue.values[0])}`;
				return `Ugyldigt valg: forventede en af følgende ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `For stor: forventede ${origin ?? "value"} ${sizing.verb} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "elementer"}`;
				return `For stor: forventede ${origin ?? "value"} havde ${adj} ${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `For lille: forventede ${origin} ${sizing.verb} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
				return `For lille: forventede ${origin} havde ${adj} ${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ugyldig streng: skal starte med "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Ugyldig streng: skal ende med "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Ugyldig streng: skal indeholde "${_issue.includes}"`;
				if (_issue.format === "regex") return `Ugyldig streng: skal matche mønsteret ${_issue.pattern}`;
				return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Ugyldigt tal: skal være deleligt med ${issue.divisor}`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Ukendte nøgler" : "Ukendt nøgle"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Ugyldig nøgle i ${issue.origin}`;
			case "invalid_union": return "Ugyldigt input: matcher ingen af de tilladte typer";
			case "invalid_element": return `Ugyldig værdi i ${issue.origin}`;
			default: return `Ugyldigt input`;
		}
	};
};
function da_default() {
	return { localeError: error$43() };
}
//#endregion
//#region node_modules/zod/v4/locales/de.js
var error$42 = () => {
	const Sizable = {
		string: {
			unit: "Zeichen",
			verb: "zu haben"
		},
		file: {
			unit: "Bytes",
			verb: "zu haben"
		},
		array: {
			unit: "Elemente",
			verb: "zu haben"
		},
		set: {
			unit: "Elemente",
			verb: "zu haben"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "Eingabe",
		email: "E-Mail-Adresse",
		url: "URL",
		emoji: "Emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO-Datum und -Uhrzeit",
		date: "ISO-Datum",
		time: "ISO-Uhrzeit",
		duration: "ISO-Dauer",
		ipv4: "IPv4-Adresse",
		ipv6: "IPv6-Adresse",
		cidrv4: "IPv4-Bereich",
		cidrv6: "IPv6-Bereich",
		base64: "Base64-codierter String",
		base64url: "Base64-URL-codierter String",
		json_string: "JSON-String",
		e164: "E.164-Nummer",
		jwt: "JWT",
		template_literal: "Eingabe"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "Zahl",
		array: "Array"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ungültige Eingabe: erwartet instanceof ${issue.expected}, erhalten ${received}`;
				return `Ungültige Eingabe: erwartet ${expected}, erhalten ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ungültige Eingabe: erwartet ${stringifyPrimitive(issue.values[0])}`;
				return `Ungültige Option: erwartet eine von ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Zu groß: erwartet, dass ${issue.origin ?? "Wert"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "Elemente"} hat`;
				return `Zu groß: erwartet, dass ${issue.origin ?? "Wert"} ${adj}${issue.maximum.toString()} ist`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Zu klein: erwartet, dass ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} hat`;
				return `Zu klein: erwartet, dass ${issue.origin} ${adj}${issue.minimum.toString()} ist`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ungültiger String: muss mit "${_issue.prefix}" beginnen`;
				if (_issue.format === "ends_with") return `Ungültiger String: muss mit "${_issue.suffix}" enden`;
				if (_issue.format === "includes") return `Ungültiger String: muss "${_issue.includes}" enthalten`;
				if (_issue.format === "regex") return `Ungültiger String: muss dem Muster ${_issue.pattern} entsprechen`;
				return `Ungültig: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Ungültige Zahl: muss ein Vielfaches von ${issue.divisor} sein`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Unbekannte Schlüssel" : "Unbekannter Schlüssel"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Ungültiger Schlüssel in ${issue.origin}`;
			case "invalid_union": return "Ungültige Eingabe";
			case "invalid_element": return `Ungültiger Wert in ${issue.origin}`;
			default: return `Ungültige Eingabe`;
		}
	};
};
function de_default() {
	return { localeError: error$42() };
}
//#endregion
//#region node_modules/zod/v4/locales/el.js
var error$41 = () => {
	const Sizable = {
		string: {
			unit: "χαρακτήρες",
			verb: "να έχει"
		},
		file: {
			unit: "bytes",
			verb: "να έχει"
		},
		array: {
			unit: "στοιχεία",
			verb: "να έχει"
		},
		set: {
			unit: "στοιχεία",
			verb: "να έχει"
		},
		map: {
			unit: "καταχωρήσεις",
			verb: "να έχει"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "είσοδος",
		email: "διεύθυνση email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO ημερομηνία και ώρα",
		date: "ISO ημερομηνία",
		time: "ISO ώρα",
		duration: "ISO διάρκεια",
		ipv4: "διεύθυνση IPv4",
		ipv6: "διεύθυνση IPv6",
		mac: "διεύθυνση MAC",
		cidrv4: "εύρος IPv4",
		cidrv6: "εύρος IPv6",
		base64: "συμβολοσειρά κωδικοποιημένη σε base64",
		base64url: "συμβολοσειρά κωδικοποιημένη σε base64url",
		json_string: "συμβολοσειρά JSON",
		e164: "αριθμός E.164",
		jwt: "JWT",
		template_literal: "είσοδος"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (typeof issue.expected === "string" && /^[A-Z]/.test(issue.expected)) return `Μη έγκυρη είσοδος: αναμενόταν instanceof ${issue.expected}, λήφθηκε ${received}`;
				return `Μη έγκυρη είσοδος: αναμενόταν ${expected}, λήφθηκε ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Μη έγκυρη είσοδος: αναμενόταν ${stringifyPrimitive(issue.values[0])}`;
				return `Μη έγκυρη επιλογή: αναμενόταν ένα από ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Πολύ μεγάλο: αναμενόταν ${issue.origin ?? "τιμή"} να έχει ${adj}${issue.maximum.toString()} ${sizing.unit ?? "στοιχεία"}`;
				return `Πολύ μεγάλο: αναμενόταν ${issue.origin ?? "τιμή"} να είναι ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Πολύ μικρό: αναμενόταν ${issue.origin} να έχει ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Πολύ μικρό: αναμενόταν ${issue.origin} να είναι ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Μη έγκυρη συμβολοσειρά: πρέπει να ξεκινά με "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Μη έγκυρη συμβολοσειρά: πρέπει να τελειώνει με "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Μη έγκυρη συμβολοσειρά: πρέπει να περιέχει "${_issue.includes}"`;
				if (_issue.format === "regex") return `Μη έγκυρη συμβολοσειρά: πρέπει να ταιριάζει με το μοτίβο ${_issue.pattern}`;
				return `Μη έγκυρο: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Μη έγκυρος αριθμός: πρέπει να είναι πολλαπλάσιο του ${issue.divisor}`;
			case "unrecognized_keys": return `Άγνωστ${issue.keys.length > 1 ? "α" : "ο"} κλειδ${issue.keys.length > 1 ? "ιά" : "ί"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Μη έγκυρο κλειδί στο ${issue.origin}`;
			case "invalid_union": return "Μη έγκυρη είσοδος";
			case "invalid_element": return `Μη έγκυρη τιμή στο ${issue.origin}`;
			default: return `Μη έγκυρη είσοδος`;
		}
	};
};
function el_default() {
	return { localeError: error$41() };
}
//#endregion
//#region node_modules/zod/v4/locales/en.js
var error$40 = () => {
	const Sizable = {
		string: {
			unit: "characters",
			verb: "to have"
		},
		file: {
			unit: "bytes",
			verb: "to have"
		},
		array: {
			unit: "items",
			verb: "to have"
		},
		set: {
			unit: "items",
			verb: "to have"
		},
		map: {
			unit: "entries",
			verb: "to have"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "email address",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO datetime",
		date: "ISO date",
		time: "ISO time",
		duration: "ISO duration",
		ipv4: "IPv4 address",
		ipv6: "IPv6 address",
		mac: "MAC address",
		cidrv4: "IPv4 range",
		cidrv6: "IPv6 range",
		base64: "base64-encoded string",
		base64url: "base64url-encoded string",
		json_string: "JSON string",
		e164: "E.164 number",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				return `Invalid input: expected ${expected}, received ${TypeDictionary[receivedType] ?? receivedType}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Invalid input: expected ${stringifyPrimitive(issue.values[0])}`;
				return `Invalid option: expected one of ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Too big: expected ${issue.origin ?? "value"} to have ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elements"}`;
				return `Too big: expected ${issue.origin ?? "value"} to be ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Too small: expected ${issue.origin} to have ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Too small: expected ${issue.origin} to be ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Invalid string: must start with "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Invalid string: must end with "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Invalid string: must include "${_issue.includes}"`;
				if (_issue.format === "regex") return `Invalid string: must match pattern ${_issue.pattern}`;
				return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Invalid number: must be a multiple of ${issue.divisor}`;
			case "unrecognized_keys": return `Unrecognized key${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Invalid key in ${issue.origin}`;
			case "invalid_union":
				if (issue.options && Array.isArray(issue.options) && issue.options.length > 0) return `Invalid discriminator value. Expected ${issue.options.map((o) => `'${o}'`).join(" | ")}`;
				return "Invalid input";
			case "invalid_element": return `Invalid value in ${issue.origin}`;
			default: return `Invalid input`;
		}
	};
};
function en_default() {
	return { localeError: error$40() };
}
//#endregion
//#region node_modules/zod/v4/locales/eo.js
var error$39 = () => {
	const Sizable = {
		string: {
			unit: "karaktrojn",
			verb: "havi"
		},
		file: {
			unit: "bajtojn",
			verb: "havi"
		},
		array: {
			unit: "elementojn",
			verb: "havi"
		},
		set: {
			unit: "elementojn",
			verb: "havi"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "enigo",
		email: "retadreso",
		url: "URL",
		emoji: "emoĝio",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO-datotempo",
		date: "ISO-dato",
		time: "ISO-tempo",
		duration: "ISO-daŭro",
		ipv4: "IPv4-adreso",
		ipv6: "IPv6-adreso",
		cidrv4: "IPv4-rango",
		cidrv6: "IPv6-rango",
		base64: "64-ume kodita karaktraro",
		base64url: "URL-64-ume kodita karaktraro",
		json_string: "JSON-karaktraro",
		e164: "E.164-nombro",
		jwt: "JWT",
		template_literal: "enigo"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "nombro",
		array: "tabelo",
		null: "senvalora"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Nevalida enigo: atendiĝis instanceof ${issue.expected}, riceviĝis ${received}`;
				return `Nevalida enigo: atendiĝis ${expected}, riceviĝis ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Nevalida enigo: atendiĝis ${stringifyPrimitive(issue.values[0])}`;
				return `Nevalida opcio: atendiĝis unu el ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Tro granda: atendiĝis ke ${issue.origin ?? "valoro"} havu ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementojn"}`;
				return `Tro granda: atendiĝis ke ${issue.origin ?? "valoro"} havu ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Tro malgranda: atendiĝis ke ${issue.origin} havu ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Tro malgranda: atendiĝis ke ${issue.origin} estu ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Nevalida karaktraro: devas komenciĝi per "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Nevalida karaktraro: devas finiĝi per "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Nevalida karaktraro: devas inkluzivi "${_issue.includes}"`;
				if (_issue.format === "regex") return `Nevalida karaktraro: devas kongrui kun la modelo ${_issue.pattern}`;
				return `Nevalida ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Nevalida nombro: devas esti oblo de ${issue.divisor}`;
			case "unrecognized_keys": return `Nekonata${issue.keys.length > 1 ? "j" : ""} ŝlosilo${issue.keys.length > 1 ? "j" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Nevalida ŝlosilo en ${issue.origin}`;
			case "invalid_union": return "Nevalida enigo";
			case "invalid_element": return `Nevalida valoro en ${issue.origin}`;
			default: return `Nevalida enigo`;
		}
	};
};
function eo_default() {
	return { localeError: error$39() };
}
//#endregion
//#region node_modules/zod/v4/locales/es.js
var error$38 = () => {
	const Sizable = {
		string: {
			unit: "caracteres",
			verb: "tener"
		},
		file: {
			unit: "bytes",
			verb: "tener"
		},
		array: {
			unit: "elementos",
			verb: "tener"
		},
		set: {
			unit: "elementos",
			verb: "tener"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "entrada",
		email: "dirección de correo electrónico",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "fecha y hora ISO",
		date: "fecha ISO",
		time: "hora ISO",
		duration: "duración ISO",
		ipv4: "dirección IPv4",
		ipv6: "dirección IPv6",
		cidrv4: "rango IPv4",
		cidrv6: "rango IPv6",
		base64: "cadena codificada en base64",
		base64url: "URL codificada en base64",
		json_string: "cadena JSON",
		e164: "número E.164",
		jwt: "JWT",
		template_literal: "entrada"
	};
	const TypeDictionary = {
		nan: "NaN",
		string: "texto",
		number: "número",
		boolean: "booleano",
		array: "arreglo",
		object: "objeto",
		set: "conjunto",
		file: "archivo",
		date: "fecha",
		bigint: "número grande",
		symbol: "símbolo",
		undefined: "indefinido",
		null: "nulo",
		function: "función",
		map: "mapa",
		record: "registro",
		tuple: "tupla",
		enum: "enumeración",
		union: "unión",
		literal: "literal",
		promise: "promesa",
		void: "vacío",
		never: "nunca",
		unknown: "desconocido",
		any: "cualquiera"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Entrada inválida: se esperaba instanceof ${issue.expected}, recibido ${received}`;
				return `Entrada inválida: se esperaba ${expected}, recibido ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Entrada inválida: se esperaba ${stringifyPrimitive(issue.values[0])}`;
				return `Opción inválida: se esperaba una de ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `Demasiado grande: se esperaba que ${origin ?? "valor"} tuviera ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementos"}`;
				return `Demasiado grande: se esperaba que ${origin ?? "valor"} fuera ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `Demasiado pequeño: se esperaba que ${origin} tuviera ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Demasiado pequeño: se esperaba que ${origin} fuera ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Cadena inválida: debe comenzar con "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Cadena inválida: debe terminar en "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Cadena inválida: debe incluir "${_issue.includes}"`;
				if (_issue.format === "regex") return `Cadena inválida: debe coincidir con el patrón ${_issue.pattern}`;
				return `Inválido ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Número inválido: debe ser múltiplo de ${issue.divisor}`;
			case "unrecognized_keys": return `Llave${issue.keys.length > 1 ? "s" : ""} desconocida${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Llave inválida en ${TypeDictionary[issue.origin] ?? issue.origin}`;
			case "invalid_union": return "Entrada inválida";
			case "invalid_element": return `Valor inválido en ${TypeDictionary[issue.origin] ?? issue.origin}`;
			default: return `Entrada inválida`;
		}
	};
};
function es_default() {
	return { localeError: error$38() };
}
//#endregion
//#region node_modules/zod/v4/locales/fa.js
var error$37 = () => {
	const Sizable = {
		string: {
			unit: "کاراکتر",
			verb: "داشته باشد"
		},
		file: {
			unit: "بایت",
			verb: "داشته باشد"
		},
		array: {
			unit: "آیتم",
			verb: "داشته باشد"
		},
		set: {
			unit: "آیتم",
			verb: "داشته باشد"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ورودی",
		email: "آدرس ایمیل",
		url: "URL",
		emoji: "ایموجی",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "تاریخ و زمان ایزو",
		date: "تاریخ ایزو",
		time: "زمان ایزو",
		duration: "مدت زمان ایزو",
		ipv4: "IPv4 آدرس",
		ipv6: "IPv6 آدرس",
		cidrv4: "IPv4 دامنه",
		cidrv6: "IPv6 دامنه",
		base64: "base64-encoded رشته",
		base64url: "base64url-encoded رشته",
		json_string: "JSON رشته",
		e164: "E.164 عدد",
		jwt: "JWT",
		template_literal: "ورودی"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "عدد",
		array: "آرایه"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `ورودی نامعتبر: می‌بایست instanceof ${issue.expected} می‌بود، ${received} دریافت شد`;
				return `ورودی نامعتبر: می‌بایست ${expected} می‌بود، ${received} دریافت شد`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `ورودی نامعتبر: می‌بایست ${stringifyPrimitive(issue.values[0])} می‌بود`;
				return `گزینه نامعتبر: می‌بایست یکی از ${joinValues(issue.values, "|")} می‌بود`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} ${sizing.unit ?? "عنصر"} باشد`;
				return `خیلی بزرگ: ${issue.origin ?? "مقدار"} باید ${adj}${issue.maximum.toString()} باشد`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} ${sizing.unit} باشد`;
				return `خیلی کوچک: ${issue.origin} باید ${adj}${issue.minimum.toString()} باشد`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `رشته نامعتبر: باید با "${_issue.prefix}" شروع شود`;
				if (_issue.format === "ends_with") return `رشته نامعتبر: باید با "${_issue.suffix}" تمام شود`;
				if (_issue.format === "includes") return `رشته نامعتبر: باید شامل "${_issue.includes}" باشد`;
				if (_issue.format === "regex") return `رشته نامعتبر: باید با الگوی ${_issue.pattern} مطابقت داشته باشد`;
				return `${FormatDictionary[_issue.format] ?? issue.format} نامعتبر`;
			}
			case "not_multiple_of": return `عدد نامعتبر: باید مضرب ${issue.divisor} باشد`;
			case "unrecognized_keys": return `کلید${issue.keys.length > 1 ? "های" : ""} ناشناس: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `کلید ناشناس در ${issue.origin}`;
			case "invalid_union": return `ورودی نامعتبر`;
			case "invalid_element": return `مقدار نامعتبر در ${issue.origin}`;
			default: return `ورودی نامعتبر`;
		}
	};
};
function fa_default() {
	return { localeError: error$37() };
}
//#endregion
//#region node_modules/zod/v4/locales/fi.js
var error$36 = () => {
	const Sizable = {
		string: {
			unit: "merkkiä",
			subject: "merkkijonon"
		},
		file: {
			unit: "tavua",
			subject: "tiedoston"
		},
		array: {
			unit: "alkiota",
			subject: "listan"
		},
		set: {
			unit: "alkiota",
			subject: "joukon"
		},
		number: {
			unit: "",
			subject: "luvun"
		},
		bigint: {
			unit: "",
			subject: "suuren kokonaisluvun"
		},
		int: {
			unit: "",
			subject: "kokonaisluvun"
		},
		date: {
			unit: "",
			subject: "päivämäärän"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "säännöllinen lauseke",
		email: "sähköpostiosoite",
		url: "URL-osoite",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO-aikaleima",
		date: "ISO-päivämäärä",
		time: "ISO-aika",
		duration: "ISO-kesto",
		ipv4: "IPv4-osoite",
		ipv6: "IPv6-osoite",
		cidrv4: "IPv4-alue",
		cidrv6: "IPv6-alue",
		base64: "base64-koodattu merkkijono",
		base64url: "base64url-koodattu merkkijono",
		json_string: "JSON-merkkijono",
		e164: "E.164-luku",
		jwt: "JWT",
		template_literal: "templaattimerkkijono"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Virheellinen tyyppi: odotettiin instanceof ${issue.expected}, oli ${received}`;
				return `Virheellinen tyyppi: odotettiin ${expected}, oli ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Virheellinen syöte: täytyy olla ${stringifyPrimitive(issue.values[0])}`;
				return `Virheellinen valinta: täytyy olla yksi seuraavista: ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Liian suuri: ${sizing.subject} täytyy olla ${adj}${issue.maximum.toString()} ${sizing.unit}`.trim();
				return `Liian suuri: arvon täytyy olla ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Liian pieni: ${sizing.subject} täytyy olla ${adj}${issue.minimum.toString()} ${sizing.unit}`.trim();
				return `Liian pieni: arvon täytyy olla ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Virheellinen syöte: täytyy alkaa "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Virheellinen syöte: täytyy loppua "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Virheellinen syöte: täytyy sisältää "${_issue.includes}"`;
				if (_issue.format === "regex") return `Virheellinen syöte: täytyy vastata säännöllistä lauseketta ${_issue.pattern}`;
				return `Virheellinen ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Virheellinen luku: täytyy olla luvun ${issue.divisor} monikerta`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Tuntemattomat avaimet" : "Tuntematon avain"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return "Virheellinen avain tietueessa";
			case "invalid_union": return "Virheellinen unioni";
			case "invalid_element": return "Virheellinen arvo joukossa";
			default: return `Virheellinen syöte`;
		}
	};
};
function fi_default() {
	return { localeError: error$36() };
}
//#endregion
//#region node_modules/zod/v4/locales/fr.js
var error$35 = () => {
	const Sizable = {
		string: {
			unit: "caractères",
			verb: "avoir"
		},
		file: {
			unit: "octets",
			verb: "avoir"
		},
		array: {
			unit: "éléments",
			verb: "avoir"
		},
		set: {
			unit: "éléments",
			verb: "avoir"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "entrée",
		email: "adresse e-mail",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "date et heure ISO",
		date: "date ISO",
		time: "heure ISO",
		duration: "durée ISO",
		ipv4: "adresse IPv4",
		ipv6: "adresse IPv6",
		cidrv4: "plage IPv4",
		cidrv6: "plage IPv6",
		base64: "chaîne encodée en base64",
		base64url: "chaîne encodée en base64url",
		json_string: "chaîne JSON",
		e164: "numéro E.164",
		jwt: "JWT",
		template_literal: "entrée"
	};
	const TypeDictionary = {
		string: "chaîne",
		number: "nombre",
		int: "entier",
		boolean: "booléen",
		bigint: "grand entier",
		symbol: "symbole",
		undefined: "indéfini",
		null: "null",
		never: "jamais",
		void: "vide",
		date: "date",
		array: "tableau",
		object: "objet",
		tuple: "tuple",
		record: "enregistrement",
		map: "carte",
		set: "ensemble",
		file: "fichier",
		nonoptional: "non-optionnel",
		nan: "NaN",
		function: "fonction"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Entrée invalide : instanceof ${issue.expected} attendu, ${received} reçu`;
				return `Entrée invalide : ${expected} attendu, ${received} reçu`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Entrée invalide : ${stringifyPrimitive(issue.values[0])} attendu`;
				return `Option invalide : une valeur parmi ${joinValues(issue.values, "|")} attendue`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Trop grand : ${TypeDictionary[issue.origin] ?? "valeur"} doit ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "élément(s)"}`;
				return `Trop grand : ${TypeDictionary[issue.origin] ?? "valeur"} doit être ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Trop petit : ${TypeDictionary[issue.origin] ?? "valeur"} doit ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Trop petit : ${TypeDictionary[issue.origin] ?? "valeur"} doit être ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Chaîne invalide : doit commencer par "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Chaîne invalide : doit se terminer par "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Chaîne invalide : doit inclure "${_issue.includes}"`;
				if (_issue.format === "regex") return `Chaîne invalide : doit correspondre au modèle ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} invalide`;
			}
			case "not_multiple_of": return `Nombre invalide : doit être un multiple de ${issue.divisor}`;
			case "unrecognized_keys": return `Clé${issue.keys.length > 1 ? "s" : ""} non reconnue${issue.keys.length > 1 ? "s" : ""} : ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Clé invalide dans ${issue.origin}`;
			case "invalid_union": return "Entrée invalide";
			case "invalid_element": return `Valeur invalide dans ${issue.origin}`;
			default: return `Entrée invalide`;
		}
	};
};
function fr_default() {
	return { localeError: error$35() };
}
//#endregion
//#region node_modules/zod/v4/locales/fr-CA.js
var error$34 = () => {
	const Sizable = {
		string: {
			unit: "caractères",
			verb: "avoir"
		},
		file: {
			unit: "octets",
			verb: "avoir"
		},
		array: {
			unit: "éléments",
			verb: "avoir"
		},
		set: {
			unit: "éléments",
			verb: "avoir"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "entrée",
		email: "adresse courriel",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "date-heure ISO",
		date: "date ISO",
		time: "heure ISO",
		duration: "durée ISO",
		ipv4: "adresse IPv4",
		ipv6: "adresse IPv6",
		cidrv4: "plage IPv4",
		cidrv6: "plage IPv6",
		base64: "chaîne encodée en base64",
		base64url: "chaîne encodée en base64url",
		json_string: "chaîne JSON",
		e164: "numéro E.164",
		jwt: "JWT",
		template_literal: "entrée"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Entrée invalide : attendu instanceof ${issue.expected}, reçu ${received}`;
				return `Entrée invalide : attendu ${expected}, reçu ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Entrée invalide : attendu ${stringifyPrimitive(issue.values[0])}`;
				return `Option invalide : attendu l'une des valeurs suivantes ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "≤" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Trop grand : attendu que ${issue.origin ?? "la valeur"} ait ${adj}${issue.maximum.toString()} ${sizing.unit}`;
				return `Trop grand : attendu que ${issue.origin ?? "la valeur"} soit ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? "≥" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Trop petit : attendu que ${issue.origin} ait ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Trop petit : attendu que ${issue.origin} soit ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Chaîne invalide : doit commencer par "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Chaîne invalide : doit se terminer par "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Chaîne invalide : doit inclure "${_issue.includes}"`;
				if (_issue.format === "regex") return `Chaîne invalide : doit correspondre au motif ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} invalide`;
			}
			case "not_multiple_of": return `Nombre invalide : doit être un multiple de ${issue.divisor}`;
			case "unrecognized_keys": return `Clé${issue.keys.length > 1 ? "s" : ""} non reconnue${issue.keys.length > 1 ? "s" : ""} : ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Clé invalide dans ${issue.origin}`;
			case "invalid_union": return "Entrée invalide";
			case "invalid_element": return `Valeur invalide dans ${issue.origin}`;
			default: return `Entrée invalide`;
		}
	};
};
function fr_CA_default() {
	return { localeError: error$34() };
}
//#endregion
//#region node_modules/zod/v4/locales/he.js
var error$33 = () => {
	const TypeNames = {
		string: {
			label: "מחרוזת",
			gender: "f"
		},
		number: {
			label: "מספר",
			gender: "m"
		},
		boolean: {
			label: "ערך בוליאני",
			gender: "m"
		},
		bigint: {
			label: "BigInt",
			gender: "m"
		},
		date: {
			label: "תאריך",
			gender: "m"
		},
		array: {
			label: "מערך",
			gender: "m"
		},
		object: {
			label: "אובייקט",
			gender: "m"
		},
		null: {
			label: "ערך ריק (null)",
			gender: "m"
		},
		undefined: {
			label: "ערך לא מוגדר (undefined)",
			gender: "m"
		},
		symbol: {
			label: "סימבול (Symbol)",
			gender: "m"
		},
		function: {
			label: "פונקציה",
			gender: "f"
		},
		map: {
			label: "מפה (Map)",
			gender: "f"
		},
		set: {
			label: "קבוצה (Set)",
			gender: "f"
		},
		file: {
			label: "קובץ",
			gender: "m"
		},
		promise: {
			label: "Promise",
			gender: "m"
		},
		NaN: {
			label: "NaN",
			gender: "m"
		},
		unknown: {
			label: "ערך לא ידוע",
			gender: "m"
		},
		value: {
			label: "ערך",
			gender: "m"
		}
	};
	const Sizable = {
		string: {
			unit: "תווים",
			shortLabel: "קצר",
			longLabel: "ארוך"
		},
		file: {
			unit: "בייטים",
			shortLabel: "קטן",
			longLabel: "גדול"
		},
		array: {
			unit: "פריטים",
			shortLabel: "קטן",
			longLabel: "גדול"
		},
		set: {
			unit: "פריטים",
			shortLabel: "קטן",
			longLabel: "גדול"
		},
		number: {
			unit: "",
			shortLabel: "קטן",
			longLabel: "גדול"
		}
	};
	const typeEntry = (t) => t ? TypeNames[t] : void 0;
	const typeLabel = (t) => {
		const e = typeEntry(t);
		if (e) return e.label;
		return t ?? TypeNames.unknown.label;
	};
	const withDefinite = (t) => `ה${typeLabel(t)}`;
	const verbFor = (t) => {
		return (typeEntry(t)?.gender ?? "m") === "f" ? "צריכה להיות" : "צריך להיות";
	};
	const getSizing = (origin) => {
		if (!origin) return null;
		return Sizable[origin] ?? null;
	};
	const FormatDictionary = {
		regex: {
			label: "קלט",
			gender: "m"
		},
		email: {
			label: "כתובת אימייל",
			gender: "f"
		},
		url: {
			label: "כתובת רשת",
			gender: "f"
		},
		emoji: {
			label: "אימוג'י",
			gender: "m"
		},
		uuid: {
			label: "UUID",
			gender: "m"
		},
		nanoid: {
			label: "nanoid",
			gender: "m"
		},
		guid: {
			label: "GUID",
			gender: "m"
		},
		cuid: {
			label: "cuid",
			gender: "m"
		},
		cuid2: {
			label: "cuid2",
			gender: "m"
		},
		ulid: {
			label: "ULID",
			gender: "m"
		},
		xid: {
			label: "XID",
			gender: "m"
		},
		ksuid: {
			label: "KSUID",
			gender: "m"
		},
		datetime: {
			label: "תאריך וזמן ISO",
			gender: "m"
		},
		date: {
			label: "תאריך ISO",
			gender: "m"
		},
		time: {
			label: "זמן ISO",
			gender: "m"
		},
		duration: {
			label: "משך זמן ISO",
			gender: "m"
		},
		ipv4: {
			label: "כתובת IPv4",
			gender: "f"
		},
		ipv6: {
			label: "כתובת IPv6",
			gender: "f"
		},
		cidrv4: {
			label: "טווח IPv4",
			gender: "m"
		},
		cidrv6: {
			label: "טווח IPv6",
			gender: "m"
		},
		base64: {
			label: "מחרוזת בבסיס 64",
			gender: "f"
		},
		base64url: {
			label: "מחרוזת בבסיס 64 לכתובות רשת",
			gender: "f"
		},
		json_string: {
			label: "מחרוזת JSON",
			gender: "f"
		},
		e164: {
			label: "מספר E.164",
			gender: "m"
		},
		jwt: {
			label: "JWT",
			gender: "m"
		},
		ends_with: {
			label: "קלט",
			gender: "m"
		},
		includes: {
			label: "קלט",
			gender: "m"
		},
		lowercase: {
			label: "קלט",
			gender: "m"
		},
		starts_with: {
			label: "קלט",
			gender: "m"
		},
		uppercase: {
			label: "קלט",
			gender: "m"
		}
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expectedKey = issue.expected;
				const expected = TypeDictionary[expectedKey ?? ""] ?? typeLabel(expectedKey);
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? TypeNames[receivedType]?.label ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `קלט לא תקין: צריך להיות instanceof ${issue.expected}, התקבל ${received}`;
				return `קלט לא תקין: צריך להיות ${expected}, התקבל ${received}`;
			}
			case "invalid_value": {
				if (issue.values.length === 1) return `ערך לא תקין: הערך חייב להיות ${stringifyPrimitive(issue.values[0])}`;
				const stringified = issue.values.map((v) => stringifyPrimitive(v));
				if (issue.values.length === 2) return `ערך לא תקין: האפשרויות המתאימות הן ${stringified[0]} או ${stringified[1]}`;
				const lastValue = stringified[stringified.length - 1];
				return `ערך לא תקין: האפשרויות המתאימות הן ${stringified.slice(0, -1).join(", ")} או ${lastValue}`;
			}
			case "too_big": {
				const sizing = getSizing(issue.origin);
				const subject = withDefinite(issue.origin ?? "value");
				if (issue.origin === "string") return `${sizing?.longLabel ?? "ארוך"} מדי: ${subject} צריכה להכיל ${issue.maximum.toString()} ${sizing?.unit ?? ""} ${issue.inclusive ? "או פחות" : "לכל היותר"}`.trim();
				if (issue.origin === "number") return `גדול מדי: ${subject} צריך להיות ${issue.inclusive ? `קטן או שווה ל-${issue.maximum}` : `קטן מ-${issue.maximum}`}`;
				if (issue.origin === "array" || issue.origin === "set") return `גדול מדי: ${subject} ${issue.origin === "set" ? "צריכה" : "צריך"} להכיל ${issue.inclusive ? `${issue.maximum} ${sizing?.unit ?? ""} או פחות` : `פחות מ-${issue.maximum} ${sizing?.unit ?? ""}`}`.trim();
				const adj = issue.inclusive ? "<=" : "<";
				const be = verbFor(issue.origin ?? "value");
				if (sizing?.unit) return `${sizing.longLabel} מדי: ${subject} ${be} ${adj}${issue.maximum.toString()} ${sizing.unit}`;
				return `${sizing?.longLabel ?? "גדול"} מדי: ${subject} ${be} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const sizing = getSizing(issue.origin);
				const subject = withDefinite(issue.origin ?? "value");
				if (issue.origin === "string") return `${sizing?.shortLabel ?? "קצר"} מדי: ${subject} צריכה להכיל ${issue.minimum.toString()} ${sizing?.unit ?? ""} ${issue.inclusive ? "או יותר" : "לפחות"}`.trim();
				if (issue.origin === "number") return `קטן מדי: ${subject} צריך להיות ${issue.inclusive ? `גדול או שווה ל-${issue.minimum}` : `גדול מ-${issue.minimum}`}`;
				if (issue.origin === "array" || issue.origin === "set") {
					const verb = issue.origin === "set" ? "צריכה" : "צריך";
					if (issue.minimum === 1 && issue.inclusive) return `קטן מדי: ${subject} ${verb} להכיל ${issue.origin === "set" ? "לפחות פריט אחד" : "לפחות פריט אחד"}`;
					return `קטן מדי: ${subject} ${verb} להכיל ${issue.inclusive ? `${issue.minimum} ${sizing?.unit ?? ""} או יותר` : `יותר מ-${issue.minimum} ${sizing?.unit ?? ""}`}`.trim();
				}
				const adj = issue.inclusive ? ">=" : ">";
				const be = verbFor(issue.origin ?? "value");
				if (sizing?.unit) return `${sizing.shortLabel} מדי: ${subject} ${be} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `${sizing?.shortLabel ?? "קטן"} מדי: ${subject} ${be} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `המחרוזת חייבת להתחיל ב "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `המחרוזת חייבת להסתיים ב "${_issue.suffix}"`;
				if (_issue.format === "includes") return `המחרוזת חייבת לכלול "${_issue.includes}"`;
				if (_issue.format === "regex") return `המחרוזת חייבת להתאים לתבנית ${_issue.pattern}`;
				const nounEntry = FormatDictionary[_issue.format];
				return `${nounEntry?.label ?? _issue.format} לא ${(nounEntry?.gender ?? "m") === "f" ? "תקינה" : "תקין"}`;
			}
			case "not_multiple_of": return `מספר לא תקין: חייב להיות מכפלה של ${issue.divisor}`;
			case "unrecognized_keys": return `מפתח${issue.keys.length > 1 ? "ות" : ""} לא מזוה${issue.keys.length > 1 ? "ים" : "ה"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `שדה לא תקין באובייקט`;
			case "invalid_union": return "קלט לא תקין";
			case "invalid_element": return `ערך לא תקין ב${withDefinite(issue.origin ?? "array")}`;
			default: return `קלט לא תקין`;
		}
	};
};
function he_default() {
	return { localeError: error$33() };
}
//#endregion
//#region node_modules/zod/v4/locales/hr.js
var error$32 = () => {
	const Sizable = {
		string: {
			unit: "znakova",
			verb: "imati"
		},
		file: {
			unit: "bajtova",
			verb: "imati"
		},
		array: {
			unit: "stavki",
			verb: "imati"
		},
		set: {
			unit: "stavki",
			verb: "imati"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "unos",
		email: "email adresa",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO datum i vrijeme",
		date: "ISO datum",
		time: "ISO vrijeme",
		duration: "ISO trajanje",
		ipv4: "IPv4 adresa",
		ipv6: "IPv6 adresa",
		cidrv4: "IPv4 raspon",
		cidrv6: "IPv6 raspon",
		base64: "base64 kodirani tekst",
		base64url: "base64url kodirani tekst",
		json_string: "JSON tekst",
		e164: "E.164 broj",
		jwt: "JWT",
		template_literal: "unos"
	};
	const TypeDictionary = {
		nan: "NaN",
		string: "tekst",
		number: "broj",
		boolean: "boolean",
		array: "niz",
		object: "objekt",
		set: "skup",
		file: "datoteka",
		date: "datum",
		bigint: "bigint",
		symbol: "simbol",
		undefined: "undefined",
		null: "null",
		function: "funkcija",
		map: "mapa"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Neispravan unos: očekuje se instanceof ${issue.expected}, a primljeno je ${received}`;
				return `Neispravan unos: očekuje se ${expected}, a primljeno je ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Neispravna vrijednost: očekivano ${stringifyPrimitive(issue.values[0])}`;
				return `Neispravna opcija: očekivano jedno od ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `Preveliko: očekivano da ${origin ?? "vrijednost"} ima ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elemenata"}`;
				return `Preveliko: očekivano da ${origin ?? "vrijednost"} bude ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				if (sizing) return `Premalo: očekivano da ${origin} ima ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Premalo: očekivano da ${origin} bude ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Neispravan tekst: mora započinjati s "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Neispravan tekst: mora završavati s "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Neispravan tekst: mora sadržavati "${_issue.includes}"`;
				if (_issue.format === "regex") return `Neispravan tekst: mora odgovarati uzorku ${_issue.pattern}`;
				return `Neispravna ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Neispravan broj: mora biti višekratnik od ${issue.divisor}`;
			case "unrecognized_keys": return `Neprepoznat${issue.keys.length > 1 ? "i ključevi" : " ključ"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Neispravan ključ u ${TypeDictionary[issue.origin] ?? issue.origin}`;
			case "invalid_union": return "Neispravan unos";
			case "invalid_element": return `Neispravna vrijednost u ${TypeDictionary[issue.origin] ?? issue.origin}`;
			default: return `Neispravan unos`;
		}
	};
};
function hr_default() {
	return { localeError: error$32() };
}
//#endregion
//#region node_modules/zod/v4/locales/hu.js
var error$31 = () => {
	const Sizable = {
		string: {
			unit: "karakter",
			verb: "legyen"
		},
		file: {
			unit: "byte",
			verb: "legyen"
		},
		array: {
			unit: "elem",
			verb: "legyen"
		},
		set: {
			unit: "elem",
			verb: "legyen"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "bemenet",
		email: "email cím",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO időbélyeg",
		date: "ISO dátum",
		time: "ISO idő",
		duration: "ISO időintervallum",
		ipv4: "IPv4 cím",
		ipv6: "IPv6 cím",
		cidrv4: "IPv4 tartomány",
		cidrv6: "IPv6 tartomány",
		base64: "base64-kódolt string",
		base64url: "base64url-kódolt string",
		json_string: "JSON string",
		e164: "E.164 szám",
		jwt: "JWT",
		template_literal: "bemenet"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "szám",
		array: "tömb"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Érvénytelen bemenet: a várt érték instanceof ${issue.expected}, a kapott érték ${received}`;
				return `Érvénytelen bemenet: a várt érték ${expected}, a kapott érték ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Érvénytelen bemenet: a várt érték ${stringifyPrimitive(issue.values[0])}`;
				return `Érvénytelen opció: valamelyik érték várt ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Túl nagy: ${issue.origin ?? "érték"} mérete túl nagy ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elem"}`;
				return `Túl nagy: a bemeneti érték ${issue.origin ?? "érték"} túl nagy: ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Túl kicsi: a bemeneti érték ${issue.origin} mérete túl kicsi ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Túl kicsi: a bemeneti érték ${issue.origin} túl kicsi ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Érvénytelen string: "${_issue.prefix}" értékkel kell kezdődnie`;
				if (_issue.format === "ends_with") return `Érvénytelen string: "${_issue.suffix}" értékkel kell végződnie`;
				if (_issue.format === "includes") return `Érvénytelen string: "${_issue.includes}" értéket kell tartalmaznia`;
				if (_issue.format === "regex") return `Érvénytelen string: ${_issue.pattern} mintának kell megfelelnie`;
				return `Érvénytelen ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Érvénytelen szám: ${issue.divisor} többszörösének kell lennie`;
			case "unrecognized_keys": return `Ismeretlen kulcs${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Érvénytelen kulcs ${issue.origin}`;
			case "invalid_union": return "Érvénytelen bemenet";
			case "invalid_element": return `Érvénytelen érték: ${issue.origin}`;
			default: return `Érvénytelen bemenet`;
		}
	};
};
function hu_default() {
	return { localeError: error$31() };
}
//#endregion
//#region node_modules/zod/v4/locales/hy.js
function getArmenianPlural(count, one, many) {
	return Math.abs(count) === 1 ? one : many;
}
function withDefiniteArticle(word) {
	if (!word) return "";
	const vowels = [
		"ա",
		"ե",
		"ը",
		"ի",
		"ո",
		"ու",
		"օ"
	];
	const lastChar = word[word.length - 1];
	return word + (vowels.includes(lastChar) ? "ն" : "ը");
}
var error$30 = () => {
	const Sizable = {
		string: {
			unit: {
				one: "նշան",
				many: "նշաններ"
			},
			verb: "ունենալ"
		},
		file: {
			unit: {
				one: "բայթ",
				many: "բայթեր"
			},
			verb: "ունենալ"
		},
		array: {
			unit: {
				one: "տարր",
				many: "տարրեր"
			},
			verb: "ունենալ"
		},
		set: {
			unit: {
				one: "տարր",
				many: "տարրեր"
			},
			verb: "ունենալ"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "մուտք",
		email: "էլ. հասցե",
		url: "URL",
		emoji: "էմոջի",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO ամսաթիվ և ժամ",
		date: "ISO ամսաթիվ",
		time: "ISO ժամ",
		duration: "ISO տևողություն",
		ipv4: "IPv4 հասցե",
		ipv6: "IPv6 հասցե",
		cidrv4: "IPv4 միջակայք",
		cidrv6: "IPv6 միջակայք",
		base64: "base64 ձևաչափով տող",
		base64url: "base64url ձևաչափով տող",
		json_string: "JSON տող",
		e164: "E.164 համար",
		jwt: "JWT",
		template_literal: "մուտք"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "թիվ",
		array: "զանգված"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Սխալ մուտքագրում․ սպասվում էր instanceof ${issue.expected}, ստացվել է ${received}`;
				return `Սխալ մուտքագրում․ սպասվում էր ${expected}, ստացվել է ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Սխալ մուտքագրում․ սպասվում էր ${stringifyPrimitive(issue.values[1])}`;
				return `Սխալ տարբերակ․ սպասվում էր հետևյալներից մեկը՝ ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getArmenianPlural(Number(issue.maximum), sizing.unit.one, sizing.unit.many);
					return `Չափազանց մեծ արժեք․ սպասվում է, որ ${withDefiniteArticle(issue.origin ?? "արժեք")} կունենա ${adj}${issue.maximum.toString()} ${unit}`;
				}
				return `Չափազանց մեծ արժեք․ սպասվում է, որ ${withDefiniteArticle(issue.origin ?? "արժեք")} լինի ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getArmenianPlural(Number(issue.minimum), sizing.unit.one, sizing.unit.many);
					return `Չափազանց փոքր արժեք․ սպասվում է, որ ${withDefiniteArticle(issue.origin)} կունենա ${adj}${issue.minimum.toString()} ${unit}`;
				}
				return `Չափազանց փոքր արժեք․ սպասվում է, որ ${withDefiniteArticle(issue.origin)} լինի ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Սխալ տող․ պետք է սկսվի "${_issue.prefix}"-ով`;
				if (_issue.format === "ends_with") return `Սխալ տող․ պետք է ավարտվի "${_issue.suffix}"-ով`;
				if (_issue.format === "includes") return `Սխալ տող․ պետք է պարունակի "${_issue.includes}"`;
				if (_issue.format === "regex") return `Սխալ տող․ պետք է համապատասխանի ${_issue.pattern} ձևաչափին`;
				return `Սխալ ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Սխալ թիվ․ պետք է բազմապատիկ լինի ${issue.divisor}-ի`;
			case "unrecognized_keys": return `Չճանաչված բանալի${issue.keys.length > 1 ? "ներ" : ""}. ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Սխալ բանալի ${withDefiniteArticle(issue.origin)}-ում`;
			case "invalid_union": return "Սխալ մուտքագրում";
			case "invalid_element": return `Սխալ արժեք ${withDefiniteArticle(issue.origin)}-ում`;
			default: return `Սխալ մուտքագրում`;
		}
	};
};
function hy_default() {
	return { localeError: error$30() };
}
//#endregion
//#region node_modules/zod/v4/locales/id.js
var error$29 = () => {
	const Sizable = {
		string: {
			unit: "karakter",
			verb: "memiliki"
		},
		file: {
			unit: "byte",
			verb: "memiliki"
		},
		array: {
			unit: "item",
			verb: "memiliki"
		},
		set: {
			unit: "item",
			verb: "memiliki"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "alamat email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "tanggal dan waktu format ISO",
		date: "tanggal format ISO",
		time: "jam format ISO",
		duration: "durasi format ISO",
		ipv4: "alamat IPv4",
		ipv6: "alamat IPv6",
		cidrv4: "rentang alamat IPv4",
		cidrv6: "rentang alamat IPv6",
		base64: "string dengan enkode base64",
		base64url: "string dengan enkode base64url",
		json_string: "string JSON",
		e164: "angka E.164",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Input tidak valid: diharapkan instanceof ${issue.expected}, diterima ${received}`;
				return `Input tidak valid: diharapkan ${expected}, diterima ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Input tidak valid: diharapkan ${stringifyPrimitive(issue.values[0])}`;
				return `Pilihan tidak valid: diharapkan salah satu dari ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Terlalu besar: diharapkan ${issue.origin ?? "value"} memiliki ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elemen"}`;
				return `Terlalu besar: diharapkan ${issue.origin ?? "value"} menjadi ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Terlalu kecil: diharapkan ${issue.origin} memiliki ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Terlalu kecil: diharapkan ${issue.origin} menjadi ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `String tidak valid: harus dimulai dengan "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `String tidak valid: harus berakhir dengan "${_issue.suffix}"`;
				if (_issue.format === "includes") return `String tidak valid: harus menyertakan "${_issue.includes}"`;
				if (_issue.format === "regex") return `String tidak valid: harus sesuai pola ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} tidak valid`;
			}
			case "not_multiple_of": return `Angka tidak valid: harus kelipatan dari ${issue.divisor}`;
			case "unrecognized_keys": return `Kunci tidak dikenali ${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Kunci tidak valid di ${issue.origin}`;
			case "invalid_union": return "Input tidak valid";
			case "invalid_element": return `Nilai tidak valid di ${issue.origin}`;
			default: return `Input tidak valid`;
		}
	};
};
function id_default() {
	return { localeError: error$29() };
}
//#endregion
//#region node_modules/zod/v4/locales/is.js
var error$28 = () => {
	const Sizable = {
		string: {
			unit: "stafi",
			verb: "að hafa"
		},
		file: {
			unit: "bæti",
			verb: "að hafa"
		},
		array: {
			unit: "hluti",
			verb: "að hafa"
		},
		set: {
			unit: "hluti",
			verb: "að hafa"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "gildi",
		email: "netfang",
		url: "vefslóð",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO dagsetning og tími",
		date: "ISO dagsetning",
		time: "ISO tími",
		duration: "ISO tímalengd",
		ipv4: "IPv4 address",
		ipv6: "IPv6 address",
		cidrv4: "IPv4 range",
		cidrv6: "IPv6 range",
		base64: "base64-encoded strengur",
		base64url: "base64url-encoded strengur",
		json_string: "JSON strengur",
		e164: "E.164 tölugildi",
		jwt: "JWT",
		template_literal: "gildi"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "númer",
		array: "fylki"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Rangt gildi: Þú slóst inn ${received} þar sem á að vera instanceof ${issue.expected}`;
				return `Rangt gildi: Þú slóst inn ${received} þar sem á að vera ${expected}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Rangt gildi: gert ráð fyrir ${stringifyPrimitive(issue.values[0])}`;
				return `Ógilt val: má vera eitt af eftirfarandi ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Of stórt: gert er ráð fyrir að ${issue.origin ?? "gildi"} hafi ${adj}${issue.maximum.toString()} ${sizing.unit ?? "hluti"}`;
				return `Of stórt: gert er ráð fyrir að ${issue.origin ?? "gildi"} sé ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Of lítið: gert er ráð fyrir að ${issue.origin} hafi ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Of lítið: gert er ráð fyrir að ${issue.origin} sé ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ógildur strengur: verður að byrja á "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Ógildur strengur: verður að enda á "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Ógildur strengur: verður að innihalda "${_issue.includes}"`;
				if (_issue.format === "regex") return `Ógildur strengur: verður að fylgja mynstri ${_issue.pattern}`;
				return `Rangt ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Röng tala: verður að vera margfeldi af ${issue.divisor}`;
			case "unrecognized_keys": return `Óþekkt ${issue.keys.length > 1 ? "ir lyklar" : "ur lykill"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Rangur lykill í ${issue.origin}`;
			case "invalid_union": return "Rangt gildi";
			case "invalid_element": return `Rangt gildi í ${issue.origin}`;
			default: return `Rangt gildi`;
		}
	};
};
function is_default() {
	return { localeError: error$28() };
}
//#endregion
//#region node_modules/zod/v4/locales/it.js
var error$27 = () => {
	const Sizable = {
		string: {
			unit: "caratteri",
			verb: "avere"
		},
		file: {
			unit: "byte",
			verb: "avere"
		},
		array: {
			unit: "elementi",
			verb: "avere"
		},
		set: {
			unit: "elementi",
			verb: "avere"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "indirizzo email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "data e ora ISO",
		date: "data ISO",
		time: "ora ISO",
		duration: "durata ISO",
		ipv4: "indirizzo IPv4",
		ipv6: "indirizzo IPv6",
		cidrv4: "intervallo IPv4",
		cidrv6: "intervallo IPv6",
		base64: "stringa codificata in base64",
		base64url: "URL codificata in base64",
		json_string: "stringa JSON",
		e164: "numero E.164",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "numero",
		array: "vettore"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Input non valido: atteso instanceof ${issue.expected}, ricevuto ${received}`;
				return `Input non valido: atteso ${expected}, ricevuto ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Input non valido: atteso ${stringifyPrimitive(issue.values[0])}`;
				return `Opzione non valida: atteso uno tra ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Troppo grande: ${issue.origin ?? "valore"} deve avere ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementi"}`;
				return `Troppo grande: ${issue.origin ?? "valore"} deve essere ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Troppo piccolo: ${issue.origin} deve avere ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Troppo piccolo: ${issue.origin} deve essere ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Stringa non valida: deve iniziare con "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Stringa non valida: deve terminare con "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Stringa non valida: deve includere "${_issue.includes}"`;
				if (_issue.format === "regex") return `Stringa non valida: deve corrispondere al pattern ${_issue.pattern}`;
				return `Input non valido: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Numero non valido: deve essere un multiplo di ${issue.divisor}`;
			case "unrecognized_keys": return `Chiav${issue.keys.length > 1 ? "i" : "e"} non riconosciut${issue.keys.length > 1 ? "e" : "a"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Chiave non valida in ${issue.origin}`;
			case "invalid_union": return "Input non valido";
			case "invalid_element": return `Valore non valido in ${issue.origin}`;
			default: return `Input non valido`;
		}
	};
};
function it_default() {
	return { localeError: error$27() };
}
//#endregion
//#region node_modules/zod/v4/locales/ja.js
var error$26 = () => {
	const Sizable = {
		string: {
			unit: "文字",
			verb: "である"
		},
		file: {
			unit: "バイト",
			verb: "である"
		},
		array: {
			unit: "要素",
			verb: "である"
		},
		set: {
			unit: "要素",
			verb: "である"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "入力値",
		email: "メールアドレス",
		url: "URL",
		emoji: "絵文字",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO日時",
		date: "ISO日付",
		time: "ISO時刻",
		duration: "ISO期間",
		ipv4: "IPv4アドレス",
		ipv6: "IPv6アドレス",
		cidrv4: "IPv4範囲",
		cidrv6: "IPv6範囲",
		base64: "base64エンコード文字列",
		base64url: "base64urlエンコード文字列",
		json_string: "JSON文字列",
		e164: "E.164番号",
		jwt: "JWT",
		template_literal: "入力値"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "数値",
		array: "配列"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `無効な入力: instanceof ${issue.expected}が期待されましたが、${received}が入力されました`;
				return `無効な入力: ${expected}が期待されましたが、${received}が入力されました`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `無効な入力: ${stringifyPrimitive(issue.values[0])}が期待されました`;
				return `無効な選択: ${joinValues(issue.values, "、")}のいずれかである必要があります`;
			case "too_big": {
				const adj = issue.inclusive ? "以下である" : "より小さい";
				const sizing = getSizing(issue.origin);
				if (sizing) return `大きすぎる値: ${issue.origin ?? "値"}は${issue.maximum.toString()}${sizing.unit ?? "要素"}${adj}必要があります`;
				return `大きすぎる値: ${issue.origin ?? "値"}は${issue.maximum.toString()}${adj}必要があります`;
			}
			case "too_small": {
				const adj = issue.inclusive ? "以上である" : "より大きい";
				const sizing = getSizing(issue.origin);
				if (sizing) return `小さすぎる値: ${issue.origin}は${issue.minimum.toString()}${sizing.unit}${adj}必要があります`;
				return `小さすぎる値: ${issue.origin}は${issue.minimum.toString()}${adj}必要があります`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `無効な文字列: "${_issue.prefix}"で始まる必要があります`;
				if (_issue.format === "ends_with") return `無効な文字列: "${_issue.suffix}"で終わる必要があります`;
				if (_issue.format === "includes") return `無効な文字列: "${_issue.includes}"を含む必要があります`;
				if (_issue.format === "regex") return `無効な文字列: パターン${_issue.pattern}に一致する必要があります`;
				return `無効な${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `無効な数値: ${issue.divisor}の倍数である必要があります`;
			case "unrecognized_keys": return `認識されていないキー${issue.keys.length > 1 ? "群" : ""}: ${joinValues(issue.keys, "、")}`;
			case "invalid_key": return `${issue.origin}内の無効なキー`;
			case "invalid_union": return "無効な入力";
			case "invalid_element": return `${issue.origin}内の無効な値`;
			default: return `無効な入力`;
		}
	};
};
function ja_default() {
	return { localeError: error$26() };
}
//#endregion
//#region node_modules/zod/v4/locales/ka.js
var error$25 = () => {
	const Sizable = {
		string: {
			unit: "სიმბოლო",
			verb: "უნდა შეიცავდეს"
		},
		file: {
			unit: "ბაიტი",
			verb: "უნდა შეიცავდეს"
		},
		array: {
			unit: "ელემენტი",
			verb: "უნდა შეიცავდეს"
		},
		set: {
			unit: "ელემენტი",
			verb: "უნდა შეიცავდეს"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "შეყვანა",
		email: "ელ-ფოსტის მისამართი",
		url: "URL",
		emoji: "ემოჯი",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "თარიღი-დრო",
		date: "თარიღი",
		time: "დრო",
		duration: "ხანგრძლივობა",
		ipv4: "IPv4 მისამართი",
		ipv6: "IPv6 მისამართი",
		cidrv4: "IPv4 დიაპაზონი",
		cidrv6: "IPv6 დიაპაზონი",
		base64: "base64-კოდირებული ველი",
		base64url: "base64url-კოდირებული ველი",
		json_string: "JSON ველი",
		e164: "E.164 ნომერი",
		jwt: "JWT",
		template_literal: "შეყვანა"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "რიცხვი",
		string: "ველი",
		boolean: "ბულეანი",
		function: "ფუნქცია",
		array: "მასივი"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `არასწორი შეყვანა: მოსალოდნელი instanceof ${issue.expected}, მიღებული ${received}`;
				return `არასწორი შეყვანა: მოსალოდნელი ${expected}, მიღებული ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `არასწორი შეყვანა: მოსალოდნელი ${stringifyPrimitive(issue.values[0])}`;
				return `არასწორი ვარიანტი: მოსალოდნელია ერთ-ერთი ${joinValues(issue.values, "|")}-დან`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `ზედმეტად დიდი: მოსალოდნელი ${issue.origin ?? "მნიშვნელობა"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit}`;
				return `ზედმეტად დიდი: მოსალოდნელი ${issue.origin ?? "მნიშვნელობა"} იყოს ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `ზედმეტად პატარა: მოსალოდნელი ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `ზედმეტად პატარა: მოსალოდნელი ${issue.origin} იყოს ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `არასწორი ველი: უნდა იწყებოდეს "${_issue.prefix}"-ით`;
				if (_issue.format === "ends_with") return `არასწორი ველი: უნდა მთავრდებოდეს "${_issue.suffix}"-ით`;
				if (_issue.format === "includes") return `არასწორი ველი: უნდა შეიცავდეს "${_issue.includes}"-ს`;
				if (_issue.format === "regex") return `არასწორი ველი: უნდა შეესაბამებოდეს შაბლონს ${_issue.pattern}`;
				return `არასწორი ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `არასწორი რიცხვი: უნდა იყოს ${issue.divisor}-ის ჯერადი`;
			case "unrecognized_keys": return `უცნობი გასაღებ${issue.keys.length > 1 ? "ები" : "ი"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `არასწორი გასაღები ${issue.origin}-ში`;
			case "invalid_union": return "არასწორი შეყვანა";
			case "invalid_element": return `არასწორი მნიშვნელობა ${issue.origin}-ში`;
			default: return `არასწორი შეყვანა`;
		}
	};
};
function ka_default() {
	return { localeError: error$25() };
}
//#endregion
//#region node_modules/zod/v4/locales/km.js
var error$24 = () => {
	const Sizable = {
		string: {
			unit: "តួអក្សរ",
			verb: "គួរមាន"
		},
		file: {
			unit: "បៃ",
			verb: "គួរមាន"
		},
		array: {
			unit: "ធាតុ",
			verb: "គួរមាន"
		},
		set: {
			unit: "ធាតុ",
			verb: "គួរមាន"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ទិន្នន័យបញ្ចូល",
		email: "អាសយដ្ឋានអ៊ីមែល",
		url: "URL",
		emoji: "សញ្ញាអារម្មណ៍",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "កាលបរិច្ឆេទ និងម៉ោង ISO",
		date: "កាលបរិច្ឆេទ ISO",
		time: "ម៉ោង ISO",
		duration: "រយៈពេល ISO",
		ipv4: "អាសយដ្ឋាន IPv4",
		ipv6: "អាសយដ្ឋាន IPv6",
		cidrv4: "ដែនអាសយដ្ឋាន IPv4",
		cidrv6: "ដែនអាសយដ្ឋាន IPv6",
		base64: "ខ្សែអក្សរអ៊ិកូដ base64",
		base64url: "ខ្សែអក្សរអ៊ិកូដ base64url",
		json_string: "ខ្សែអក្សរ JSON",
		e164: "លេខ E.164",
		jwt: "JWT",
		template_literal: "ទិន្នន័យបញ្ចូល"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "លេខ",
		array: "អារេ (Array)",
		null: "គ្មានតម្លៃ (null)"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `ទិន្នន័យបញ្ចូលមិនត្រឹមត្រូវ៖ ត្រូវការ instanceof ${issue.expected} ប៉ុន្តែទទួលបាន ${received}`;
				return `ទិន្នន័យបញ្ចូលមិនត្រឹមត្រូវ៖ ត្រូវការ ${expected} ប៉ុន្តែទទួលបាន ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `ទិន្នន័យបញ្ចូលមិនត្រឹមត្រូវ៖ ត្រូវការ ${stringifyPrimitive(issue.values[0])}`;
				return `ជម្រើសមិនត្រឹមត្រូវ៖ ត្រូវជាមួយក្នុងចំណោម ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `ធំពេក៖ ត្រូវការ ${issue.origin ?? "តម្លៃ"} ${adj} ${issue.maximum.toString()} ${sizing.unit ?? "ធាតុ"}`;
				return `ធំពេក៖ ត្រូវការ ${issue.origin ?? "តម្លៃ"} ${adj} ${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `តូចពេក៖ ត្រូវការ ${issue.origin} ${adj} ${issue.minimum.toString()} ${sizing.unit}`;
				return `តូចពេក៖ ត្រូវការ ${issue.origin} ${adj} ${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវចាប់ផ្តើមដោយ "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវបញ្ចប់ដោយ "${_issue.suffix}"`;
				if (_issue.format === "includes") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវមាន "${_issue.includes}"`;
				if (_issue.format === "regex") return `ខ្សែអក្សរមិនត្រឹមត្រូវ៖ ត្រូវតែផ្គូផ្គងនឹងទម្រង់ដែលបានកំណត់ ${_issue.pattern}`;
				return `មិនត្រឹមត្រូវ៖ ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `លេខមិនត្រឹមត្រូវ៖ ត្រូវតែជាពហុគុណនៃ ${issue.divisor}`;
			case "unrecognized_keys": return `រកឃើញសោមិនស្គាល់៖ ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `សោមិនត្រឹមត្រូវនៅក្នុង ${issue.origin}`;
			case "invalid_union": return `ទិន្នន័យមិនត្រឹមត្រូវ`;
			case "invalid_element": return `ទិន្នន័យមិនត្រឹមត្រូវនៅក្នុង ${issue.origin}`;
			default: return `ទិន្នន័យមិនត្រឹមត្រូវ`;
		}
	};
};
function km_default() {
	return { localeError: error$24() };
}
//#endregion
//#region node_modules/zod/v4/locales/kh.js
/** @deprecated Use `km` instead. */
function kh_default() {
	return km_default();
}
//#endregion
//#region node_modules/zod/v4/locales/ko.js
var error$23 = () => {
	const Sizable = {
		string: {
			unit: "문자",
			verb: "to have"
		},
		file: {
			unit: "바이트",
			verb: "to have"
		},
		array: {
			unit: "개",
			verb: "to have"
		},
		set: {
			unit: "개",
			verb: "to have"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "입력",
		email: "이메일 주소",
		url: "URL",
		emoji: "이모지",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO 날짜시간",
		date: "ISO 날짜",
		time: "ISO 시간",
		duration: "ISO 기간",
		ipv4: "IPv4 주소",
		ipv6: "IPv6 주소",
		cidrv4: "IPv4 범위",
		cidrv6: "IPv6 범위",
		base64: "base64 인코딩 문자열",
		base64url: "base64url 인코딩 문자열",
		json_string: "JSON 문자열",
		e164: "E.164 번호",
		jwt: "JWT",
		template_literal: "입력"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `잘못된 입력: 예상 타입은 instanceof ${issue.expected}, 받은 타입은 ${received}입니다`;
				return `잘못된 입력: 예상 타입은 ${expected}, 받은 타입은 ${received}입니다`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `잘못된 입력: 값은 ${stringifyPrimitive(issue.values[0])} 이어야 합니다`;
				return `잘못된 옵션: ${joinValues(issue.values, "또는 ")} 중 하나여야 합니다`;
			case "too_big": {
				const adj = issue.inclusive ? "이하" : "미만";
				const suffix = adj === "미만" ? "이어야 합니다" : "여야 합니다";
				const sizing = getSizing(issue.origin);
				const unit = sizing?.unit ?? "요소";
				if (sizing) return `${issue.origin ?? "값"}이 너무 큽니다: ${issue.maximum.toString()}${unit} ${adj}${suffix}`;
				return `${issue.origin ?? "값"}이 너무 큽니다: ${issue.maximum.toString()} ${adj}${suffix}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? "이상" : "초과";
				const suffix = adj === "이상" ? "이어야 합니다" : "여야 합니다";
				const sizing = getSizing(issue.origin);
				const unit = sizing?.unit ?? "요소";
				if (sizing) return `${issue.origin ?? "값"}이 너무 작습니다: ${issue.minimum.toString()}${unit} ${adj}${suffix}`;
				return `${issue.origin ?? "값"}이 너무 작습니다: ${issue.minimum.toString()} ${adj}${suffix}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `잘못된 문자열: "${_issue.prefix}"(으)로 시작해야 합니다`;
				if (_issue.format === "ends_with") return `잘못된 문자열: "${_issue.suffix}"(으)로 끝나야 합니다`;
				if (_issue.format === "includes") return `잘못된 문자열: "${_issue.includes}"을(를) 포함해야 합니다`;
				if (_issue.format === "regex") return `잘못된 문자열: 정규식 ${_issue.pattern} 패턴과 일치해야 합니다`;
				return `잘못된 ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `잘못된 숫자: ${issue.divisor}의 배수여야 합니다`;
			case "unrecognized_keys": return `인식할 수 없는 키: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `잘못된 키: ${issue.origin}`;
			case "invalid_union": return `잘못된 입력`;
			case "invalid_element": return `잘못된 값: ${issue.origin}`;
			default: return `잘못된 입력`;
		}
	};
};
function ko_default() {
	return { localeError: error$23() };
}
//#endregion
//#region node_modules/zod/v4/locales/lt.js
var capitalizeFirstCharacter = (text) => {
	return text.charAt(0).toUpperCase() + text.slice(1);
};
function getUnitTypeFromNumber(number) {
	const abs = Math.abs(number);
	const last = abs % 10;
	const last2 = abs % 100;
	if (last2 >= 11 && last2 <= 19 || last === 0) return "many";
	if (last === 1) return "one";
	return "few";
}
var error$22 = () => {
	const Sizable = {
		string: {
			unit: {
				one: "simbolis",
				few: "simboliai",
				many: "simbolių"
			},
			verb: {
				smaller: {
					inclusive: "turi būti ne ilgesnė kaip",
					notInclusive: "turi būti trumpesnė kaip"
				},
				bigger: {
					inclusive: "turi būti ne trumpesnė kaip",
					notInclusive: "turi būti ilgesnė kaip"
				}
			}
		},
		file: {
			unit: {
				one: "baitas",
				few: "baitai",
				many: "baitų"
			},
			verb: {
				smaller: {
					inclusive: "turi būti ne didesnis kaip",
					notInclusive: "turi būti mažesnis kaip"
				},
				bigger: {
					inclusive: "turi būti ne mažesnis kaip",
					notInclusive: "turi būti didesnis kaip"
				}
			}
		},
		array: {
			unit: {
				one: "elementą",
				few: "elementus",
				many: "elementų"
			},
			verb: {
				smaller: {
					inclusive: "turi turėti ne daugiau kaip",
					notInclusive: "turi turėti mažiau kaip"
				},
				bigger: {
					inclusive: "turi turėti ne mažiau kaip",
					notInclusive: "turi turėti daugiau kaip"
				}
			}
		},
		set: {
			unit: {
				one: "elementą",
				few: "elementus",
				many: "elementų"
			},
			verb: {
				smaller: {
					inclusive: "turi turėti ne daugiau kaip",
					notInclusive: "turi turėti mažiau kaip"
				},
				bigger: {
					inclusive: "turi turėti ne mažiau kaip",
					notInclusive: "turi turėti daugiau kaip"
				}
			}
		}
	};
	function getSizing(origin, unitType, inclusive, targetShouldBe) {
		const result = Sizable[origin] ?? null;
		if (result === null) return result;
		return {
			unit: result.unit[unitType],
			verb: result.verb[targetShouldBe][inclusive ? "inclusive" : "notInclusive"]
		};
	}
	const FormatDictionary = {
		regex: "įvestis",
		email: "el. pašto adresas",
		url: "URL",
		emoji: "jaustukas",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO data ir laikas",
		date: "ISO data",
		time: "ISO laikas",
		duration: "ISO trukmė",
		ipv4: "IPv4 adresas",
		ipv6: "IPv6 adresas",
		cidrv4: "IPv4 tinklo prefiksas (CIDR)",
		cidrv6: "IPv6 tinklo prefiksas (CIDR)",
		base64: "base64 užkoduota eilutė",
		base64url: "base64url užkoduota eilutė",
		json_string: "JSON eilutė",
		e164: "E.164 numeris",
		jwt: "JWT",
		template_literal: "įvestis"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "skaičius",
		bigint: "sveikasis skaičius",
		string: "eilutė",
		boolean: "loginė reikšmė",
		undefined: "neapibrėžta reikšmė",
		function: "funkcija",
		symbol: "simbolis",
		array: "masyvas",
		object: "objektas",
		null: "nulinė reikšmė"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Gautas tipas ${received}, o tikėtasi - instanceof ${issue.expected}`;
				return `Gautas tipas ${received}, o tikėtasi - ${expected}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Privalo būti ${stringifyPrimitive(issue.values[0])}`;
				return `Privalo būti vienas iš ${joinValues(issue.values, "|")} pasirinkimų`;
			case "too_big": {
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				const sizing = getSizing(issue.origin, getUnitTypeFromNumber(Number(issue.maximum)), issue.inclusive ?? false, "smaller");
				if (sizing?.verb) return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} ${sizing.verb} ${issue.maximum.toString()} ${sizing.unit ?? "elementų"}`;
				const adj = issue.inclusive ? "ne didesnis kaip" : "mažesnis kaip";
				return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} turi būti ${adj} ${issue.maximum.toString()} ${sizing?.unit}`;
			}
			case "too_small": {
				const origin = TypeDictionary[issue.origin] ?? issue.origin;
				const sizing = getSizing(issue.origin, getUnitTypeFromNumber(Number(issue.minimum)), issue.inclusive ?? false, "bigger");
				if (sizing?.verb) return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} ${sizing.verb} ${issue.minimum.toString()} ${sizing.unit ?? "elementų"}`;
				const adj = issue.inclusive ? "ne mažesnis kaip" : "didesnis kaip";
				return `${capitalizeFirstCharacter(origin ?? issue.origin ?? "reikšmė")} turi būti ${adj} ${issue.minimum.toString()} ${sizing?.unit}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Eilutė privalo prasidėti "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Eilutė privalo pasibaigti "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Eilutė privalo įtraukti "${_issue.includes}"`;
				if (_issue.format === "regex") return `Eilutė privalo atitikti ${_issue.pattern}`;
				return `Neteisingas ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Skaičius privalo būti ${issue.divisor} kartotinis.`;
			case "unrecognized_keys": return `Neatpažint${issue.keys.length > 1 ? "i" : "as"} rakt${issue.keys.length > 1 ? "ai" : "as"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return "Rastas klaidingas raktas";
			case "invalid_union": return "Klaidinga įvestis";
			case "invalid_element": return `${capitalizeFirstCharacter(TypeDictionary[issue.origin] ?? issue.origin ?? issue.origin ?? "reikšmė")} turi klaidingą įvestį`;
			default: return "Klaidinga įvestis";
		}
	};
};
function lt_default() {
	return { localeError: error$22() };
}
//#endregion
//#region node_modules/zod/v4/locales/mk.js
var error$21 = () => {
	const Sizable = {
		string: {
			unit: "знаци",
			verb: "да имаат"
		},
		file: {
			unit: "бајти",
			verb: "да имаат"
		},
		array: {
			unit: "ставки",
			verb: "да имаат"
		},
		set: {
			unit: "ставки",
			verb: "да имаат"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "внес",
		email: "адреса на е-пошта",
		url: "URL",
		emoji: "емоџи",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO датум и време",
		date: "ISO датум",
		time: "ISO време",
		duration: "ISO времетраење",
		ipv4: "IPv4 адреса",
		ipv6: "IPv6 адреса",
		cidrv4: "IPv4 опсег",
		cidrv6: "IPv6 опсег",
		base64: "base64-енкодирана низа",
		base64url: "base64url-енкодирана низа",
		json_string: "JSON низа",
		e164: "E.164 број",
		jwt: "JWT",
		template_literal: "внес"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "број",
		array: "низа"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Грешен внес: се очекува instanceof ${issue.expected}, примено ${received}`;
				return `Грешен внес: се очекува ${expected}, примено ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Invalid input: expected ${stringifyPrimitive(issue.values[0])}`;
				return `Грешана опција: се очекува една ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Премногу голем: се очекува ${issue.origin ?? "вредноста"} да има ${adj}${issue.maximum.toString()} ${sizing.unit ?? "елементи"}`;
				return `Премногу голем: се очекува ${issue.origin ?? "вредноста"} да биде ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Премногу мал: се очекува ${issue.origin} да има ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Премногу мал: се очекува ${issue.origin} да биде ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Неважечка низа: мора да започнува со "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Неважечка низа: мора да завршува со "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Неважечка низа: мора да вклучува "${_issue.includes}"`;
				if (_issue.format === "regex") return `Неважечка низа: мора да одгоара на патернот ${_issue.pattern}`;
				return `Invalid ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Грешен број: мора да биде делив со ${issue.divisor}`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Непрепознаени клучеви" : "Непрепознаен клуч"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Грешен клуч во ${issue.origin}`;
			case "invalid_union": return "Грешен внес";
			case "invalid_element": return `Грешна вредност во ${issue.origin}`;
			default: return `Грешен внес`;
		}
	};
};
function mk_default() {
	return { localeError: error$21() };
}
//#endregion
//#region node_modules/zod/v4/locales/ms.js
var error$20 = () => {
	const Sizable = {
		string: {
			unit: "aksara",
			verb: "mempunyai"
		},
		file: {
			unit: "bait",
			verb: "mempunyai"
		},
		array: {
			unit: "elemen",
			verb: "mempunyai"
		},
		set: {
			unit: "elemen",
			verb: "mempunyai"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "alamat e-mel",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "tarikh masa ISO",
		date: "tarikh ISO",
		time: "masa ISO",
		duration: "tempoh ISO",
		ipv4: "alamat IPv4",
		ipv6: "alamat IPv6",
		cidrv4: "julat IPv4",
		cidrv6: "julat IPv6",
		base64: "string dikodkan base64",
		base64url: "string dikodkan base64url",
		json_string: "string JSON",
		e164: "nombor E.164",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "nombor"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Input tidak sah: dijangka instanceof ${issue.expected}, diterima ${received}`;
				return `Input tidak sah: dijangka ${expected}, diterima ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Input tidak sah: dijangka ${stringifyPrimitive(issue.values[0])}`;
				return `Pilihan tidak sah: dijangka salah satu daripada ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Terlalu besar: dijangka ${issue.origin ?? "nilai"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elemen"}`;
				return `Terlalu besar: dijangka ${issue.origin ?? "nilai"} adalah ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Terlalu kecil: dijangka ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Terlalu kecil: dijangka ${issue.origin} adalah ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `String tidak sah: mesti bermula dengan "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `String tidak sah: mesti berakhir dengan "${_issue.suffix}"`;
				if (_issue.format === "includes") return `String tidak sah: mesti mengandungi "${_issue.includes}"`;
				if (_issue.format === "regex") return `String tidak sah: mesti sepadan dengan corak ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} tidak sah`;
			}
			case "not_multiple_of": return `Nombor tidak sah: perlu gandaan ${issue.divisor}`;
			case "unrecognized_keys": return `Kunci tidak dikenali: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Kunci tidak sah dalam ${issue.origin}`;
			case "invalid_union": return "Input tidak sah";
			case "invalid_element": return `Nilai tidak sah dalam ${issue.origin}`;
			default: return `Input tidak sah`;
		}
	};
};
function ms_default() {
	return { localeError: error$20() };
}
//#endregion
//#region node_modules/zod/v4/locales/nl.js
var error$19 = () => {
	const Sizable = {
		string: {
			unit: "tekens",
			verb: "heeft"
		},
		file: {
			unit: "bytes",
			verb: "heeft"
		},
		array: {
			unit: "elementen",
			verb: "heeft"
		},
		set: {
			unit: "elementen",
			verb: "heeft"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "invoer",
		email: "emailadres",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO datum en tijd",
		date: "ISO datum",
		time: "ISO tijd",
		duration: "ISO duur",
		ipv4: "IPv4-adres",
		ipv6: "IPv6-adres",
		cidrv4: "IPv4-bereik",
		cidrv6: "IPv6-bereik",
		base64: "base64-gecodeerde tekst",
		base64url: "base64 URL-gecodeerde tekst",
		json_string: "JSON string",
		e164: "E.164-nummer",
		jwt: "JWT",
		template_literal: "invoer"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "getal"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ongeldige invoer: verwacht instanceof ${issue.expected}, ontving ${received}`;
				return `Ongeldige invoer: verwacht ${expected}, ontving ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ongeldige invoer: verwacht ${stringifyPrimitive(issue.values[0])}`;
				return `Ongeldige optie: verwacht één van ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				const longName = issue.origin === "date" ? "laat" : issue.origin === "string" ? "lang" : "groot";
				if (sizing) return `Te ${longName}: verwacht dat ${issue.origin ?? "waarde"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementen"} ${sizing.verb}`;
				return `Te ${longName}: verwacht dat ${issue.origin ?? "waarde"} ${adj}${issue.maximum.toString()} is`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				const shortName = issue.origin === "date" ? "vroeg" : issue.origin === "string" ? "kort" : "klein";
				if (sizing) return `Te ${shortName}: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
				return `Te ${shortName}: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} is`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ongeldige tekst: moet met "${_issue.prefix}" beginnen`;
				if (_issue.format === "ends_with") return `Ongeldige tekst: moet op "${_issue.suffix}" eindigen`;
				if (_issue.format === "includes") return `Ongeldige tekst: moet "${_issue.includes}" bevatten`;
				if (_issue.format === "regex") return `Ongeldige tekst: moet overeenkomen met patroon ${_issue.pattern}`;
				return `Ongeldig: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Ongeldig getal: moet een veelvoud van ${issue.divisor} zijn`;
			case "unrecognized_keys": return `Onbekende key${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Ongeldige key in ${issue.origin}`;
			case "invalid_union": return "Ongeldige invoer";
			case "invalid_element": return `Ongeldige waarde in ${issue.origin}`;
			default: return `Ongeldige invoer`;
		}
	};
};
function nl_default() {
	return { localeError: error$19() };
}
//#endregion
//#region node_modules/zod/v4/locales/no.js
var error$18 = () => {
	const Sizable = {
		string: {
			unit: "tegn",
			verb: "å ha"
		},
		file: {
			unit: "bytes",
			verb: "å ha"
		},
		array: {
			unit: "elementer",
			verb: "å inneholde"
		},
		set: {
			unit: "elementer",
			verb: "å inneholde"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "input",
		email: "e-postadresse",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO dato- og klokkeslett",
		date: "ISO-dato",
		time: "ISO-klokkeslett",
		duration: "ISO-varighet",
		ipv4: "IPv4-område",
		ipv6: "IPv6-område",
		cidrv4: "IPv4-spekter",
		cidrv6: "IPv6-spekter",
		base64: "base64-enkodet streng",
		base64url: "base64url-enkodet streng",
		json_string: "JSON-streng",
		e164: "E.164-nummer",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "tall",
		array: "liste"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ugyldig input: forventet instanceof ${issue.expected}, fikk ${received}`;
				return `Ugyldig input: forventet ${expected}, fikk ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ugyldig verdi: forventet ${stringifyPrimitive(issue.values[0])}`;
				return `Ugyldig valg: forventet en av ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `For stor(t): forventet ${issue.origin ?? "value"} til å ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementer"}`;
				return `For stor(t): forventet ${issue.origin ?? "value"} til å ha ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `For lite(n): forventet ${issue.origin} til å ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `For lite(n): forventet ${issue.origin} til å ha ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ugyldig streng: må starte med "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Ugyldig streng: må ende med "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Ugyldig streng: må inneholde "${_issue.includes}"`;
				if (_issue.format === "regex") return `Ugyldig streng: må matche mønsteret ${_issue.pattern}`;
				return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Ugyldig tall: må være et multiplum av ${issue.divisor}`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Ukjente nøkler" : "Ukjent nøkkel"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Ugyldig nøkkel i ${issue.origin}`;
			case "invalid_union": return "Ugyldig input";
			case "invalid_element": return `Ugyldig verdi i ${issue.origin}`;
			default: return `Ugyldig input`;
		}
	};
};
function no_default() {
	return { localeError: error$18() };
}
//#endregion
//#region node_modules/zod/v4/locales/ota.js
var error$17 = () => {
	const Sizable = {
		string: {
			unit: "harf",
			verb: "olmalıdır"
		},
		file: {
			unit: "bayt",
			verb: "olmalıdır"
		},
		array: {
			unit: "unsur",
			verb: "olmalıdır"
		},
		set: {
			unit: "unsur",
			verb: "olmalıdır"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "giren",
		email: "epostagâh",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO hengâmı",
		date: "ISO tarihi",
		time: "ISO zamanı",
		duration: "ISO müddeti",
		ipv4: "IPv4 nişânı",
		ipv6: "IPv6 nişânı",
		cidrv4: "IPv4 menzili",
		cidrv6: "IPv6 menzili",
		base64: "base64-şifreli metin",
		base64url: "base64url-şifreli metin",
		json_string: "JSON metin",
		e164: "E.164 sayısı",
		jwt: "JWT",
		template_literal: "giren"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "numara",
		array: "saf",
		null: "gayb"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Fâsit giren: umulan instanceof ${issue.expected}, alınan ${received}`;
				return `Fâsit giren: umulan ${expected}, alınan ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Fâsit giren: umulan ${stringifyPrimitive(issue.values[0])}`;
				return `Fâsit tercih: mûteberler ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Fazla büyük: ${issue.origin ?? "value"}, ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elements"} sahip olmalıydı.`;
				return `Fazla büyük: ${issue.origin ?? "value"}, ${adj}${issue.maximum.toString()} olmalıydı.`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Fazla küçük: ${issue.origin}, ${adj}${issue.minimum.toString()} ${sizing.unit} sahip olmalıydı.`;
				return `Fazla küçük: ${issue.origin}, ${adj}${issue.minimum.toString()} olmalıydı.`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Fâsit metin: "${_issue.prefix}" ile başlamalı.`;
				if (_issue.format === "ends_with") return `Fâsit metin: "${_issue.suffix}" ile bitmeli.`;
				if (_issue.format === "includes") return `Fâsit metin: "${_issue.includes}" ihtivâ etmeli.`;
				if (_issue.format === "regex") return `Fâsit metin: ${_issue.pattern} nakşına uymalı.`;
				return `Fâsit ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Fâsit sayı: ${issue.divisor} katı olmalıydı.`;
			case "unrecognized_keys": return `Tanınmayan anahtar ${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} için tanınmayan anahtar var.`;
			case "invalid_union": return "Giren tanınamadı.";
			case "invalid_element": return `${issue.origin} için tanınmayan kıymet var.`;
			default: return `Kıymet tanınamadı.`;
		}
	};
};
function ota_default() {
	return { localeError: error$17() };
}
//#endregion
//#region node_modules/zod/v4/locales/ps.js
var error$16 = () => {
	const Sizable = {
		string: {
			unit: "توکي",
			verb: "ولري"
		},
		file: {
			unit: "بایټس",
			verb: "ولري"
		},
		array: {
			unit: "توکي",
			verb: "ولري"
		},
		set: {
			unit: "توکي",
			verb: "ولري"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ورودي",
		email: "بریښنالیک",
		url: "یو آر ال",
		emoji: "ایموجي",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "نیټه او وخت",
		date: "نېټه",
		time: "وخت",
		duration: "موده",
		ipv4: "د IPv4 پته",
		ipv6: "د IPv6 پته",
		cidrv4: "د IPv4 ساحه",
		cidrv6: "د IPv6 ساحه",
		base64: "base64-encoded متن",
		base64url: "base64url-encoded متن",
		json_string: "JSON متن",
		e164: "د E.164 شمېره",
		jwt: "JWT",
		template_literal: "ورودي"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "عدد",
		array: "ارې"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `ناسم ورودي: باید instanceof ${issue.expected} وای, مګر ${received} ترلاسه شو`;
				return `ناسم ورودي: باید ${expected} وای, مګر ${received} ترلاسه شو`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `ناسم ورودي: باید ${stringifyPrimitive(issue.values[0])} وای`;
				return `ناسم انتخاب: باید یو له ${joinValues(issue.values, "|")} څخه وای`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `ډیر لوی: ${issue.origin ?? "ارزښت"} باید ${adj}${issue.maximum.toString()} ${sizing.unit ?? "عنصرونه"} ولري`;
				return `ډیر لوی: ${issue.origin ?? "ارزښت"} باید ${adj}${issue.maximum.toString()} وي`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `ډیر کوچنی: ${issue.origin} باید ${adj}${issue.minimum.toString()} ${sizing.unit} ولري`;
				return `ډیر کوچنی: ${issue.origin} باید ${adj}${issue.minimum.toString()} وي`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `ناسم متن: باید د "${_issue.prefix}" سره پیل شي`;
				if (_issue.format === "ends_with") return `ناسم متن: باید د "${_issue.suffix}" سره پای ته ورسيږي`;
				if (_issue.format === "includes") return `ناسم متن: باید "${_issue.includes}" ولري`;
				if (_issue.format === "regex") return `ناسم متن: باید د ${_issue.pattern} سره مطابقت ولري`;
				return `${FormatDictionary[_issue.format] ?? issue.format} ناسم دی`;
			}
			case "not_multiple_of": return `ناسم عدد: باید د ${issue.divisor} مضرب وي`;
			case "unrecognized_keys": return `ناسم ${issue.keys.length > 1 ? "کلیډونه" : "کلیډ"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `ناسم کلیډ په ${issue.origin} کې`;
			case "invalid_union": return `ناسمه ورودي`;
			case "invalid_element": return `ناسم عنصر په ${issue.origin} کې`;
			default: return `ناسمه ورودي`;
		}
	};
};
function ps_default() {
	return { localeError: error$16() };
}
//#endregion
//#region node_modules/zod/v4/locales/pl.js
var error$15 = () => {
	const Sizable = {
		string: {
			unit: "znaków",
			verb: "mieć"
		},
		file: {
			unit: "bajtów",
			verb: "mieć"
		},
		array: {
			unit: "elementów",
			verb: "mieć"
		},
		set: {
			unit: "elementów",
			verb: "mieć"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "wyrażenie",
		email: "adres email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "data i godzina w formacie ISO",
		date: "data w formacie ISO",
		time: "godzina w formacie ISO",
		duration: "czas trwania ISO",
		ipv4: "adres IPv4",
		ipv6: "adres IPv6",
		cidrv4: "zakres IPv4",
		cidrv6: "zakres IPv6",
		base64: "ciąg znaków zakodowany w formacie base64",
		base64url: "ciąg znaków zakodowany w formacie base64url",
		json_string: "ciąg znaków w formacie JSON",
		e164: "liczba E.164",
		jwt: "JWT",
		template_literal: "wejście"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "liczba",
		array: "tablica"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Nieprawidłowe dane wejściowe: oczekiwano instanceof ${issue.expected}, otrzymano ${received}`;
				return `Nieprawidłowe dane wejściowe: oczekiwano ${expected}, otrzymano ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Nieprawidłowe dane wejściowe: oczekiwano ${stringifyPrimitive(issue.values[0])}`;
				return `Nieprawidłowa opcja: oczekiwano jednej z wartości ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Za duża wartość: oczekiwano, że ${issue.origin ?? "wartość"} będzie mieć ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementów"}`;
				return `Zbyt duż(y/a/e): oczekiwano, że ${issue.origin ?? "wartość"} będzie wynosić ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Za mała wartość: oczekiwano, że ${issue.origin ?? "wartość"} będzie mieć ${adj}${issue.minimum.toString()} ${sizing.unit ?? "elementów"}`;
				return `Zbyt mał(y/a/e): oczekiwano, że ${issue.origin ?? "wartość"} będzie wynosić ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Nieprawidłowy ciąg znaków: musi zaczynać się od "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Nieprawidłowy ciąg znaków: musi kończyć się na "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Nieprawidłowy ciąg znaków: musi zawierać "${_issue.includes}"`;
				if (_issue.format === "regex") return `Nieprawidłowy ciąg znaków: musi odpowiadać wzorcowi ${_issue.pattern}`;
				return `Nieprawidłow(y/a/e) ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Nieprawidłowa liczba: musi być wielokrotnością ${issue.divisor}`;
			case "unrecognized_keys": return `Nierozpoznane klucze${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Nieprawidłowy klucz w ${issue.origin}`;
			case "invalid_union": return "Nieprawidłowe dane wejściowe";
			case "invalid_element": return `Nieprawidłowa wartość w ${issue.origin}`;
			default: return `Nieprawidłowe dane wejściowe`;
		}
	};
};
function pl_default() {
	return { localeError: error$15() };
}
//#endregion
//#region node_modules/zod/v4/locales/pt.js
var error$14 = () => {
	const Sizable = {
		string: {
			unit: "caracteres",
			verb: "ter"
		},
		file: {
			unit: "bytes",
			verb: "ter"
		},
		array: {
			unit: "itens",
			verb: "ter"
		},
		set: {
			unit: "itens",
			verb: "ter"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "padrão",
		email: "endereço de e-mail",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "data e hora ISO",
		date: "data ISO",
		time: "hora ISO",
		duration: "duração ISO",
		ipv4: "endereço IPv4",
		ipv6: "endereço IPv6",
		cidrv4: "faixa de IPv4",
		cidrv6: "faixa de IPv6",
		base64: "texto codificado em base64",
		base64url: "URL codificada em base64",
		json_string: "texto JSON",
		e164: "número E.164",
		jwt: "JWT",
		template_literal: "entrada"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "número",
		null: "nulo"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Tipo inválido: esperado instanceof ${issue.expected}, recebido ${received}`;
				return `Tipo inválido: esperado ${expected}, recebido ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Entrada inválida: esperado ${stringifyPrimitive(issue.values[0])}`;
				return `Opção inválida: esperada uma das ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Muito grande: esperado que ${issue.origin ?? "valor"} tivesse ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementos"}`;
				return `Muito grande: esperado que ${issue.origin ?? "valor"} fosse ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Muito pequeno: esperado que ${issue.origin} tivesse ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Muito pequeno: esperado que ${issue.origin} fosse ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Texto inválido: deve começar com "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Texto inválido: deve terminar com "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Texto inválido: deve incluir "${_issue.includes}"`;
				if (_issue.format === "regex") return `Texto inválido: deve corresponder ao padrão ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} inválido`;
			}
			case "not_multiple_of": return `Número inválido: deve ser múltiplo de ${issue.divisor}`;
			case "unrecognized_keys": return `Chave${issue.keys.length > 1 ? "s" : ""} desconhecida${issue.keys.length > 1 ? "s" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Chave inválida em ${issue.origin}`;
			case "invalid_union": return "Entrada inválida";
			case "invalid_element": return `Valor inválido em ${issue.origin}`;
			default: return `Campo inválido`;
		}
	};
};
function pt_default() {
	return { localeError: error$14() };
}
//#endregion
//#region node_modules/zod/v4/locales/ro.js
var error$13 = () => {
	const Sizable = {
		string: {
			unit: "caractere",
			verb: "să aibă"
		},
		file: {
			unit: "octeți",
			verb: "să aibă"
		},
		array: {
			unit: "elemente",
			verb: "să aibă"
		},
		set: {
			unit: "elemente",
			verb: "să aibă"
		},
		map: {
			unit: "intrări",
			verb: "să aibă"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "intrare",
		email: "adresă de email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "dată și oră ISO",
		date: "dată ISO",
		time: "oră ISO",
		duration: "durată ISO",
		ipv4: "adresă IPv4",
		ipv6: "adresă IPv6",
		mac: "adresă MAC",
		cidrv4: "interval IPv4",
		cidrv6: "interval IPv6",
		base64: "șir codat base64",
		base64url: "șir codat base64url",
		json_string: "șir JSON",
		e164: "număr E.164",
		jwt: "JWT",
		template_literal: "intrare"
	};
	const TypeDictionary = {
		nan: "NaN",
		string: "șir",
		number: "număr",
		boolean: "boolean",
		function: "funcție",
		array: "matrice",
		object: "obiect",
		undefined: "nedefinit",
		symbol: "simbol",
		bigint: "număr mare",
		void: "void",
		never: "never",
		map: "hartă",
		set: "set"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				return `Intrare invalidă: așteptat ${expected}, primit ${TypeDictionary[receivedType] ?? receivedType}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Intrare invalidă: așteptat ${stringifyPrimitive(issue.values[0])}`;
				return `Opțiune invalidă: așteptat una dintre ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Prea mare: așteptat ca ${issue.origin ?? "valoarea"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elemente"}`;
				return `Prea mare: așteptat ca ${issue.origin ?? "valoarea"} să fie ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Prea mic: așteptat ca ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Prea mic: așteptat ca ${issue.origin} să fie ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Șir invalid: trebuie să înceapă cu "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Șir invalid: trebuie să se termine cu "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Șir invalid: trebuie să includă "${_issue.includes}"`;
				if (_issue.format === "regex") return `Șir invalid: trebuie să se potrivească cu modelul ${_issue.pattern}`;
				return `Format invalid: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Număr invalid: trebuie să fie multiplu de ${issue.divisor}`;
			case "unrecognized_keys": return `Chei nerecunoscute: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Cheie invalidă în ${issue.origin}`;
			case "invalid_union": return "Intrare invalidă";
			case "invalid_element": return `Valoare invalidă în ${issue.origin}`;
			default: return `Intrare invalidă`;
		}
	};
};
function ro_default() {
	return { localeError: error$13() };
}
//#endregion
//#region node_modules/zod/v4/locales/ru.js
function getRussianPlural(count, one, few, many) {
	const absCount = Math.abs(count);
	const lastDigit = absCount % 10;
	const lastTwoDigits = absCount % 100;
	if (lastTwoDigits >= 11 && lastTwoDigits <= 19) return many;
	if (lastDigit === 1) return one;
	if (lastDigit >= 2 && lastDigit <= 4) return few;
	return many;
}
var error$12 = () => {
	const Sizable = {
		string: {
			unit: {
				one: "символ",
				few: "символа",
				many: "символов"
			},
			verb: "иметь"
		},
		file: {
			unit: {
				one: "байт",
				few: "байта",
				many: "байт"
			},
			verb: "иметь"
		},
		array: {
			unit: {
				one: "элемент",
				few: "элемента",
				many: "элементов"
			},
			verb: "иметь"
		},
		set: {
			unit: {
				one: "элемент",
				few: "элемента",
				many: "элементов"
			},
			verb: "иметь"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ввод",
		email: "email адрес",
		url: "URL",
		emoji: "эмодзи",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO дата и время",
		date: "ISO дата",
		time: "ISO время",
		duration: "ISO длительность",
		ipv4: "IPv4 адрес",
		ipv6: "IPv6 адрес",
		cidrv4: "IPv4 диапазон",
		cidrv6: "IPv6 диапазон",
		base64: "строка в формате base64",
		base64url: "строка в формате base64url",
		json_string: "JSON строка",
		e164: "номер E.164",
		jwt: "JWT",
		template_literal: "ввод"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "число",
		array: "массив"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Неверный ввод: ожидалось instanceof ${issue.expected}, получено ${received}`;
				return `Неверный ввод: ожидалось ${expected}, получено ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Неверный ввод: ожидалось ${stringifyPrimitive(issue.values[0])}`;
				return `Неверный вариант: ожидалось одно из ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getRussianPlural(Number(issue.maximum), sizing.unit.one, sizing.unit.few, sizing.unit.many);
					return `Слишком большое значение: ожидалось, что ${issue.origin ?? "значение"} будет иметь ${adj}${issue.maximum.toString()} ${unit}`;
				}
				return `Слишком большое значение: ожидалось, что ${issue.origin ?? "значение"} будет ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) {
					const unit = getRussianPlural(Number(issue.minimum), sizing.unit.one, sizing.unit.few, sizing.unit.many);
					return `Слишком маленькое значение: ожидалось, что ${issue.origin} будет иметь ${adj}${issue.minimum.toString()} ${unit}`;
				}
				return `Слишком маленькое значение: ожидалось, что ${issue.origin} будет ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Неверная строка: должна начинаться с "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Неверная строка: должна заканчиваться на "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Неверная строка: должна содержать "${_issue.includes}"`;
				if (_issue.format === "regex") return `Неверная строка: должна соответствовать шаблону ${_issue.pattern}`;
				return `Неверный ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Неверное число: должно быть кратным ${issue.divisor}`;
			case "unrecognized_keys": return `Нераспознанн${issue.keys.length > 1 ? "ые" : "ый"} ключ${issue.keys.length > 1 ? "и" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Неверный ключ в ${issue.origin}`;
			case "invalid_union": return "Неверные входные данные";
			case "invalid_element": return `Неверное значение в ${issue.origin}`;
			default: return `Неверные входные данные`;
		}
	};
};
function ru_default() {
	return { localeError: error$12() };
}
//#endregion
//#region node_modules/zod/v4/locales/sl.js
var error$11 = () => {
	const Sizable = {
		string: {
			unit: "znakov",
			verb: "imeti"
		},
		file: {
			unit: "bajtov",
			verb: "imeti"
		},
		array: {
			unit: "elementov",
			verb: "imeti"
		},
		set: {
			unit: "elementov",
			verb: "imeti"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "vnos",
		email: "e-poštni naslov",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO datum in čas",
		date: "ISO datum",
		time: "ISO čas",
		duration: "ISO trajanje",
		ipv4: "IPv4 naslov",
		ipv6: "IPv6 naslov",
		cidrv4: "obseg IPv4",
		cidrv6: "obseg IPv6",
		base64: "base64 kodiran niz",
		base64url: "base64url kodiran niz",
		json_string: "JSON niz",
		e164: "E.164 številka",
		jwt: "JWT",
		template_literal: "vnos"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "število",
		array: "tabela"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Neveljaven vnos: pričakovano instanceof ${issue.expected}, prejeto ${received}`;
				return `Neveljaven vnos: pričakovano ${expected}, prejeto ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Neveljaven vnos: pričakovano ${stringifyPrimitive(issue.values[0])}`;
				return `Neveljavna možnost: pričakovano eno izmed ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Preveliko: pričakovano, da bo ${issue.origin ?? "vrednost"} imelo ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementov"}`;
				return `Preveliko: pričakovano, da bo ${issue.origin ?? "vrednost"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Premajhno: pričakovano, da bo ${issue.origin} imelo ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Premajhno: pričakovano, da bo ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Neveljaven niz: mora se začeti z "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Neveljaven niz: mora se končati z "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Neveljaven niz: mora vsebovati "${_issue.includes}"`;
				if (_issue.format === "regex") return `Neveljaven niz: mora ustrezati vzorcu ${_issue.pattern}`;
				return `Neveljaven ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Neveljavno število: mora biti večkratnik ${issue.divisor}`;
			case "unrecognized_keys": return `Neprepoznan${issue.keys.length > 1 ? "i ključi" : " ključ"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Neveljaven ključ v ${issue.origin}`;
			case "invalid_union": return "Neveljaven vnos";
			case "invalid_element": return `Neveljavna vrednost v ${issue.origin}`;
			default: return "Neveljaven vnos";
		}
	};
};
function sl_default() {
	return { localeError: error$11() };
}
//#endregion
//#region node_modules/zod/v4/locales/sv.js
var error$10 = () => {
	const Sizable = {
		string: {
			unit: "tecken",
			verb: "att ha"
		},
		file: {
			unit: "bytes",
			verb: "att ha"
		},
		array: {
			unit: "objekt",
			verb: "att innehålla"
		},
		set: {
			unit: "objekt",
			verb: "att innehålla"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "reguljärt uttryck",
		email: "e-postadress",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO-datum och tid",
		date: "ISO-datum",
		time: "ISO-tid",
		duration: "ISO-varaktighet",
		ipv4: "IPv4-intervall",
		ipv6: "IPv6-intervall",
		cidrv4: "IPv4-spektrum",
		cidrv6: "IPv6-spektrum",
		base64: "base64-kodad sträng",
		base64url: "base64url-kodad sträng",
		json_string: "JSON-sträng",
		e164: "E.164-nummer",
		jwt: "JWT",
		template_literal: "mall-literal"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "antal",
		array: "lista"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ogiltig inmatning: förväntat instanceof ${issue.expected}, fick ${received}`;
				return `Ogiltig inmatning: förväntat ${expected}, fick ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ogiltig inmatning: förväntat ${stringifyPrimitive(issue.values[0])}`;
				return `Ogiltigt val: förväntade en av ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `För stor(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? "element"}`;
				return `För stor(t): förväntat ${issue.origin ?? "värdet"} att ha ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `För lite(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `För lite(t): förväntade ${issue.origin ?? "värdet"} att ha ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ogiltig sträng: måste börja med "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Ogiltig sträng: måste sluta med "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Ogiltig sträng: måste innehålla "${_issue.includes}"`;
				if (_issue.format === "regex") return `Ogiltig sträng: måste matcha mönstret "${_issue.pattern}"`;
				return `Ogiltig(t) ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Ogiltigt tal: måste vara en multipel av ${issue.divisor}`;
			case "unrecognized_keys": return `${issue.keys.length > 1 ? "Okända nycklar" : "Okänd nyckel"}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Ogiltig nyckel i ${issue.origin ?? "värdet"}`;
			case "invalid_union": return "Ogiltig input";
			case "invalid_element": return `Ogiltigt värde i ${issue.origin ?? "värdet"}`;
			default: return `Ogiltig input`;
		}
	};
};
function sv_default() {
	return { localeError: error$10() };
}
//#endregion
//#region node_modules/zod/v4/locales/ta.js
var error$9 = () => {
	const Sizable = {
		string: {
			unit: "எழுத்துக்கள்",
			verb: "கொண்டிருக்க வேண்டும்"
		},
		file: {
			unit: "பைட்டுகள்",
			verb: "கொண்டிருக்க வேண்டும்"
		},
		array: {
			unit: "உறுப்புகள்",
			verb: "கொண்டிருக்க வேண்டும்"
		},
		set: {
			unit: "உறுப்புகள்",
			verb: "கொண்டிருக்க வேண்டும்"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "உள்ளீடு",
		email: "மின்னஞ்சல் முகவரி",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO தேதி நேரம்",
		date: "ISO தேதி",
		time: "ISO நேரம்",
		duration: "ISO கால அளவு",
		ipv4: "IPv4 முகவரி",
		ipv6: "IPv6 முகவரி",
		cidrv4: "IPv4 வரம்பு",
		cidrv6: "IPv6 வரம்பு",
		base64: "base64-encoded சரம்",
		base64url: "base64url-encoded சரம்",
		json_string: "JSON சரம்",
		e164: "E.164 எண்",
		jwt: "JWT",
		template_literal: "input"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "எண்",
		array: "அணி",
		null: "வெறுமை"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `தவறான உள்ளீடு: எதிர்பார்க்கப்பட்டது instanceof ${issue.expected}, பெறப்பட்டது ${received}`;
				return `தவறான உள்ளீடு: எதிர்பார்க்கப்பட்டது ${expected}, பெறப்பட்டது ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `தவறான உள்ளீடு: எதிர்பார்க்கப்பட்டது ${stringifyPrimitive(issue.values[0])}`;
				return `தவறான விருப்பம்: எதிர்பார்க்கப்பட்டது ${joinValues(issue.values, "|")} இல் ஒன்று`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `மிக பெரியது: எதிர்பார்க்கப்பட்டது ${issue.origin ?? "மதிப்பு"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "உறுப்புகள்"} ஆக இருக்க வேண்டும்`;
				return `மிக பெரியது: எதிர்பார்க்கப்பட்டது ${issue.origin ?? "மதிப்பு"} ${adj}${issue.maximum.toString()} ஆக இருக்க வேண்டும்`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `மிகச் சிறியது: எதிர்பார்க்கப்பட்டது ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ஆக இருக்க வேண்டும்`;
				return `மிகச் சிறியது: எதிர்பார்க்கப்பட்டது ${issue.origin} ${adj}${issue.minimum.toString()} ஆக இருக்க வேண்டும்`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `தவறான சரம்: "${_issue.prefix}" இல் தொடங்க வேண்டும்`;
				if (_issue.format === "ends_with") return `தவறான சரம்: "${_issue.suffix}" இல் முடிவடைய வேண்டும்`;
				if (_issue.format === "includes") return `தவறான சரம்: "${_issue.includes}" ஐ உள்ளடக்க வேண்டும்`;
				if (_issue.format === "regex") return `தவறான சரம்: ${_issue.pattern} முறைபாட்டுடன் பொருந்த வேண்டும்`;
				return `தவறான ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `தவறான எண்: ${issue.divisor} இன் பலமாக இருக்க வேண்டும்`;
			case "unrecognized_keys": return `அடையாளம் தெரியாத விசை${issue.keys.length > 1 ? "கள்" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} இல் தவறான விசை`;
			case "invalid_union": return "தவறான உள்ளீடு";
			case "invalid_element": return `${issue.origin} இல் தவறான மதிப்பு`;
			default: return `தவறான உள்ளீடு`;
		}
	};
};
function ta_default() {
	return { localeError: error$9() };
}
//#endregion
//#region node_modules/zod/v4/locales/th.js
var error$8 = () => {
	const Sizable = {
		string: {
			unit: "ตัวอักษร",
			verb: "ควรมี"
		},
		file: {
			unit: "ไบต์",
			verb: "ควรมี"
		},
		array: {
			unit: "รายการ",
			verb: "ควรมี"
		},
		set: {
			unit: "รายการ",
			verb: "ควรมี"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ข้อมูลที่ป้อน",
		email: "ที่อยู่อีเมล",
		url: "URL",
		emoji: "อิโมจิ",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "วันที่เวลาแบบ ISO",
		date: "วันที่แบบ ISO",
		time: "เวลาแบบ ISO",
		duration: "ช่วงเวลาแบบ ISO",
		ipv4: "ที่อยู่ IPv4",
		ipv6: "ที่อยู่ IPv6",
		cidrv4: "ช่วง IP แบบ IPv4",
		cidrv6: "ช่วง IP แบบ IPv6",
		base64: "ข้อความแบบ Base64",
		base64url: "ข้อความแบบ Base64 สำหรับ URL",
		json_string: "ข้อความแบบ JSON",
		e164: "เบอร์โทรศัพท์ระหว่างประเทศ (E.164)",
		jwt: "โทเคน JWT",
		template_literal: "ข้อมูลที่ป้อน"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "ตัวเลข",
		array: "อาร์เรย์ (Array)",
		null: "ไม่มีค่า (null)"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `ประเภทข้อมูลไม่ถูกต้อง: ควรเป็น instanceof ${issue.expected} แต่ได้รับ ${received}`;
				return `ประเภทข้อมูลไม่ถูกต้อง: ควรเป็น ${expected} แต่ได้รับ ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `ค่าไม่ถูกต้อง: ควรเป็น ${stringifyPrimitive(issue.values[0])}`;
				return `ตัวเลือกไม่ถูกต้อง: ควรเป็นหนึ่งใน ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "ไม่เกิน" : "น้อยกว่า";
				const sizing = getSizing(issue.origin);
				if (sizing) return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()} ${sizing.unit ?? "รายการ"}`;
				return `เกินกำหนด: ${issue.origin ?? "ค่า"} ควรมี${adj} ${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? "อย่างน้อย" : "มากกว่า";
				const sizing = getSizing(issue.origin);
				if (sizing) return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()} ${sizing.unit}`;
				return `น้อยกว่ากำหนด: ${issue.origin} ควรมี${adj} ${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `รูปแบบไม่ถูกต้อง: ข้อความต้องขึ้นต้นด้วย "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `รูปแบบไม่ถูกต้อง: ข้อความต้องลงท้ายด้วย "${_issue.suffix}"`;
				if (_issue.format === "includes") return `รูปแบบไม่ถูกต้อง: ข้อความต้องมี "${_issue.includes}" อยู่ในข้อความ`;
				if (_issue.format === "regex") return `รูปแบบไม่ถูกต้อง: ต้องตรงกับรูปแบบที่กำหนด ${_issue.pattern}`;
				return `รูปแบบไม่ถูกต้อง: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `ตัวเลขไม่ถูกต้อง: ต้องเป็นจำนวนที่หารด้วย ${issue.divisor} ได้ลงตัว`;
			case "unrecognized_keys": return `พบคีย์ที่ไม่รู้จัก: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `คีย์ไม่ถูกต้องใน ${issue.origin}`;
			case "invalid_union": return "ข้อมูลไม่ถูกต้อง: ไม่ตรงกับรูปแบบยูเนียนที่กำหนดไว้";
			case "invalid_element": return `ข้อมูลไม่ถูกต้องใน ${issue.origin}`;
			default: return `ข้อมูลไม่ถูกต้อง`;
		}
	};
};
function th_default() {
	return { localeError: error$8() };
}
//#endregion
//#region node_modules/zod/v4/locales/tr.js
var error$7 = () => {
	const Sizable = {
		string: {
			unit: "karakter",
			verb: "olmalı"
		},
		file: {
			unit: "bayt",
			verb: "olmalı"
		},
		array: {
			unit: "öğe",
			verb: "olmalı"
		},
		set: {
			unit: "öğe",
			verb: "olmalı"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "girdi",
		email: "e-posta adresi",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO tarih ve saat",
		date: "ISO tarih",
		time: "ISO saat",
		duration: "ISO süre",
		ipv4: "IPv4 adresi",
		ipv6: "IPv6 adresi",
		cidrv4: "IPv4 aralığı",
		cidrv6: "IPv6 aralığı",
		base64: "base64 ile şifrelenmiş metin",
		base64url: "base64url ile şifrelenmiş metin",
		json_string: "JSON dizesi",
		e164: "E.164 sayısı",
		jwt: "JWT",
		template_literal: "Şablon dizesi"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Geçersiz değer: beklenen instanceof ${issue.expected}, alınan ${received}`;
				return `Geçersiz değer: beklenen ${expected}, alınan ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Geçersiz değer: beklenen ${stringifyPrimitive(issue.values[0])}`;
				return `Geçersiz seçenek: aşağıdakilerden biri olmalı: ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Çok büyük: beklenen ${issue.origin ?? "değer"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "öğe"}`;
				return `Çok büyük: beklenen ${issue.origin ?? "değer"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Çok küçük: beklenen ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Çok küçük: beklenen ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Geçersiz metin: "${_issue.prefix}" ile başlamalı`;
				if (_issue.format === "ends_with") return `Geçersiz metin: "${_issue.suffix}" ile bitmeli`;
				if (_issue.format === "includes") return `Geçersiz metin: "${_issue.includes}" içermeli`;
				if (_issue.format === "regex") return `Geçersiz metin: ${_issue.pattern} desenine uymalı`;
				return `Geçersiz ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Geçersiz sayı: ${issue.divisor} ile tam bölünebilmeli`;
			case "unrecognized_keys": return `Tanınmayan anahtar${issue.keys.length > 1 ? "lar" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} içinde geçersiz anahtar`;
			case "invalid_union": return "Geçersiz değer";
			case "invalid_element": return `${issue.origin} içinde geçersiz değer`;
			default: return `Geçersiz değer`;
		}
	};
};
function tr_default() {
	return { localeError: error$7() };
}
//#endregion
//#region node_modules/zod/v4/locales/uk.js
var error$6 = () => {
	const Sizable = {
		string: {
			unit: "символів",
			verb: "матиме"
		},
		file: {
			unit: "байтів",
			verb: "матиме"
		},
		array: {
			unit: "елементів",
			verb: "матиме"
		},
		set: {
			unit: "елементів",
			verb: "матиме"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "вхідні дані",
		email: "адреса електронної пошти",
		url: "URL",
		emoji: "емодзі",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "дата та час ISO",
		date: "дата ISO",
		time: "час ISO",
		duration: "тривалість ISO",
		ipv4: "адреса IPv4",
		ipv6: "адреса IPv6",
		cidrv4: "діапазон IPv4",
		cidrv6: "діапазон IPv6",
		base64: "рядок у кодуванні base64",
		base64url: "рядок у кодуванні base64url",
		json_string: "рядок JSON",
		e164: "номер E.164",
		jwt: "JWT",
		template_literal: "вхідні дані"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "число",
		array: "масив"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Неправильні вхідні дані: очікується instanceof ${issue.expected}, отримано ${received}`;
				return `Неправильні вхідні дані: очікується ${expected}, отримано ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Неправильні вхідні дані: очікується ${stringifyPrimitive(issue.values[0])}`;
				return `Неправильна опція: очікується одне з ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Занадто велике: очікується, що ${issue.origin ?? "значення"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "елементів"}`;
				return `Занадто велике: очікується, що ${issue.origin ?? "значення"} буде ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Занадто мале: очікується, що ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Занадто мале: очікується, що ${issue.origin} буде ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Неправильний рядок: повинен починатися з "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Неправильний рядок: повинен закінчуватися на "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Неправильний рядок: повинен містити "${_issue.includes}"`;
				if (_issue.format === "regex") return `Неправильний рядок: повинен відповідати шаблону ${_issue.pattern}`;
				return `Неправильний ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Неправильне число: повинно бути кратним ${issue.divisor}`;
			case "unrecognized_keys": return `Нерозпізнаний ключ${issue.keys.length > 1 ? "і" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Неправильний ключ у ${issue.origin}`;
			case "invalid_union": return "Неправильні вхідні дані";
			case "invalid_element": return `Неправильне значення у ${issue.origin}`;
			default: return `Неправильні вхідні дані`;
		}
	};
};
function uk_default() {
	return { localeError: error$6() };
}
//#endregion
//#region node_modules/zod/v4/locales/ua.js
/** @deprecated Use `uk` instead. */
function ua_default() {
	return uk_default();
}
//#endregion
//#region node_modules/zod/v4/locales/ur.js
var error$5 = () => {
	const Sizable = {
		string: {
			unit: "حروف",
			verb: "ہونا"
		},
		file: {
			unit: "بائٹس",
			verb: "ہونا"
		},
		array: {
			unit: "آئٹمز",
			verb: "ہونا"
		},
		set: {
			unit: "آئٹمز",
			verb: "ہونا"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ان پٹ",
		email: "ای میل ایڈریس",
		url: "یو آر ایل",
		emoji: "ایموجی",
		uuid: "یو یو آئی ڈی",
		uuidv4: "یو یو آئی ڈی وی 4",
		uuidv6: "یو یو آئی ڈی وی 6",
		nanoid: "نینو آئی ڈی",
		guid: "جی یو آئی ڈی",
		cuid: "سی یو آئی ڈی",
		cuid2: "سی یو آئی ڈی 2",
		ulid: "یو ایل آئی ڈی",
		xid: "ایکس آئی ڈی",
		ksuid: "کے ایس یو آئی ڈی",
		datetime: "آئی ایس او ڈیٹ ٹائم",
		date: "آئی ایس او تاریخ",
		time: "آئی ایس او وقت",
		duration: "آئی ایس او مدت",
		ipv4: "آئی پی وی 4 ایڈریس",
		ipv6: "آئی پی وی 6 ایڈریس",
		cidrv4: "آئی پی وی 4 رینج",
		cidrv6: "آئی پی وی 6 رینج",
		base64: "بیس 64 ان کوڈڈ سٹرنگ",
		base64url: "بیس 64 یو آر ایل ان کوڈڈ سٹرنگ",
		json_string: "جے ایس او این سٹرنگ",
		e164: "ای 164 نمبر",
		jwt: "جے ڈبلیو ٹی",
		template_literal: "ان پٹ"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "نمبر",
		array: "آرے",
		null: "نل"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `غلط ان پٹ: instanceof ${issue.expected} متوقع تھا، ${received} موصول ہوا`;
				return `غلط ان پٹ: ${expected} متوقع تھا، ${received} موصول ہوا`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `غلط ان پٹ: ${stringifyPrimitive(issue.values[0])} متوقع تھا`;
				return `غلط آپشن: ${joinValues(issue.values, "|")} میں سے ایک متوقع تھا`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `بہت بڑا: ${issue.origin ?? "ویلیو"} کے ${adj}${issue.maximum.toString()} ${sizing.unit ?? "عناصر"} ہونے متوقع تھے`;
				return `بہت بڑا: ${issue.origin ?? "ویلیو"} کا ${adj}${issue.maximum.toString()} ہونا متوقع تھا`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `بہت چھوٹا: ${issue.origin} کے ${adj}${issue.minimum.toString()} ${sizing.unit} ہونے متوقع تھے`;
				return `بہت چھوٹا: ${issue.origin} کا ${adj}${issue.minimum.toString()} ہونا متوقع تھا`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `غلط سٹرنگ: "${_issue.prefix}" سے شروع ہونا چاہیے`;
				if (_issue.format === "ends_with") return `غلط سٹرنگ: "${_issue.suffix}" پر ختم ہونا چاہیے`;
				if (_issue.format === "includes") return `غلط سٹرنگ: "${_issue.includes}" شامل ہونا چاہیے`;
				if (_issue.format === "regex") return `غلط سٹرنگ: پیٹرن ${_issue.pattern} سے میچ ہونا چاہیے`;
				return `غلط ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `غلط نمبر: ${issue.divisor} کا مضاعف ہونا چاہیے`;
			case "unrecognized_keys": return `غیر تسلیم شدہ کی${issue.keys.length > 1 ? "ز" : ""}: ${joinValues(issue.keys, "، ")}`;
			case "invalid_key": return `${issue.origin} میں غلط کی`;
			case "invalid_union": return "غلط ان پٹ";
			case "invalid_element": return `${issue.origin} میں غلط ویلیو`;
			default: return `غلط ان پٹ`;
		}
	};
};
function ur_default() {
	return { localeError: error$5() };
}
//#endregion
//#region node_modules/zod/v4/locales/uz.js
var error$4 = () => {
	const Sizable = {
		string: {
			unit: "belgi",
			verb: "bo‘lishi kerak"
		},
		file: {
			unit: "bayt",
			verb: "bo‘lishi kerak"
		},
		array: {
			unit: "element",
			verb: "bo‘lishi kerak"
		},
		set: {
			unit: "element",
			verb: "bo‘lishi kerak"
		},
		map: {
			unit: "yozuv",
			verb: "bo‘lishi kerak"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "kirish",
		email: "elektron pochta manzili",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO sana va vaqti",
		date: "ISO sana",
		time: "ISO vaqt",
		duration: "ISO davomiylik",
		ipv4: "IPv4 manzil",
		ipv6: "IPv6 manzil",
		mac: "MAC manzil",
		cidrv4: "IPv4 diapazon",
		cidrv6: "IPv6 diapazon",
		base64: "base64 kodlangan satr",
		base64url: "base64url kodlangan satr",
		json_string: "JSON satr",
		e164: "E.164 raqam",
		jwt: "JWT",
		template_literal: "kirish"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "raqam",
		array: "massiv"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Noto‘g‘ri kirish: kutilgan instanceof ${issue.expected}, qabul qilingan ${received}`;
				return `Noto‘g‘ri kirish: kutilgan ${expected}, qabul qilingan ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Noto‘g‘ri kirish: kutilgan ${stringifyPrimitive(issue.values[0])}`;
				return `Noto‘g‘ri variant: quyidagilardan biri kutilgan ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Juda katta: kutilgan ${issue.origin ?? "qiymat"} ${adj}${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;
				return `Juda katta: kutilgan ${issue.origin ?? "qiymat"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
				return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Noto‘g‘ri satr: "${_issue.prefix}" bilan boshlanishi kerak`;
				if (_issue.format === "ends_with") return `Noto‘g‘ri satr: "${_issue.suffix}" bilan tugashi kerak`;
				if (_issue.format === "includes") return `Noto‘g‘ri satr: "${_issue.includes}" ni o‘z ichiga olishi kerak`;
				if (_issue.format === "regex") return `Noto‘g‘ri satr: ${_issue.pattern} shabloniga mos kelishi kerak`;
				return `Noto‘g‘ri ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Noto‘g‘ri raqam: ${issue.divisor} ning karralisi bo‘lishi kerak`;
			case "unrecognized_keys": return `Noma’lum kalit${issue.keys.length > 1 ? "lar" : ""}: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} dagi kalit noto‘g‘ri`;
			case "invalid_union": return "Noto‘g‘ri kirish";
			case "invalid_element": return `${issue.origin} da noto‘g‘ri qiymat`;
			default: return `Noto‘g‘ri kirish`;
		}
	};
};
function uz_default() {
	return { localeError: error$4() };
}
//#endregion
//#region node_modules/zod/v4/locales/vi.js
var error$3 = () => {
	const Sizable = {
		string: {
			unit: "ký tự",
			verb: "có"
		},
		file: {
			unit: "byte",
			verb: "có"
		},
		array: {
			unit: "phần tử",
			verb: "có"
		},
		set: {
			unit: "phần tử",
			verb: "có"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "đầu vào",
		email: "địa chỉ email",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ngày giờ ISO",
		date: "ngày ISO",
		time: "giờ ISO",
		duration: "khoảng thời gian ISO",
		ipv4: "địa chỉ IPv4",
		ipv6: "địa chỉ IPv6",
		cidrv4: "dải IPv4",
		cidrv6: "dải IPv6",
		base64: "chuỗi mã hóa base64",
		base64url: "chuỗi mã hóa base64url",
		json_string: "chuỗi JSON",
		e164: "số E.164",
		jwt: "JWT",
		template_literal: "đầu vào"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "số",
		array: "mảng"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Đầu vào không hợp lệ: mong đợi instanceof ${issue.expected}, nhận được ${received}`;
				return `Đầu vào không hợp lệ: mong đợi ${expected}, nhận được ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Đầu vào không hợp lệ: mong đợi ${stringifyPrimitive(issue.values[0])}`;
				return `Tùy chọn không hợp lệ: mong đợi một trong các giá trị ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Quá lớn: mong đợi ${issue.origin ?? "giá trị"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "phần tử"}`;
				return `Quá lớn: mong đợi ${issue.origin ?? "giá trị"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Quá nhỏ: mong đợi ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `Quá nhỏ: mong đợi ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Chuỗi không hợp lệ: phải bắt đầu bằng "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Chuỗi không hợp lệ: phải kết thúc bằng "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Chuỗi không hợp lệ: phải bao gồm "${_issue.includes}"`;
				if (_issue.format === "regex") return `Chuỗi không hợp lệ: phải khớp với mẫu ${_issue.pattern}`;
				return `${FormatDictionary[_issue.format] ?? issue.format} không hợp lệ`;
			}
			case "not_multiple_of": return `Số không hợp lệ: phải là bội số của ${issue.divisor}`;
			case "unrecognized_keys": return `Khóa không được nhận dạng: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Khóa không hợp lệ trong ${issue.origin}`;
			case "invalid_union": return "Đầu vào không hợp lệ";
			case "invalid_element": return `Giá trị không hợp lệ trong ${issue.origin}`;
			default: return `Đầu vào không hợp lệ`;
		}
	};
};
function vi_default() {
	return { localeError: error$3() };
}
//#endregion
//#region node_modules/zod/v4/locales/zh-CN.js
var error$2 = () => {
	const Sizable = {
		string: {
			unit: "字符",
			verb: "包含"
		},
		file: {
			unit: "字节",
			verb: "包含"
		},
		array: {
			unit: "项",
			verb: "包含"
		},
		set: {
			unit: "项",
			verb: "包含"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "输入",
		email: "电子邮件",
		url: "URL",
		emoji: "表情符号",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO日期时间",
		date: "ISO日期",
		time: "ISO时间",
		duration: "ISO时长",
		ipv4: "IPv4地址",
		ipv6: "IPv6地址",
		cidrv4: "IPv4网段",
		cidrv6: "IPv6网段",
		base64: "base64编码字符串",
		base64url: "base64url编码字符串",
		json_string: "JSON字符串",
		e164: "E.164号码",
		jwt: "JWT",
		template_literal: "输入"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "数字",
		array: "数组",
		null: "空值(null)"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `无效输入：期望 instanceof ${issue.expected}，实际接收 ${received}`;
				return `无效输入：期望 ${expected}，实际接收 ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `无效输入：期望 ${stringifyPrimitive(issue.values[0])}`;
				return `无效选项：期望以下之一 ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `数值过大：期望 ${issue.origin ?? "值"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "个元素"}`;
				return `数值过大：期望 ${issue.origin ?? "值"} ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `数值过小：期望 ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `数值过小：期望 ${issue.origin} ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `无效字符串：必须以 "${_issue.prefix}" 开头`;
				if (_issue.format === "ends_with") return `无效字符串：必须以 "${_issue.suffix}" 结尾`;
				if (_issue.format === "includes") return `无效字符串：必须包含 "${_issue.includes}"`;
				if (_issue.format === "regex") return `无效字符串：必须满足正则表达式 ${_issue.pattern}`;
				return `无效${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `无效数字：必须是 ${issue.divisor} 的倍数`;
			case "unrecognized_keys": return `出现未知的键(key): ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `${issue.origin} 中的键(key)无效`;
			case "invalid_union": return "无效输入";
			case "invalid_element": return `${issue.origin} 中包含无效值(value)`;
			default: return `无效输入`;
		}
	};
};
function zh_CN_default$1() {
	return { localeError: error$2() };
}
//#endregion
//#region node_modules/zod/v4/locales/zh-TW.js
var error$1 = () => {
	const Sizable = {
		string: {
			unit: "字元",
			verb: "擁有"
		},
		file: {
			unit: "位元組",
			verb: "擁有"
		},
		array: {
			unit: "項目",
			verb: "擁有"
		},
		set: {
			unit: "項目",
			verb: "擁有"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "輸入",
		email: "郵件地址",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "ISO 日期時間",
		date: "ISO 日期",
		time: "ISO 時間",
		duration: "ISO 期間",
		ipv4: "IPv4 位址",
		ipv6: "IPv6 位址",
		cidrv4: "IPv4 範圍",
		cidrv6: "IPv6 範圍",
		base64: "base64 編碼字串",
		base64url: "base64url 編碼字串",
		json_string: "JSON 字串",
		e164: "E.164 數值",
		jwt: "JWT",
		template_literal: "輸入"
	};
	const TypeDictionary = { nan: "NaN" };
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `無效的輸入值：預期為 instanceof ${issue.expected}，但收到 ${received}`;
				return `無效的輸入值：預期為 ${expected}，但收到 ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `無效的輸入值：預期為 ${stringifyPrimitive(issue.values[0])}`;
				return `無效的選項：預期為以下其中之一 ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `數值過大：預期 ${issue.origin ?? "值"} 應為 ${adj}${issue.maximum.toString()} ${sizing.unit ?? "個元素"}`;
				return `數值過大：預期 ${issue.origin ?? "值"} 應為 ${adj}${issue.maximum.toString()}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `數值過小：預期 ${issue.origin} 應為 ${adj}${issue.minimum.toString()} ${sizing.unit}`;
				return `數值過小：預期 ${issue.origin} 應為 ${adj}${issue.minimum.toString()}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `無效的字串：必須以 "${_issue.prefix}" 開頭`;
				if (_issue.format === "ends_with") return `無效的字串：必須以 "${_issue.suffix}" 結尾`;
				if (_issue.format === "includes") return `無效的字串：必須包含 "${_issue.includes}"`;
				if (_issue.format === "regex") return `無效的字串：必須符合格式 ${_issue.pattern}`;
				return `無效的 ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `無效的數字：必須為 ${issue.divisor} 的倍數`;
			case "unrecognized_keys": return `無法識別的鍵值${issue.keys.length > 1 ? "們" : ""}：${joinValues(issue.keys, "、")}`;
			case "invalid_key": return `${issue.origin} 中有無效的鍵值`;
			case "invalid_union": return "無效的輸入值";
			case "invalid_element": return `${issue.origin} 中有無效的值`;
			default: return `無效的輸入值`;
		}
	};
};
function zh_TW_default() {
	return { localeError: error$1() };
}
//#endregion
//#region node_modules/zod/v4/locales/yo.js
var error = () => {
	const Sizable = {
		string: {
			unit: "àmi",
			verb: "ní"
		},
		file: {
			unit: "bytes",
			verb: "ní"
		},
		array: {
			unit: "nkan",
			verb: "ní"
		},
		set: {
			unit: "nkan",
			verb: "ní"
		}
	};
	function getSizing(origin) {
		return Sizable[origin] ?? null;
	}
	const FormatDictionary = {
		regex: "ẹ̀rọ ìbáwọlé",
		email: "àdírẹ́sì ìmẹ́lì",
		url: "URL",
		emoji: "emoji",
		uuid: "UUID",
		uuidv4: "UUIDv4",
		uuidv6: "UUIDv6",
		nanoid: "nanoid",
		guid: "GUID",
		cuid: "cuid",
		cuid2: "cuid2",
		ulid: "ULID",
		xid: "XID",
		ksuid: "KSUID",
		datetime: "àkókò ISO",
		date: "ọjọ́ ISO",
		time: "àkókò ISO",
		duration: "àkókò tó pé ISO",
		ipv4: "àdírẹ́sì IPv4",
		ipv6: "àdírẹ́sì IPv6",
		cidrv4: "àgbègbè IPv4",
		cidrv6: "àgbègbè IPv6",
		base64: "ọ̀rọ̀ tí a kọ́ ní base64",
		base64url: "ọ̀rọ̀ base64url",
		json_string: "ọ̀rọ̀ JSON",
		e164: "nọ́mbà E.164",
		jwt: "JWT",
		template_literal: "ẹ̀rọ ìbáwọlé"
	};
	const TypeDictionary = {
		nan: "NaN",
		number: "nọ́mbà",
		array: "akopọ"
	};
	return (issue) => {
		switch (issue.code) {
			case "invalid_type": {
				const expected = TypeDictionary[issue.expected] ?? issue.expected;
				const receivedType = parsedType(issue.input);
				const received = TypeDictionary[receivedType] ?? receivedType;
				if (/^[A-Z]/.test(issue.expected)) return `Ìbáwọlé aṣìṣe: a ní láti fi instanceof ${issue.expected}, àmọ̀ a rí ${received}`;
				return `Ìbáwọlé aṣìṣe: a ní láti fi ${expected}, àmọ̀ a rí ${received}`;
			}
			case "invalid_value":
				if (issue.values.length === 1) return `Ìbáwọlé aṣìṣe: a ní láti fi ${stringifyPrimitive(issue.values[0])}`;
				return `Àṣàyàn aṣìṣe: yan ọ̀kan lára ${joinValues(issue.values, "|")}`;
			case "too_big": {
				const adj = issue.inclusive ? "<=" : "<";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Tó pọ̀ jù: a ní láti jẹ́ pé ${issue.origin ?? "iye"} ${sizing.verb} ${adj}${issue.maximum} ${sizing.unit}`;
				return `Tó pọ̀ jù: a ní láti jẹ́ ${adj}${issue.maximum}`;
			}
			case "too_small": {
				const adj = issue.inclusive ? ">=" : ">";
				const sizing = getSizing(issue.origin);
				if (sizing) return `Kéré ju: a ní láti jẹ́ pé ${issue.origin} ${sizing.verb} ${adj}${issue.minimum} ${sizing.unit}`;
				return `Kéré ju: a ní láti jẹ́ ${adj}${issue.minimum}`;
			}
			case "invalid_format": {
				const _issue = issue;
				if (_issue.format === "starts_with") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bẹ̀rẹ̀ pẹ̀lú "${_issue.prefix}"`;
				if (_issue.format === "ends_with") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ parí pẹ̀lú "${_issue.suffix}"`;
				if (_issue.format === "includes") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ ní "${_issue.includes}"`;
				if (_issue.format === "regex") return `Ọ̀rọ̀ aṣìṣe: gbọ́dọ̀ bá àpẹẹrẹ mu ${_issue.pattern}`;
				return `Aṣìṣe: ${FormatDictionary[_issue.format] ?? issue.format}`;
			}
			case "not_multiple_of": return `Nọ́mbà aṣìṣe: gbọ́dọ̀ jẹ́ èyà pípín ti ${issue.divisor}`;
			case "unrecognized_keys": return `Bọtìnì àìmọ̀: ${joinValues(issue.keys, ", ")}`;
			case "invalid_key": return `Bọtìnì aṣìṣe nínú ${issue.origin}`;
			case "invalid_union": return "Ìbáwọlé aṣìṣe";
			case "invalid_element": return `Iye aṣìṣe nínú ${issue.origin}`;
			default: return "Ìbáwọlé aṣìṣe";
		}
	};
};
function yo_default() {
	return { localeError: error() };
}
//#endregion
//#region node_modules/zod/v4/locales/index.js
var locales_exports = /* @__PURE__ */ __exportAll({
	ar: () => ar_default,
	az: () => az_default,
	be: () => be_default,
	bg: () => bg_default,
	ca: () => ca_default,
	cs: () => cs_default,
	da: () => da_default,
	de: () => de_default,
	el: () => el_default,
	en: () => en_default,
	eo: () => eo_default,
	es: () => es_default,
	fa: () => fa_default,
	fi: () => fi_default,
	fr: () => fr_default,
	frCA: () => fr_CA_default,
	he: () => he_default,
	hr: () => hr_default,
	hu: () => hu_default,
	hy: () => hy_default,
	id: () => id_default,
	is: () => is_default,
	it: () => it_default,
	ja: () => ja_default,
	ka: () => ka_default,
	kh: () => kh_default,
	km: () => km_default,
	ko: () => ko_default,
	lt: () => lt_default,
	mk: () => mk_default,
	ms: () => ms_default,
	nl: () => nl_default,
	no: () => no_default,
	ota: () => ota_default,
	pl: () => pl_default,
	ps: () => ps_default,
	pt: () => pt_default,
	ro: () => ro_default,
	ru: () => ru_default,
	sl: () => sl_default,
	sv: () => sv_default,
	ta: () => ta_default,
	th: () => th_default,
	tr: () => tr_default,
	ua: () => ua_default,
	uk: () => uk_default,
	ur: () => ur_default,
	uz: () => uz_default,
	vi: () => vi_default,
	yo: () => yo_default,
	zhCN: () => zh_CN_default$1,
	zhTW: () => zh_TW_default
});
//#endregion
//#region node_modules/zod/v4/core/registries.js
var _a;
var $output = Symbol("ZodOutput");
var $input = Symbol("ZodInput");
var $ZodRegistry = class {
	constructor() {
		this._map = /* @__PURE__ */ new WeakMap();
		this._idmap = /* @__PURE__ */ new Map();
	}
	add(schema, ..._meta) {
		const meta = _meta[0];
		this._map.set(schema, meta);
		if (meta && typeof meta === "object" && "id" in meta) this._idmap.set(meta.id, schema);
		return this;
	}
	clear() {
		this._map = /* @__PURE__ */ new WeakMap();
		this._idmap = /* @__PURE__ */ new Map();
		return this;
	}
	remove(schema) {
		const meta = this._map.get(schema);
		if (meta && typeof meta === "object" && "id" in meta) this._idmap.delete(meta.id);
		this._map.delete(schema);
		return this;
	}
	get(schema) {
		const p = schema._zod.parent;
		if (p) {
			const pm = { ...this.get(p) ?? {} };
			delete pm.id;
			const f = {
				...pm,
				...this._map.get(schema)
			};
			return Object.keys(f).length ? f : void 0;
		}
		return this._map.get(schema);
	}
	has(schema) {
		return this._map.has(schema);
	}
};
function registry() {
	return new $ZodRegistry();
}
(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
var globalRegistry = globalThis.__zod_globalRegistry;
//#endregion
//#region node_modules/zod/v4/core/api.js
// @__NO_SIDE_EFFECTS__
function _string(Class, params) {
	return new Class({
		type: "string",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _coercedString(Class, params) {
	return new Class({
		type: "string",
		coerce: true,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _email(Class, params) {
	return new Class({
		type: "string",
		format: "email",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _guid(Class, params) {
	return new Class({
		type: "string",
		format: "guid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uuid(Class, params) {
	return new Class({
		type: "string",
		format: "uuid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uuidv4(Class, params) {
	return new Class({
		type: "string",
		format: "uuid",
		check: "string_format",
		abort: false,
		version: "v4",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uuidv6(Class, params) {
	return new Class({
		type: "string",
		format: "uuid",
		check: "string_format",
		abort: false,
		version: "v6",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uuidv7(Class, params) {
	return new Class({
		type: "string",
		format: "uuid",
		check: "string_format",
		abort: false,
		version: "v7",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _url(Class, params) {
	return new Class({
		type: "string",
		format: "url",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _emoji(Class, params) {
	return new Class({
		type: "string",
		format: "emoji",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _nanoid(Class, params) {
	return new Class({
		type: "string",
		format: "nanoid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
/**
* @deprecated CUID v1 is deprecated by its authors due to information leakage
* (timestamps embedded in the id). Use {@link _cuid2} instead.
* See https://github.com/paralleldrive/cuid.
*/
// @__NO_SIDE_EFFECTS__
function _cuid(Class, params) {
	return new Class({
		type: "string",
		format: "cuid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _cuid2(Class, params) {
	return new Class({
		type: "string",
		format: "cuid2",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _ulid(Class, params) {
	return new Class({
		type: "string",
		format: "ulid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _xid(Class, params) {
	return new Class({
		type: "string",
		format: "xid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _ksuid(Class, params) {
	return new Class({
		type: "string",
		format: "ksuid",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _ipv4(Class, params) {
	return new Class({
		type: "string",
		format: "ipv4",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _ipv6(Class, params) {
	return new Class({
		type: "string",
		format: "ipv6",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _mac(Class, params) {
	return new Class({
		type: "string",
		format: "mac",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _cidrv4(Class, params) {
	return new Class({
		type: "string",
		format: "cidrv4",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _cidrv6(Class, params) {
	return new Class({
		type: "string",
		format: "cidrv6",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _base64(Class, params) {
	return new Class({
		type: "string",
		format: "base64",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _base64url(Class, params) {
	return new Class({
		type: "string",
		format: "base64url",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _e164(Class, params) {
	return new Class({
		type: "string",
		format: "e164",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _jwt(Class, params) {
	return new Class({
		type: "string",
		format: "jwt",
		check: "string_format",
		abort: false,
		...normalizeParams(params)
	});
}
var TimePrecision = {
	Any: null,
	Minute: -1,
	Second: 0,
	Millisecond: 3,
	Microsecond: 6
};
// @__NO_SIDE_EFFECTS__
function _isoDateTime(Class, params) {
	return new Class({
		type: "string",
		format: "datetime",
		check: "string_format",
		offset: false,
		local: false,
		precision: null,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _isoDate(Class, params) {
	return new Class({
		type: "string",
		format: "date",
		check: "string_format",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _isoTime(Class, params) {
	return new Class({
		type: "string",
		format: "time",
		check: "string_format",
		precision: null,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _isoDuration(Class, params) {
	return new Class({
		type: "string",
		format: "duration",
		check: "string_format",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _number(Class, params) {
	return new Class({
		type: "number",
		checks: [],
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _coercedNumber(Class, params) {
	return new Class({
		type: "number",
		coerce: true,
		checks: [],
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _int(Class, params) {
	return new Class({
		type: "number",
		check: "number_format",
		abort: false,
		format: "safeint",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _float32(Class, params) {
	return new Class({
		type: "number",
		check: "number_format",
		abort: false,
		format: "float32",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _float64(Class, params) {
	return new Class({
		type: "number",
		check: "number_format",
		abort: false,
		format: "float64",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _int32(Class, params) {
	return new Class({
		type: "number",
		check: "number_format",
		abort: false,
		format: "int32",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uint32(Class, params) {
	return new Class({
		type: "number",
		check: "number_format",
		abort: false,
		format: "uint32",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _boolean(Class, params) {
	return new Class({
		type: "boolean",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _coercedBoolean(Class, params) {
	return new Class({
		type: "boolean",
		coerce: true,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _bigint(Class, params) {
	return new Class({
		type: "bigint",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _coercedBigint(Class, params) {
	return new Class({
		type: "bigint",
		coerce: true,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _int64(Class, params) {
	return new Class({
		type: "bigint",
		check: "bigint_format",
		abort: false,
		format: "int64",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uint64(Class, params) {
	return new Class({
		type: "bigint",
		check: "bigint_format",
		abort: false,
		format: "uint64",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _symbol(Class, params) {
	return new Class({
		type: "symbol",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _undefined$1(Class, params) {
	return new Class({
		type: "undefined",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _null$1(Class, params) {
	return new Class({
		type: "null",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _any(Class) {
	return new Class({ type: "any" });
}
// @__NO_SIDE_EFFECTS__
function _unknown(Class) {
	return new Class({ type: "unknown" });
}
// @__NO_SIDE_EFFECTS__
function _never(Class, params) {
	return new Class({
		type: "never",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _void$1(Class, params) {
	return new Class({
		type: "void",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _date(Class, params) {
	return new Class({
		type: "date",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _coercedDate(Class, params) {
	return new Class({
		type: "date",
		coerce: true,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _nan(Class, params) {
	return new Class({
		type: "nan",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _lt(value, params) {
	return new $ZodCheckLessThan({
		check: "less_than",
		...normalizeParams(params),
		value,
		inclusive: false
	});
}
// @__NO_SIDE_EFFECTS__
function _lte(value, params) {
	return new $ZodCheckLessThan({
		check: "less_than",
		...normalizeParams(params),
		value,
		inclusive: true
	});
}
// @__NO_SIDE_EFFECTS__
function _gt(value, params) {
	return new $ZodCheckGreaterThan({
		check: "greater_than",
		...normalizeParams(params),
		value,
		inclusive: false
	});
}
// @__NO_SIDE_EFFECTS__
function _gte(value, params) {
	return new $ZodCheckGreaterThan({
		check: "greater_than",
		...normalizeParams(params),
		value,
		inclusive: true
	});
}
// @__NO_SIDE_EFFECTS__
function _positive(params) {
	return /* @__PURE__ */ _gt(0, params);
}
// @__NO_SIDE_EFFECTS__
function _negative(params) {
	return /* @__PURE__ */ _lt(0, params);
}
// @__NO_SIDE_EFFECTS__
function _nonpositive(params) {
	return /* @__PURE__ */ _lte(0, params);
}
// @__NO_SIDE_EFFECTS__
function _nonnegative(params) {
	return /* @__PURE__ */ _gte(0, params);
}
// @__NO_SIDE_EFFECTS__
function _multipleOf(value, params) {
	return new $ZodCheckMultipleOf({
		check: "multiple_of",
		...normalizeParams(params),
		value
	});
}
// @__NO_SIDE_EFFECTS__
function _maxSize(maximum, params) {
	return new $ZodCheckMaxSize({
		check: "max_size",
		...normalizeParams(params),
		maximum
	});
}
// @__NO_SIDE_EFFECTS__
function _minSize(minimum, params) {
	return new $ZodCheckMinSize({
		check: "min_size",
		...normalizeParams(params),
		minimum
	});
}
// @__NO_SIDE_EFFECTS__
function _size(size, params) {
	return new $ZodCheckSizeEquals({
		check: "size_equals",
		...normalizeParams(params),
		size
	});
}
// @__NO_SIDE_EFFECTS__
function _maxLength(maximum, params) {
	return new $ZodCheckMaxLength({
		check: "max_length",
		...normalizeParams(params),
		maximum
	});
}
// @__NO_SIDE_EFFECTS__
function _minLength(minimum, params) {
	return new $ZodCheckMinLength({
		check: "min_length",
		...normalizeParams(params),
		minimum
	});
}
// @__NO_SIDE_EFFECTS__
function _length(length, params) {
	return new $ZodCheckLengthEquals({
		check: "length_equals",
		...normalizeParams(params),
		length
	});
}
// @__NO_SIDE_EFFECTS__
function _regex(pattern, params) {
	return new $ZodCheckRegex({
		check: "string_format",
		format: "regex",
		...normalizeParams(params),
		pattern
	});
}
// @__NO_SIDE_EFFECTS__
function _lowercase(params) {
	return new $ZodCheckLowerCase({
		check: "string_format",
		format: "lowercase",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _uppercase(params) {
	return new $ZodCheckUpperCase({
		check: "string_format",
		format: "uppercase",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _includes(includes, params) {
	return new $ZodCheckIncludes({
		check: "string_format",
		format: "includes",
		...normalizeParams(params),
		includes
	});
}
// @__NO_SIDE_EFFECTS__
function _startsWith(prefix, params) {
	return new $ZodCheckStartsWith({
		check: "string_format",
		format: "starts_with",
		...normalizeParams(params),
		prefix
	});
}
// @__NO_SIDE_EFFECTS__
function _endsWith(suffix, params) {
	return new $ZodCheckEndsWith({
		check: "string_format",
		format: "ends_with",
		...normalizeParams(params),
		suffix
	});
}
// @__NO_SIDE_EFFECTS__
function _property(property, schema, params) {
	return new $ZodCheckProperty({
		check: "property",
		property,
		schema,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _mime(types, params) {
	return new $ZodCheckMimeType({
		check: "mime_type",
		mime: types,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _overwrite(tx) {
	return new $ZodCheckOverwrite({
		check: "overwrite",
		tx
	});
}
// @__NO_SIDE_EFFECTS__
function _normalize(form) {
	return /* @__PURE__ */ _overwrite((input) => input.normalize(form));
}
// @__NO_SIDE_EFFECTS__
function _trim() {
	return /* @__PURE__ */ _overwrite((input) => input.trim());
}
// @__NO_SIDE_EFFECTS__
function _toLowerCase() {
	return /* @__PURE__ */ _overwrite((input) => input.toLowerCase());
}
// @__NO_SIDE_EFFECTS__
function _toUpperCase() {
	return /* @__PURE__ */ _overwrite((input) => input.toUpperCase());
}
// @__NO_SIDE_EFFECTS__
function _slugify() {
	return /* @__PURE__ */ _overwrite((input) => slugify(input));
}
// @__NO_SIDE_EFFECTS__
function _array(Class, element, params) {
	return new Class({
		type: "array",
		element,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _union(Class, options, params) {
	return new Class({
		type: "union",
		options,
		...normalizeParams(params)
	});
}
function _xor(Class, options, params) {
	return new Class({
		type: "union",
		options,
		inclusive: false,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _discriminatedUnion(Class, discriminator, options, params) {
	return new Class({
		type: "union",
		options,
		discriminator,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _intersection(Class, left, right) {
	return new Class({
		type: "intersection",
		left,
		right
	});
}
// @__NO_SIDE_EFFECTS__
function _tuple(Class, items, _paramsOrRest, _params) {
	const hasRest = _paramsOrRest instanceof $ZodType;
	return new Class({
		type: "tuple",
		items,
		rest: hasRest ? _paramsOrRest : null,
		...normalizeParams(hasRest ? _params : _paramsOrRest)
	});
}
// @__NO_SIDE_EFFECTS__
function _record(Class, keyType, valueType, params) {
	return new Class({
		type: "record",
		keyType,
		valueType,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _map(Class, keyType, valueType, params) {
	return new Class({
		type: "map",
		keyType,
		valueType,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _set(Class, valueType, params) {
	return new Class({
		type: "set",
		valueType,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _enum$1(Class, values, params) {
	return new Class({
		type: "enum",
		entries: Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values,
		...normalizeParams(params)
	});
}
/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.
*
* ```ts
* enum Colors { red, green, blue }
* z.enum(Colors);
* ```
*/
// @__NO_SIDE_EFFECTS__
function _nativeEnum(Class, entries, params) {
	return new Class({
		type: "enum",
		entries,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _literal(Class, value, params) {
	return new Class({
		type: "literal",
		values: Array.isArray(value) ? value : [value],
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _file(Class, params) {
	return new Class({
		type: "file",
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _transform(Class, fn) {
	return new Class({
		type: "transform",
		transform: fn
	});
}
// @__NO_SIDE_EFFECTS__
function _optional(Class, innerType) {
	return new Class({
		type: "optional",
		innerType
	});
}
// @__NO_SIDE_EFFECTS__
function _nullable(Class, innerType) {
	return new Class({
		type: "nullable",
		innerType
	});
}
// @__NO_SIDE_EFFECTS__
function _default$1(Class, innerType, defaultValue) {
	return new Class({
		type: "default",
		innerType,
		get defaultValue() {
			return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue);
		}
	});
}
// @__NO_SIDE_EFFECTS__
function _nonoptional(Class, innerType, params) {
	return new Class({
		type: "nonoptional",
		innerType,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _success(Class, innerType) {
	return new Class({
		type: "success",
		innerType
	});
}
// @__NO_SIDE_EFFECTS__
function _catch$1(Class, innerType, catchValue) {
	return new Class({
		type: "catch",
		innerType,
		catchValue: typeof catchValue === "function" ? catchValue : () => catchValue
	});
}
// @__NO_SIDE_EFFECTS__
function _pipe(Class, in_, out) {
	return new Class({
		type: "pipe",
		in: in_,
		out
	});
}
// @__NO_SIDE_EFFECTS__
function _readonly(Class, innerType) {
	return new Class({
		type: "readonly",
		innerType
	});
}
// @__NO_SIDE_EFFECTS__
function _templateLiteral(Class, parts, params) {
	return new Class({
		type: "template_literal",
		parts,
		...normalizeParams(params)
	});
}
// @__NO_SIDE_EFFECTS__
function _lazy(Class, getter) {
	return new Class({
		type: "lazy",
		getter
	});
}
// @__NO_SIDE_EFFECTS__
function _promise(Class, innerType) {
	return new Class({
		type: "promise",
		innerType
	});
}
// @__NO_SIDE_EFFECTS__
function _custom(Class, fn, _params) {
	const norm = normalizeParams(_params);
	norm.abort ?? (norm.abort = true);
	return new Class({
		type: "custom",
		check: "custom",
		fn,
		...norm
	});
}
// @__NO_SIDE_EFFECTS__
function _refine(Class, fn, _params) {
	return new Class({
		type: "custom",
		check: "custom",
		fn,
		...normalizeParams(_params)
	});
}
// @__NO_SIDE_EFFECTS__
function _superRefine(fn, params) {
	const ch = /* @__PURE__ */ _check((payload) => {
		payload.addIssue = (issue$2) => {
			if (typeof issue$2 === "string") payload.issues.push(issue(issue$2, payload.value, ch._zod.def));
			else {
				const _issue = issue$2;
				if (_issue.fatal) _issue.continue = false;
				_issue.code ?? (_issue.code = "custom");
				_issue.input ?? (_issue.input = payload.value);
				_issue.inst ?? (_issue.inst = ch);
				_issue.continue ?? (_issue.continue = !ch._zod.def.abort);
				payload.issues.push(issue(_issue));
			}
		};
		return fn(payload.value, payload);
	}, params);
	return ch;
}
// @__NO_SIDE_EFFECTS__
function _check(fn, params) {
	const ch = new $ZodCheck({
		check: "custom",
		...normalizeParams(params)
	});
	ch._zod.check = fn;
	return ch;
}
// @__NO_SIDE_EFFECTS__
function describe$1(description) {
	const ch = new $ZodCheck({ check: "describe" });
	ch._zod.onattach = [(inst) => {
		const existing = globalRegistry.get(inst) ?? {};
		globalRegistry.add(inst, {
			...existing,
			description
		});
	}];
	ch._zod.check = () => {};
	return ch;
}
// @__NO_SIDE_EFFECTS__
function meta$1(metadata) {
	const ch = new $ZodCheck({ check: "meta" });
	ch._zod.onattach = [(inst) => {
		const existing = globalRegistry.get(inst) ?? {};
		globalRegistry.add(inst, {
			...existing,
			...metadata
		});
	}];
	ch._zod.check = () => {};
	return ch;
}
// @__NO_SIDE_EFFECTS__
function _stringbool(Classes, _params) {
	const params = normalizeParams(_params);
	let truthyArray = params.truthy ?? [
		"true",
		"1",
		"yes",
		"on",
		"y",
		"enabled"
	];
	let falsyArray = params.falsy ?? [
		"false",
		"0",
		"no",
		"off",
		"n",
		"disabled"
	];
	if (params.case !== "sensitive") {
		truthyArray = truthyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v);
		falsyArray = falsyArray.map((v) => typeof v === "string" ? v.toLowerCase() : v);
	}
	const truthySet = new Set(truthyArray);
	const falsySet = new Set(falsyArray);
	const _Codec = Classes.Codec ?? $ZodCodec;
	const _Boolean = Classes.Boolean ?? $ZodBoolean;
	const codec = new _Codec({
		type: "pipe",
		in: new (Classes.String ?? $ZodString)({
			type: "string",
			error: params.error
		}),
		out: new _Boolean({
			type: "boolean",
			error: params.error
		}),
		transform: ((input, payload) => {
			let data = input;
			if (params.case !== "sensitive") data = data.toLowerCase();
			if (truthySet.has(data)) return true;
			else if (falsySet.has(data)) return false;
			else {
				payload.issues.push({
					code: "invalid_value",
					expected: "stringbool",
					values: [...truthySet, ...falsySet],
					input: payload.value,
					inst: codec,
					continue: false
				});
				return {};
			}
		}),
		reverseTransform: ((input, _payload) => {
			if (input === true) return truthyArray[0] || "true";
			else return falsyArray[0] || "false";
		}),
		error: params.error
	});
	return codec;
}
// @__NO_SIDE_EFFECTS__
function _stringFormat(Class, format, fnOrRegex, _params = {}) {
	const params = normalizeParams(_params);
	const def = {
		...normalizeParams(_params),
		check: "string_format",
		type: "string",
		format,
		fn: typeof fnOrRegex === "function" ? fnOrRegex : (val) => fnOrRegex.test(val),
		...params
	};
	if (fnOrRegex instanceof RegExp) def.pattern = fnOrRegex;
	return new Class(def);
}
//#endregion
//#region node_modules/zod/v4/core/to-json-schema.js
function initializeContext(params) {
	let target = params?.target ?? "draft-2020-12";
	if (target === "draft-4") target = "draft-04";
	if (target === "draft-7") target = "draft-07";
	return {
		processors: params.processors ?? {},
		metadataRegistry: params?.metadata ?? globalRegistry,
		target,
		unrepresentable: params?.unrepresentable ?? "throw",
		override: params?.override ?? (() => {}),
		io: params?.io ?? "output",
		counter: 0,
		seen: /* @__PURE__ */ new Map(),
		cycles: params?.cycles ?? "ref",
		reused: params?.reused ?? "inline",
		external: params?.external ?? void 0
	};
}
function process$1(schema, ctx, _params = {
	path: [],
	schemaPath: []
}) {
	var _a;
	const def = schema._zod.def;
	const seen = ctx.seen.get(schema);
	if (seen) {
		seen.count++;
		if (_params.schemaPath.includes(schema)) seen.cycle = _params.path;
		return seen.schema;
	}
	const result = {
		schema: {},
		count: 1,
		cycle: void 0,
		path: _params.path
	};
	ctx.seen.set(schema, result);
	const overrideSchema = schema._zod.toJSONSchema?.();
	if (overrideSchema) result.schema = overrideSchema;
	else {
		const params = {
			..._params,
			schemaPath: [..._params.schemaPath, schema],
			path: _params.path
		};
		if (schema._zod.processJSONSchema) schema._zod.processJSONSchema(ctx, result.schema, params);
		else {
			const _json = result.schema;
			const processor = ctx.processors[def.type];
			if (!processor) throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`);
			processor(schema, ctx, _json, params);
		}
		const parent = schema._zod.parent;
		if (parent) {
			if (!result.ref) result.ref = parent;
			process$1(parent, ctx, params);
			ctx.seen.get(parent).isParent = true;
		}
	}
	const meta = ctx.metadataRegistry.get(schema);
	if (meta) Object.assign(result.schema, meta);
	if (ctx.io === "input" && isTransforming(schema)) {
		delete result.schema.examples;
		delete result.schema.default;
	}
	if (ctx.io === "input" && "_prefault" in result.schema) (_a = result.schema).default ?? (_a.default = result.schema._prefault);
	delete result.schema._prefault;
	return ctx.seen.get(schema).schema;
}
function extractDefs(ctx, schema) {
	const root = ctx.seen.get(schema);
	if (!root) throw new Error("Unprocessed schema. This is a bug in Zod.");
	const idToSchema = /* @__PURE__ */ new Map();
	for (const entry of ctx.seen.entries()) {
		const id = ctx.metadataRegistry.get(entry[0])?.id;
		if (id) {
			const existing = idToSchema.get(id);
			if (existing && existing !== entry[0]) throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
			idToSchema.set(id, entry[0]);
		}
	}
	const makeURI = (entry) => {
		const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
		if (ctx.external) {
			const externalId = ctx.external.registry.get(entry[0])?.id;
			const uriGenerator = ctx.external.uri ?? ((id) => id);
			if (externalId) return { ref: uriGenerator(externalId) };
			const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
			entry[1].defId = id;
			return {
				defId: id,
				ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}`
			};
		}
		if (entry[1] === root) return { ref: "#" };
		const defUriPrefix = `#/${defsSegment}/`;
		const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;
		return {
			defId,
			ref: defUriPrefix + defId
		};
	};
	const extractToDef = (entry) => {
		if (entry[1].schema.$ref) return;
		const seen = entry[1];
		const { ref, defId } = makeURI(entry);
		seen.def = { ...seen.schema };
		if (defId) seen.defId = defId;
		const schema = seen.schema;
		for (const key in schema) delete schema[key];
		schema.$ref = ref;
	};
	if (ctx.cycles === "throw") for (const entry of ctx.seen.entries()) {
		const seen = entry[1];
		if (seen.cycle) throw new Error(`Cycle detected: #/${seen.cycle?.join("/")}/<root>

Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`);
	}
	for (const entry of ctx.seen.entries()) {
		const seen = entry[1];
		if (schema === entry[0]) {
			extractToDef(entry);
			continue;
		}
		if (ctx.external) {
			const ext = ctx.external.registry.get(entry[0])?.id;
			if (schema !== entry[0] && ext) {
				extractToDef(entry);
				continue;
			}
		}
		if (ctx.metadataRegistry.get(entry[0])?.id) {
			extractToDef(entry);
			continue;
		}
		if (seen.cycle) {
			extractToDef(entry);
			continue;
		}
		if (seen.count > 1) {
			if (ctx.reused === "ref") {
				extractToDef(entry);
				continue;
			}
		}
	}
}
function finalize(ctx, schema) {
	const root = ctx.seen.get(schema);
	if (!root) throw new Error("Unprocessed schema. This is a bug in Zod.");
	const flattenRef = (zodSchema) => {
		const seen = ctx.seen.get(zodSchema);
		if (seen.ref === null) return;
		const schema = seen.def ?? seen.schema;
		const _cached = { ...schema };
		const ref = seen.ref;
		seen.ref = null;
		if (ref) {
			flattenRef(ref);
			const refSeen = ctx.seen.get(ref);
			const refSchema = refSeen.schema;
			if (refSchema.$ref && (ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0")) {
				schema.allOf = schema.allOf ?? [];
				schema.allOf.push(refSchema);
			} else Object.assign(schema, refSchema);
			Object.assign(schema, _cached);
			if (zodSchema._zod.parent === ref) for (const key in schema) {
				if (key === "$ref" || key === "allOf") continue;
				if (!(key in _cached)) delete schema[key];
			}
			if (refSchema.$ref && refSeen.def) for (const key in schema) {
				if (key === "$ref" || key === "allOf") continue;
				if (key in refSeen.def && JSON.stringify(schema[key]) === JSON.stringify(refSeen.def[key])) delete schema[key];
			}
		}
		const parent = zodSchema._zod.parent;
		if (parent && parent !== ref) {
			flattenRef(parent);
			const parentSeen = ctx.seen.get(parent);
			if (parentSeen?.schema.$ref) {
				schema.$ref = parentSeen.schema.$ref;
				if (parentSeen.def) for (const key in schema) {
					if (key === "$ref" || key === "allOf") continue;
					if (key in parentSeen.def && JSON.stringify(schema[key]) === JSON.stringify(parentSeen.def[key])) delete schema[key];
				}
			}
		}
		ctx.override({
			zodSchema,
			jsonSchema: schema,
			path: seen.path ?? []
		});
	};
	for (const entry of [...ctx.seen.entries()].reverse()) flattenRef(entry[0]);
	const result = {};
	if (ctx.target === "draft-2020-12") result.$schema = "https://json-schema.org/draft/2020-12/schema";
	else if (ctx.target === "draft-07") result.$schema = "http://json-schema.org/draft-07/schema#";
	else if (ctx.target === "draft-04") result.$schema = "http://json-schema.org/draft-04/schema#";
	else if (ctx.target === "openapi-3.0") {}
	if (ctx.external?.uri) {
		const id = ctx.external.registry.get(schema)?.id;
		if (!id) throw new Error("Schema is missing an `id` property");
		result.$id = ctx.external.uri(id);
	}
	Object.assign(result, root.def ?? root.schema);
	const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
	if (rootMetaId !== void 0 && result.id === rootMetaId) delete result.id;
	const defs = ctx.external?.defs ?? {};
	for (const entry of ctx.seen.entries()) {
		const seen = entry[1];
		if (seen.def && seen.defId) {
			if (seen.def.id === seen.defId) delete seen.def.id;
			defs[seen.defId] = seen.def;
		}
	}
	if (ctx.external) {} else if (Object.keys(defs).length > 0) if (ctx.target === "draft-2020-12") result.$defs = defs;
	else result.definitions = defs;
	try {
		const finalized = JSON.parse(JSON.stringify(result));
		Object.defineProperty(finalized, "~standard", {
			value: {
				...schema["~standard"],
				jsonSchema: {
					input: createStandardJSONSchemaMethod(schema, "input", ctx.processors),
					output: createStandardJSONSchemaMethod(schema, "output", ctx.processors)
				}
			},
			enumerable: false,
			writable: false
		});
		return finalized;
	} catch (_err) {
		throw new Error("Error converting schema to JSON.");
	}
}
function isTransforming(_schema, _ctx) {
	const ctx = _ctx ?? { seen: /* @__PURE__ */ new Set() };
	if (ctx.seen.has(_schema)) return false;
	ctx.seen.add(_schema);
	const def = _schema._zod.def;
	if (def.type === "transform") return true;
	if (def.type === "array") return isTransforming(def.element, ctx);
	if (def.type === "set") return isTransforming(def.valueType, ctx);
	if (def.type === "lazy") return isTransforming(def.getter(), ctx);
	if (def.type === "promise" || def.type === "optional" || def.type === "nonoptional" || def.type === "nullable" || def.type === "readonly" || def.type === "default" || def.type === "prefault") return isTransforming(def.innerType, ctx);
	if (def.type === "intersection") return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);
	if (def.type === "record" || def.type === "map") return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
	if (def.type === "pipe") {
		if (_schema._zod.traits.has("$ZodCodec")) return true;
		return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
	}
	if (def.type === "object") {
		for (const key in def.shape) if (isTransforming(def.shape[key], ctx)) return true;
		return false;
	}
	if (def.type === "union") {
		for (const option of def.options) if (isTransforming(option, ctx)) return true;
		return false;
	}
	if (def.type === "tuple") {
		for (const item of def.items) if (isTransforming(item, ctx)) return true;
		if (def.rest && isTransforming(def.rest, ctx)) return true;
		return false;
	}
	return false;
}
/**
* Creates a toJSONSchema method for a schema instance.
* This encapsulates the logic of initializing context, processing, extracting defs, and finalizing.
*/
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
	const ctx = initializeContext({
		...params,
		processors
	});
	process$1(schema, ctx);
	extractDefs(ctx, schema);
	return finalize(ctx, schema);
};
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
	const { libraryOptions, target } = params ?? {};
	const ctx = initializeContext({
		...libraryOptions ?? {},
		target,
		io,
		processors
	});
	process$1(schema, ctx);
	extractDefs(ctx, schema);
	return finalize(ctx, schema);
};
//#endregion
//#region node_modules/zod/v4/core/json-schema-processors.js
var formatMap = {
	guid: "uuid",
	url: "uri",
	datetime: "date-time",
	json_string: "json-string",
	regex: ""
};
var stringProcessor = (schema, ctx, _json, _params) => {
	const json = _json;
	json.type = "string";
	const { minimum, maximum, format, patterns, contentEncoding } = schema._zod.bag;
	if (typeof minimum === "number") json.minLength = minimum;
	if (typeof maximum === "number") json.maxLength = maximum;
	if (format) {
		json.format = formatMap[format] ?? format;
		if (json.format === "") delete json.format;
		if (format === "time") delete json.format;
	}
	if (contentEncoding) json.contentEncoding = contentEncoding;
	if (patterns && patterns.size > 0) {
		const regexes = [...patterns];
		if (regexes.length === 1) json.pattern = regexes[0].source;
		else if (regexes.length > 1) json.allOf = [...regexes.map((regex) => ({
			...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {},
			pattern: regex.source
		}))];
	}
};
var numberProcessor = (schema, ctx, _json, _params) => {
	const json = _json;
	const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;
	if (typeof format === "string" && format.includes("int")) json.type = "integer";
	else json.type = "number";
	const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
	const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
	const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
	if (exMin) if (legacy) {
		json.minimum = exclusiveMinimum;
		json.exclusiveMinimum = true;
	} else json.exclusiveMinimum = exclusiveMinimum;
	else if (typeof minimum === "number") json.minimum = minimum;
	if (exMax) if (legacy) {
		json.maximum = exclusiveMaximum;
		json.exclusiveMaximum = true;
	} else json.exclusiveMaximum = exclusiveMaximum;
	else if (typeof maximum === "number") json.maximum = maximum;
	if (typeof multipleOf === "number") json.multipleOf = multipleOf;
};
var booleanProcessor = (_schema, _ctx, json, _params) => {
	json.type = "boolean";
};
var bigintProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("BigInt cannot be represented in JSON Schema");
};
var symbolProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Symbols cannot be represented in JSON Schema");
};
var nullProcessor = (_schema, ctx, json, _params) => {
	if (ctx.target === "openapi-3.0") {
		json.type = "string";
		json.nullable = true;
		json.enum = [null];
	} else json.type = "null";
};
var undefinedProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Undefined cannot be represented in JSON Schema");
};
var voidProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Void cannot be represented in JSON Schema");
};
var neverProcessor = (_schema, _ctx, json, _params) => {
	json.not = {};
};
var anyProcessor = (_schema, _ctx, _json, _params) => {};
var unknownProcessor = (_schema, _ctx, _json, _params) => {};
var dateProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Date cannot be represented in JSON Schema");
};
var enumProcessor = (schema, _ctx, json, _params) => {
	const def = schema._zod.def;
	const values = getEnumValues(def.entries);
	if (values.every((v) => typeof v === "number")) json.type = "number";
	if (values.every((v) => typeof v === "string")) json.type = "string";
	json.enum = values;
};
var literalProcessor = (schema, ctx, json, _params) => {
	const def = schema._zod.def;
	const vals = [];
	for (const val of def.values) if (val === void 0) {
		if (ctx.unrepresentable === "throw") throw new Error("Literal `undefined` cannot be represented in JSON Schema");
	} else if (typeof val === "bigint") if (ctx.unrepresentable === "throw") throw new Error("BigInt literals cannot be represented in JSON Schema");
	else vals.push(Number(val));
	else vals.push(val);
	if (vals.length === 0) {} else if (vals.length === 1) {
		const val = vals[0];
		json.type = val === null ? "null" : typeof val;
		if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") json.enum = [val];
		else json.const = val;
	} else {
		if (vals.every((v) => typeof v === "number")) json.type = "number";
		if (vals.every((v) => typeof v === "string")) json.type = "string";
		if (vals.every((v) => typeof v === "boolean")) json.type = "boolean";
		if (vals.every((v) => v === null)) json.type = "null";
		json.enum = vals;
	}
};
var nanProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("NaN cannot be represented in JSON Schema");
};
var templateLiteralProcessor = (schema, _ctx, json, _params) => {
	const _json = json;
	const pattern = schema._zod.pattern;
	if (!pattern) throw new Error("Pattern not found in template literal");
	_json.type = "string";
	_json.pattern = pattern.source;
};
var fileProcessor = (schema, _ctx, json, _params) => {
	const _json = json;
	const file = {
		type: "string",
		format: "binary",
		contentEncoding: "binary"
	};
	const { minimum, maximum, mime } = schema._zod.bag;
	if (minimum !== void 0) file.minLength = minimum;
	if (maximum !== void 0) file.maxLength = maximum;
	if (mime) if (mime.length === 1) {
		file.contentMediaType = mime[0];
		Object.assign(_json, file);
	} else {
		Object.assign(_json, file);
		_json.anyOf = mime.map((m) => ({ contentMediaType: m }));
	}
	else Object.assign(_json, file);
};
var successProcessor = (_schema, _ctx, json, _params) => {
	json.type = "boolean";
};
var customProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Custom types cannot be represented in JSON Schema");
};
var functionProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Function types cannot be represented in JSON Schema");
};
var transformProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Transforms cannot be represented in JSON Schema");
};
var mapProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Map cannot be represented in JSON Schema");
};
var setProcessor = (_schema, ctx, _json, _params) => {
	if (ctx.unrepresentable === "throw") throw new Error("Set cannot be represented in JSON Schema");
};
var arrayProcessor = (schema, ctx, _json, params) => {
	const json = _json;
	const def = schema._zod.def;
	const { minimum, maximum } = schema._zod.bag;
	if (typeof minimum === "number") json.minItems = minimum;
	if (typeof maximum === "number") json.maxItems = maximum;
	json.type = "array";
	json.items = process$1(def.element, ctx, {
		...params,
		path: [...params.path, "items"]
	});
};
var objectProcessor = (schema, ctx, _json, params) => {
	const json = _json;
	const def = schema._zod.def;
	json.type = "object";
	json.properties = {};
	const shape = def.shape;
	for (const key in shape) json.properties[key] = process$1(shape[key], ctx, {
		...params,
		path: [
			...params.path,
			"properties",
			key
		]
	});
	const allKeys = new Set(Object.keys(shape));
	const requiredKeys = new Set([...allKeys].filter((key) => {
		const v = def.shape[key]._zod;
		if (ctx.io === "input") return v.optin === void 0;
		else return v.optout === void 0;
	}));
	if (requiredKeys.size > 0) json.required = Array.from(requiredKeys);
	if (def.catchall?._zod.def.type === "never") json.additionalProperties = false;
	else if (!def.catchall) {
		if (ctx.io === "output") json.additionalProperties = false;
	} else if (def.catchall) json.additionalProperties = process$1(def.catchall, ctx, {
		...params,
		path: [...params.path, "additionalProperties"]
	});
};
var unionProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	const isExclusive = def.inclusive === false;
	const options = def.options.map((x, i) => process$1(x, ctx, {
		...params,
		path: [
			...params.path,
			isExclusive ? "oneOf" : "anyOf",
			i
		]
	}));
	if (isExclusive) json.oneOf = options;
	else json.anyOf = options;
};
var intersectionProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	const a = process$1(def.left, ctx, {
		...params,
		path: [
			...params.path,
			"allOf",
			0
		]
	});
	const b = process$1(def.right, ctx, {
		...params,
		path: [
			...params.path,
			"allOf",
			1
		]
	});
	const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
	json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
};
var tupleProcessor = (schema, ctx, _json, params) => {
	const json = _json;
	const def = schema._zod.def;
	json.type = "array";
	const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
	const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
	const prefixItems = def.items.map((x, i) => process$1(x, ctx, {
		...params,
		path: [
			...params.path,
			prefixPath,
			i
		]
	}));
	const rest = def.rest ? process$1(def.rest, ctx, {
		...params,
		path: [
			...params.path,
			restPath,
			...ctx.target === "openapi-3.0" ? [def.items.length] : []
		]
	}) : null;
	if (ctx.target === "draft-2020-12") {
		json.prefixItems = prefixItems;
		if (rest) json.items = rest;
	} else if (ctx.target === "openapi-3.0") {
		json.items = { anyOf: prefixItems };
		if (rest) json.items.anyOf.push(rest);
		json.minItems = prefixItems.length;
		if (!rest) json.maxItems = prefixItems.length;
	} else {
		json.items = prefixItems;
		if (rest) json.additionalItems = rest;
	}
	const { minimum, maximum } = schema._zod.bag;
	if (typeof minimum === "number") json.minItems = minimum;
	if (typeof maximum === "number") json.maxItems = maximum;
};
var recordProcessor = (schema, ctx, _json, params) => {
	const json = _json;
	const def = schema._zod.def;
	json.type = "object";
	const keyType = def.keyType;
	const patterns = keyType._zod.bag?.patterns;
	if (def.mode === "loose" && patterns && patterns.size > 0) {
		const valueSchema = process$1(def.valueType, ctx, {
			...params,
			path: [
				...params.path,
				"patternProperties",
				"*"
			]
		});
		json.patternProperties = {};
		for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
	} else {
		if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$1(def.keyType, ctx, {
			...params,
			path: [...params.path, "propertyNames"]
		});
		json.additionalProperties = process$1(def.valueType, ctx, {
			...params,
			path: [...params.path, "additionalProperties"]
		});
	}
	const keyValues = keyType._zod.values;
	if (keyValues) {
		const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
		if (validKeyValues.length > 0) json.required = validKeyValues;
	}
};
var nullableProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	const inner = process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	if (ctx.target === "openapi-3.0") {
		seen.ref = def.innerType;
		json.nullable = true;
	} else json.anyOf = [inner, { type: "null" }];
};
var nonoptionalProcessor = (schema, ctx, _json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
};
var defaultProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
	json.default = JSON.parse(JSON.stringify(def.defaultValue));
};
var prefaultProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
	if (ctx.io === "input") json._prefault = JSON.parse(JSON.stringify(def.defaultValue));
};
var catchProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
	let catchValue;
	try {
		catchValue = def.catchValue(void 0);
	} catch {
		throw new Error("Dynamic catch values are not supported in JSON Schema");
	}
	json.default = catchValue;
};
var pipeProcessor = (schema, ctx, _json, params) => {
	const def = schema._zod.def;
	const inIsTransform = def.in._zod.traits.has("$ZodTransform");
	const innerType = ctx.io === "input" ? inIsTransform ? def.out : def.in : def.out;
	process$1(innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = innerType;
};
var readonlyProcessor = (schema, ctx, json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
	json.readOnly = true;
};
var promiseProcessor = (schema, ctx, _json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
};
var optionalProcessor = (schema, ctx, _json, params) => {
	const def = schema._zod.def;
	process$1(def.innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = def.innerType;
};
var lazyProcessor = (schema, ctx, _json, params) => {
	const innerType = schema._zod.innerType;
	process$1(innerType, ctx, params);
	const seen = ctx.seen.get(schema);
	seen.ref = innerType;
};
var allProcessors = {
	string: stringProcessor,
	number: numberProcessor,
	boolean: booleanProcessor,
	bigint: bigintProcessor,
	symbol: symbolProcessor,
	null: nullProcessor,
	undefined: undefinedProcessor,
	void: voidProcessor,
	never: neverProcessor,
	any: anyProcessor,
	unknown: unknownProcessor,
	date: dateProcessor,
	enum: enumProcessor,
	literal: literalProcessor,
	nan: nanProcessor,
	template_literal: templateLiteralProcessor,
	file: fileProcessor,
	success: successProcessor,
	custom: customProcessor,
	function: functionProcessor,
	transform: transformProcessor,
	map: mapProcessor,
	set: setProcessor,
	array: arrayProcessor,
	object: objectProcessor,
	union: unionProcessor,
	intersection: intersectionProcessor,
	tuple: tupleProcessor,
	record: recordProcessor,
	nullable: nullableProcessor,
	nonoptional: nonoptionalProcessor,
	default: defaultProcessor,
	prefault: prefaultProcessor,
	catch: catchProcessor,
	pipe: pipeProcessor,
	readonly: readonlyProcessor,
	promise: promiseProcessor,
	optional: optionalProcessor,
	lazy: lazyProcessor
};
function toJSONSchema(input, params) {
	if ("_idmap" in input) {
		const registry = input;
		const ctx = initializeContext({
			...params,
			processors: allProcessors
		});
		const defs = {};
		for (const entry of registry._idmap.entries()) {
			const [_, schema] = entry;
			process$1(schema, ctx);
		}
		const schemas = {};
		ctx.external = {
			registry,
			uri: params?.uri,
			defs
		};
		for (const entry of registry._idmap.entries()) {
			const [key, schema] = entry;
			extractDefs(ctx, schema);
			schemas[key] = finalize(ctx, schema);
		}
		if (Object.keys(defs).length > 0) schemas.__shared = { [ctx.target === "draft-2020-12" ? "$defs" : "definitions"]: defs };
		return { schemas };
	}
	const ctx = initializeContext({
		...params,
		processors: allProcessors
	});
	process$1(input, ctx);
	extractDefs(ctx, input);
	return finalize(ctx, input);
}
//#endregion
//#region node_modules/zod/v4/core/json-schema-generator.js
/**
* Legacy class-based interface for JSON Schema generation.
* This class wraps the new functional implementation to provide backward compatibility.
*
* @deprecated Use the `toJSONSchema` function instead for new code.
*
* @example
* ```typescript
* // Legacy usage (still supported)
* const gen = new JSONSchemaGenerator({ target: "draft-07" });
* gen.process(schema);
* const result = gen.emit(schema);
*
* // Preferred modern usage
* const result = toJSONSchema(schema, { target: "draft-07" });
* ```
*/
var JSONSchemaGenerator = class {
	/** @deprecated Access via ctx instead */
	get metadataRegistry() {
		return this.ctx.metadataRegistry;
	}
	/** @deprecated Access via ctx instead */
	get target() {
		return this.ctx.target;
	}
	/** @deprecated Access via ctx instead */
	get unrepresentable() {
		return this.ctx.unrepresentable;
	}
	/** @deprecated Access via ctx instead */
	get override() {
		return this.ctx.override;
	}
	/** @deprecated Access via ctx instead */
	get io() {
		return this.ctx.io;
	}
	/** @deprecated Access via ctx instead */
	get counter() {
		return this.ctx.counter;
	}
	set counter(value) {
		this.ctx.counter = value;
	}
	/** @deprecated Access via ctx instead */
	get seen() {
		return this.ctx.seen;
	}
	constructor(params) {
		let normalizedTarget = params?.target ?? "draft-2020-12";
		if (normalizedTarget === "draft-4") normalizedTarget = "draft-04";
		if (normalizedTarget === "draft-7") normalizedTarget = "draft-07";
		this.ctx = initializeContext({
			processors: allProcessors,
			target: normalizedTarget,
			...params?.metadata && { metadata: params.metadata },
			...params?.unrepresentable && { unrepresentable: params.unrepresentable },
			...params?.override && { override: params.override },
			...params?.io && { io: params.io }
		});
	}
	/**
	* Process a schema to prepare it for JSON Schema generation.
	* This must be called before emit().
	*/
	process(schema, _params = {
		path: [],
		schemaPath: []
	}) {
		return process$1(schema, this.ctx, _params);
	}
	/**
	* Emit the final JSON Schema after processing.
	* Must call process() first.
	*/
	emit(schema, _params) {
		if (_params) {
			if (_params.cycles) this.ctx.cycles = _params.cycles;
			if (_params.reused) this.ctx.reused = _params.reused;
			if (_params.external) this.ctx.external = _params.external;
		}
		extractDefs(this.ctx, schema);
		const { "~standard": _, ...plainResult } = finalize(this.ctx, schema);
		return plainResult;
	}
};
//#endregion
//#region node_modules/zod/v4/core/json-schema.js
var json_schema_exports = /* @__PURE__ */ __exportAll({});
//#endregion
//#region node_modules/zod/v4/core/index.js
var core_exports = /* @__PURE__ */ __exportAll({
	$ZodAny: () => $ZodAny,
	$ZodArray: () => $ZodArray,
	$ZodAsyncError: () => $ZodAsyncError,
	$ZodBase64: () => $ZodBase64,
	$ZodBase64URL: () => $ZodBase64URL,
	$ZodBigInt: () => $ZodBigInt,
	$ZodBigIntFormat: () => $ZodBigIntFormat,
	$ZodBoolean: () => $ZodBoolean,
	$ZodCIDRv4: () => $ZodCIDRv4,
	$ZodCIDRv6: () => $ZodCIDRv6,
	$ZodCUID: () => $ZodCUID,
	$ZodCUID2: () => $ZodCUID2,
	$ZodCatch: () => $ZodCatch,
	$ZodCheck: () => $ZodCheck,
	$ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
	$ZodCheckEndsWith: () => $ZodCheckEndsWith,
	$ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
	$ZodCheckIncludes: () => $ZodCheckIncludes,
	$ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
	$ZodCheckLessThan: () => $ZodCheckLessThan,
	$ZodCheckLowerCase: () => $ZodCheckLowerCase,
	$ZodCheckMaxLength: () => $ZodCheckMaxLength,
	$ZodCheckMaxSize: () => $ZodCheckMaxSize,
	$ZodCheckMimeType: () => $ZodCheckMimeType,
	$ZodCheckMinLength: () => $ZodCheckMinLength,
	$ZodCheckMinSize: () => $ZodCheckMinSize,
	$ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
	$ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
	$ZodCheckOverwrite: () => $ZodCheckOverwrite,
	$ZodCheckProperty: () => $ZodCheckProperty,
	$ZodCheckRegex: () => $ZodCheckRegex,
	$ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
	$ZodCheckStartsWith: () => $ZodCheckStartsWith,
	$ZodCheckStringFormat: () => $ZodCheckStringFormat,
	$ZodCheckUpperCase: () => $ZodCheckUpperCase,
	$ZodCodec: () => $ZodCodec,
	$ZodCustom: () => $ZodCustom,
	$ZodCustomStringFormat: () => $ZodCustomStringFormat,
	$ZodDate: () => $ZodDate,
	$ZodDefault: () => $ZodDefault,
	$ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
	$ZodE164: () => $ZodE164,
	$ZodEmail: () => $ZodEmail,
	$ZodEmoji: () => $ZodEmoji,
	$ZodEncodeError: () => $ZodEncodeError,
	$ZodEnum: () => $ZodEnum,
	$ZodError: () => $ZodError,
	$ZodExactOptional: () => $ZodExactOptional,
	$ZodFile: () => $ZodFile,
	$ZodFunction: () => $ZodFunction,
	$ZodGUID: () => $ZodGUID,
	$ZodIPv4: () => $ZodIPv4,
	$ZodIPv6: () => $ZodIPv6,
	$ZodISODate: () => $ZodISODate,
	$ZodISODateTime: () => $ZodISODateTime,
	$ZodISODuration: () => $ZodISODuration,
	$ZodISOTime: () => $ZodISOTime,
	$ZodIntersection: () => $ZodIntersection,
	$ZodJWT: () => $ZodJWT,
	$ZodKSUID: () => $ZodKSUID,
	$ZodLazy: () => $ZodLazy,
	$ZodLiteral: () => $ZodLiteral,
	$ZodMAC: () => $ZodMAC,
	$ZodMap: () => $ZodMap,
	$ZodNaN: () => $ZodNaN,
	$ZodNanoID: () => $ZodNanoID,
	$ZodNever: () => $ZodNever,
	$ZodNonOptional: () => $ZodNonOptional,
	$ZodNull: () => $ZodNull,
	$ZodNullable: () => $ZodNullable,
	$ZodNumber: () => $ZodNumber,
	$ZodNumberFormat: () => $ZodNumberFormat,
	$ZodObject: () => $ZodObject,
	$ZodObjectJIT: () => $ZodObjectJIT,
	$ZodOptional: () => $ZodOptional,
	$ZodPipe: () => $ZodPipe,
	$ZodPrefault: () => $ZodPrefault,
	$ZodPreprocess: () => $ZodPreprocess,
	$ZodPromise: () => $ZodPromise,
	$ZodReadonly: () => $ZodReadonly,
	$ZodRealError: () => $ZodRealError,
	$ZodRecord: () => $ZodRecord,
	$ZodRegistry: () => $ZodRegistry,
	$ZodSet: () => $ZodSet,
	$ZodString: () => $ZodString,
	$ZodStringFormat: () => $ZodStringFormat,
	$ZodSuccess: () => $ZodSuccess,
	$ZodSymbol: () => $ZodSymbol,
	$ZodTemplateLiteral: () => $ZodTemplateLiteral,
	$ZodTransform: () => $ZodTransform,
	$ZodTuple: () => $ZodTuple,
	$ZodType: () => $ZodType,
	$ZodULID: () => $ZodULID,
	$ZodURL: () => $ZodURL,
	$ZodUUID: () => $ZodUUID,
	$ZodUndefined: () => $ZodUndefined,
	$ZodUnion: () => $ZodUnion,
	$ZodUnknown: () => $ZodUnknown,
	$ZodVoid: () => $ZodVoid,
	$ZodXID: () => $ZodXID,
	$ZodXor: () => $ZodXor,
	$brand: () => $brand,
	$constructor: () => $constructor,
	$input: () => $input,
	$output: () => $output,
	Doc: () => Doc,
	JSONSchema: () => json_schema_exports,
	JSONSchemaGenerator: () => JSONSchemaGenerator,
	NEVER: () => NEVER,
	TimePrecision: () => TimePrecision,
	_any: () => _any,
	_array: () => _array,
	_base64: () => _base64,
	_base64url: () => _base64url,
	_bigint: () => _bigint,
	_boolean: () => _boolean,
	_catch: () => _catch$1,
	_check: () => _check,
	_cidrv4: () => _cidrv4,
	_cidrv6: () => _cidrv6,
	_coercedBigint: () => _coercedBigint,
	_coercedBoolean: () => _coercedBoolean,
	_coercedDate: () => _coercedDate,
	_coercedNumber: () => _coercedNumber,
	_coercedString: () => _coercedString,
	_cuid: () => _cuid,
	_cuid2: () => _cuid2,
	_custom: () => _custom,
	_date: () => _date,
	_decode: () => _decode,
	_decodeAsync: () => _decodeAsync,
	_default: () => _default$1,
	_discriminatedUnion: () => _discriminatedUnion,
	_e164: () => _e164,
	_email: () => _email,
	_emoji: () => _emoji,
	_encode: () => _encode,
	_encodeAsync: () => _encodeAsync,
	_endsWith: () => _endsWith,
	_enum: () => _enum$1,
	_file: () => _file,
	_float32: () => _float32,
	_float64: () => _float64,
	_gt: () => _gt,
	_gte: () => _gte,
	_guid: () => _guid,
	_includes: () => _includes,
	_int: () => _int,
	_int32: () => _int32,
	_int64: () => _int64,
	_intersection: () => _intersection,
	_ipv4: () => _ipv4,
	_ipv6: () => _ipv6,
	_isoDate: () => _isoDate,
	_isoDateTime: () => _isoDateTime,
	_isoDuration: () => _isoDuration,
	_isoTime: () => _isoTime,
	_jwt: () => _jwt,
	_ksuid: () => _ksuid,
	_lazy: () => _lazy,
	_length: () => _length,
	_literal: () => _literal,
	_lowercase: () => _lowercase,
	_lt: () => _lt,
	_lte: () => _lte,
	_mac: () => _mac,
	_map: () => _map,
	_max: () => _lte,
	_maxLength: () => _maxLength,
	_maxSize: () => _maxSize,
	_mime: () => _mime,
	_min: () => _gte,
	_minLength: () => _minLength,
	_minSize: () => _minSize,
	_multipleOf: () => _multipleOf,
	_nan: () => _nan,
	_nanoid: () => _nanoid,
	_nativeEnum: () => _nativeEnum,
	_negative: () => _negative,
	_never: () => _never,
	_nonnegative: () => _nonnegative,
	_nonoptional: () => _nonoptional,
	_nonpositive: () => _nonpositive,
	_normalize: () => _normalize,
	_null: () => _null$1,
	_nullable: () => _nullable,
	_number: () => _number,
	_optional: () => _optional,
	_overwrite: () => _overwrite,
	_parse: () => _parse,
	_parseAsync: () => _parseAsync,
	_pipe: () => _pipe,
	_positive: () => _positive,
	_promise: () => _promise,
	_property: () => _property,
	_readonly: () => _readonly,
	_record: () => _record,
	_refine: () => _refine,
	_regex: () => _regex,
	_safeDecode: () => _safeDecode,
	_safeDecodeAsync: () => _safeDecodeAsync,
	_safeEncode: () => _safeEncode,
	_safeEncodeAsync: () => _safeEncodeAsync,
	_safeParse: () => _safeParse,
	_safeParseAsync: () => _safeParseAsync,
	_set: () => _set,
	_size: () => _size,
	_slugify: () => _slugify,
	_startsWith: () => _startsWith,
	_string: () => _string,
	_stringFormat: () => _stringFormat,
	_stringbool: () => _stringbool,
	_success: () => _success,
	_superRefine: () => _superRefine,
	_symbol: () => _symbol,
	_templateLiteral: () => _templateLiteral,
	_toLowerCase: () => _toLowerCase,
	_toUpperCase: () => _toUpperCase,
	_transform: () => _transform,
	_trim: () => _trim,
	_tuple: () => _tuple,
	_uint32: () => _uint32,
	_uint64: () => _uint64,
	_ulid: () => _ulid,
	_undefined: () => _undefined$1,
	_union: () => _union,
	_unknown: () => _unknown,
	_uppercase: () => _uppercase,
	_url: () => _url,
	_uuid: () => _uuid,
	_uuidv4: () => _uuidv4,
	_uuidv6: () => _uuidv6,
	_uuidv7: () => _uuidv7,
	_void: () => _void$1,
	_xid: () => _xid,
	_xor: () => _xor,
	clone: () => clone,
	config: () => config,
	createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
	createToJSONSchemaMethod: () => createToJSONSchemaMethod,
	decode: () => decode$2,
	decodeAsync: () => decodeAsync$1,
	describe: () => describe$1,
	encode: () => encode$2,
	encodeAsync: () => encodeAsync$1,
	extractDefs: () => extractDefs,
	finalize: () => finalize,
	flattenError: () => flattenError,
	formatError: () => formatError,
	globalConfig: () => globalConfig,
	globalRegistry: () => globalRegistry,
	initializeContext: () => initializeContext,
	isValidBase64: () => isValidBase64,
	isValidBase64URL: () => isValidBase64URL,
	isValidJWT: () => isValidJWT,
	locales: () => locales_exports,
	meta: () => meta$1,
	parse: () => parse$1,
	parseAsync: () => parseAsync$1,
	prettifyError: () => prettifyError,
	process: () => process$1,
	regexes: () => regexes_exports,
	registry: () => registry,
	safeDecode: () => safeDecode$1,
	safeDecodeAsync: () => safeDecodeAsync$1,
	safeEncode: () => safeEncode$1,
	safeEncodeAsync: () => safeEncodeAsync$1,
	safeParse: () => safeParse$1,
	safeParseAsync: () => safeParseAsync$1,
	toDotPath: () => toDotPath,
	toJSONSchema: () => toJSONSchema,
	treeifyError: () => treeifyError,
	util: () => util_exports,
	version: () => version$2
});
//#endregion
//#region node_modules/zod/v4/classic/checks.js
var checks_exports = /* @__PURE__ */ __exportAll({
	endsWith: () => _endsWith,
	gt: () => _gt,
	gte: () => _gte,
	includes: () => _includes,
	length: () => _length,
	lowercase: () => _lowercase,
	lt: () => _lt,
	lte: () => _lte,
	maxLength: () => _maxLength,
	maxSize: () => _maxSize,
	mime: () => _mime,
	minLength: () => _minLength,
	minSize: () => _minSize,
	multipleOf: () => _multipleOf,
	negative: () => _negative,
	nonnegative: () => _nonnegative,
	nonpositive: () => _nonpositive,
	normalize: () => _normalize,
	overwrite: () => _overwrite,
	positive: () => _positive,
	property: () => _property,
	regex: () => _regex,
	size: () => _size,
	slugify: () => _slugify,
	startsWith: () => _startsWith,
	toLowerCase: () => _toLowerCase,
	toUpperCase: () => _toUpperCase,
	trim: () => _trim,
	uppercase: () => _uppercase
});
//#endregion
//#region node_modules/zod/v4/classic/iso.js
var iso_exports = /* @__PURE__ */ __exportAll({
	ZodISODate: () => ZodISODate,
	ZodISODateTime: () => ZodISODateTime,
	ZodISODuration: () => ZodISODuration,
	ZodISOTime: () => ZodISOTime,
	date: () => date$2,
	datetime: () => datetime,
	duration: () => duration,
	time: () => time
});
var ZodISODateTime = /*@__PURE__*/ $constructor("ZodISODateTime", (inst, def) => {
	$ZodISODateTime.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function datetime(params) {
	return /* @__PURE__ */ _isoDateTime(ZodISODateTime, params);
}
var ZodISODate = /*@__PURE__*/ $constructor("ZodISODate", (inst, def) => {
	$ZodISODate.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function date$2(params) {
	return /* @__PURE__ */ _isoDate(ZodISODate, params);
}
var ZodISOTime = /*@__PURE__*/ $constructor("ZodISOTime", (inst, def) => {
	$ZodISOTime.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function time(params) {
	return /* @__PURE__ */ _isoTime(ZodISOTime, params);
}
var ZodISODuration = /*@__PURE__*/ $constructor("ZodISODuration", (inst, def) => {
	$ZodISODuration.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function duration(params) {
	return /* @__PURE__ */ _isoDuration(ZodISODuration, params);
}
//#endregion
//#region node_modules/zod/v4/classic/errors.js
var initializer = (inst, issues) => {
	$ZodError.init(inst, issues);
	inst.name = "ZodError";
	Object.defineProperties(inst, {
		format: { value: (mapper) => formatError(inst, mapper) },
		flatten: { value: (mapper) => flattenError(inst, mapper) },
		addIssue: { value: (issue) => {
			inst.issues.push(issue);
			inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
		} },
		addIssues: { value: (issues) => {
			inst.issues.push(...issues);
			inst.message = JSON.stringify(inst.issues, jsonStringifyReplacer, 2);
		} },
		isEmpty: { get() {
			return inst.issues.length === 0;
		} }
	});
};
var ZodError = /*@__PURE__*/ $constructor("ZodError", initializer);
var ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, { Parent: Error });
//#endregion
//#region node_modules/zod/v4/classic/parse.js
var parse = /* @__PURE__ */ _parse(ZodRealError);
var parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
var safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
var safeParseAsync = /* @__PURE__ */ _safeParseAsync(ZodRealError);
var encode$1 = /* @__PURE__ */ _encode(ZodRealError);
var decode$1 = /* @__PURE__ */ _decode(ZodRealError);
var encodeAsync = /* @__PURE__ */ _encodeAsync(ZodRealError);
var decodeAsync = /* @__PURE__ */ _decodeAsync(ZodRealError);
var safeEncode = /* @__PURE__ */ _safeEncode(ZodRealError);
var safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
var safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
//#endregion
//#region node_modules/zod/v4/classic/schemas.js
var schemas_exports = /* @__PURE__ */ __exportAll({
	ZodAny: () => ZodAny,
	ZodArray: () => ZodArray,
	ZodBase64: () => ZodBase64,
	ZodBase64URL: () => ZodBase64URL,
	ZodBigInt: () => ZodBigInt,
	ZodBigIntFormat: () => ZodBigIntFormat,
	ZodBoolean: () => ZodBoolean,
	ZodCIDRv4: () => ZodCIDRv4,
	ZodCIDRv6: () => ZodCIDRv6,
	ZodCUID: () => ZodCUID,
	ZodCUID2: () => ZodCUID2,
	ZodCatch: () => ZodCatch,
	ZodCodec: () => ZodCodec,
	ZodCustom: () => ZodCustom,
	ZodCustomStringFormat: () => ZodCustomStringFormat,
	ZodDate: () => ZodDate,
	ZodDefault: () => ZodDefault,
	ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
	ZodE164: () => ZodE164,
	ZodEmail: () => ZodEmail,
	ZodEmoji: () => ZodEmoji,
	ZodEnum: () => ZodEnum,
	ZodExactOptional: () => ZodExactOptional,
	ZodFile: () => ZodFile,
	ZodFunction: () => ZodFunction,
	ZodGUID: () => ZodGUID,
	ZodIPv4: () => ZodIPv4,
	ZodIPv6: () => ZodIPv6,
	ZodIntersection: () => ZodIntersection,
	ZodJWT: () => ZodJWT,
	ZodKSUID: () => ZodKSUID,
	ZodLazy: () => ZodLazy,
	ZodLiteral: () => ZodLiteral,
	ZodMAC: () => ZodMAC,
	ZodMap: () => ZodMap,
	ZodNaN: () => ZodNaN,
	ZodNanoID: () => ZodNanoID,
	ZodNever: () => ZodNever,
	ZodNonOptional: () => ZodNonOptional,
	ZodNull: () => ZodNull,
	ZodNullable: () => ZodNullable,
	ZodNumber: () => ZodNumber,
	ZodNumberFormat: () => ZodNumberFormat,
	ZodObject: () => ZodObject,
	ZodOptional: () => ZodOptional,
	ZodPipe: () => ZodPipe,
	ZodPrefault: () => ZodPrefault,
	ZodPreprocess: () => ZodPreprocess,
	ZodPromise: () => ZodPromise,
	ZodReadonly: () => ZodReadonly,
	ZodRecord: () => ZodRecord,
	ZodSet: () => ZodSet,
	ZodString: () => ZodString,
	ZodStringFormat: () => ZodStringFormat,
	ZodSuccess: () => ZodSuccess,
	ZodSymbol: () => ZodSymbol,
	ZodTemplateLiteral: () => ZodTemplateLiteral,
	ZodTransform: () => ZodTransform,
	ZodTuple: () => ZodTuple,
	ZodType: () => ZodType,
	ZodULID: () => ZodULID,
	ZodURL: () => ZodURL,
	ZodUUID: () => ZodUUID,
	ZodUndefined: () => ZodUndefined,
	ZodUnion: () => ZodUnion,
	ZodUnknown: () => ZodUnknown,
	ZodVoid: () => ZodVoid,
	ZodXID: () => ZodXID,
	ZodXor: () => ZodXor,
	_ZodString: () => _ZodString,
	_default: () => _default,
	_function: () => _function,
	any: () => any,
	array: () => array,
	base64: () => base64,
	base64url: () => base64url,
	bigint: () => bigint$1,
	boolean: () => boolean$1,
	catch: () => _catch,
	check: () => check,
	cidrv4: () => cidrv4,
	cidrv6: () => cidrv6,
	codec: () => codec,
	cuid: () => cuid,
	cuid2: () => cuid2,
	custom: () => custom,
	date: () => date$1,
	describe: () => describe,
	discriminatedUnion: () => discriminatedUnion,
	e164: () => e164,
	email: () => email,
	emoji: () => emoji,
	enum: () => _enum,
	exactOptional: () => exactOptional,
	file: () => file,
	float32: () => float32,
	float64: () => float64,
	function: () => _function,
	guid: () => guid,
	hash: () => hash,
	hex: () => hex,
	hostname: () => hostname,
	httpUrl: () => httpUrl,
	instanceof: () => _instanceof,
	int: () => int,
	int32: () => int32,
	int64: () => int64,
	intersection: () => intersection,
	invertCodec: () => invertCodec,
	ipv4: () => ipv4,
	ipv6: () => ipv6,
	json: () => json,
	jwt: () => jwt,
	keyof: () => keyof,
	ksuid: () => ksuid,
	lazy: () => lazy,
	literal: () => literal,
	looseObject: () => looseObject,
	looseRecord: () => looseRecord,
	mac: () => mac,
	map: () => map,
	meta: () => meta,
	nan: () => nan,
	nanoid: () => nanoid,
	nativeEnum: () => nativeEnum,
	never: () => never,
	nonoptional: () => nonoptional,
	null: () => _null,
	nullable: () => nullable,
	nullish: () => nullish,
	number: () => number$1,
	object: () => object,
	optional: () => optional,
	partialRecord: () => partialRecord,
	pipe: () => pipe,
	prefault: () => prefault,
	preprocess: () => preprocess,
	promise: () => promise,
	readonly: () => readonly,
	record: () => record,
	refine: () => refine,
	set: () => set,
	strictObject: () => strictObject,
	string: () => string$1,
	stringFormat: () => stringFormat,
	stringbool: () => stringbool,
	success: () => success,
	superRefine: () => superRefine,
	symbol: () => symbol,
	templateLiteral: () => templateLiteral,
	transform: () => transform,
	tuple: () => tuple,
	uint32: () => uint32,
	uint64: () => uint64,
	ulid: () => ulid,
	undefined: () => _undefined,
	union: () => union,
	unknown: () => unknown,
	url: () => url,
	uuid: () => uuid,
	uuidv4: () => uuidv4,
	uuidv6: () => uuidv6,
	uuidv7: () => uuidv7,
	void: () => _void,
	xid: () => xid,
	xor: () => xor
});
var _installedGroups = /* @__PURE__ */ new WeakMap();
function _installLazyMethods(inst, group, methods) {
	const proto = Object.getPrototypeOf(inst);
	let installed = _installedGroups.get(proto);
	if (!installed) {
		installed = /* @__PURE__ */ new Set();
		_installedGroups.set(proto, installed);
	}
	if (installed.has(group)) return;
	installed.add(group);
	for (const key in methods) {
		const fn = methods[key];
		Object.defineProperty(proto, key, {
			configurable: true,
			enumerable: false,
			get() {
				const bound = fn.bind(this);
				Object.defineProperty(this, key, {
					configurable: true,
					writable: true,
					enumerable: true,
					value: bound
				});
				return bound;
			},
			set(v) {
				Object.defineProperty(this, key, {
					configurable: true,
					writable: true,
					enumerable: true,
					value: v
				});
			}
		});
	}
}
var ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => {
	$ZodType.init(inst, def);
	Object.assign(inst["~standard"], { jsonSchema: {
		input: createStandardJSONSchemaMethod(inst, "input"),
		output: createStandardJSONSchemaMethod(inst, "output")
	} });
	inst.toJSONSchema = createToJSONSchemaMethod(inst, {});
	inst.def = def;
	inst.type = def.type;
	Object.defineProperty(inst, "_def", { value: def });
	inst.parse = (data, params) => parse(inst, data, params, { callee: inst.parse });
	inst.safeParse = (data, params) => safeParse(inst, data, params);
	inst.parseAsync = async (data, params) => parseAsync(inst, data, params, { callee: inst.parseAsync });
	inst.safeParseAsync = async (data, params) => safeParseAsync(inst, data, params);
	inst.spa = inst.safeParseAsync;
	inst.encode = (data, params) => encode$1(inst, data, params);
	inst.decode = (data, params) => decode$1(inst, data, params);
	inst.encodeAsync = async (data, params) => encodeAsync(inst, data, params);
	inst.decodeAsync = async (data, params) => decodeAsync(inst, data, params);
	inst.safeEncode = (data, params) => safeEncode(inst, data, params);
	inst.safeDecode = (data, params) => safeDecode(inst, data, params);
	inst.safeEncodeAsync = async (data, params) => safeEncodeAsync(inst, data, params);
	inst.safeDecodeAsync = async (data, params) => safeDecodeAsync(inst, data, params);
	_installLazyMethods(inst, "ZodType", {
		check(...chks) {
			const def = this.def;
			return this.clone(mergeDefs(def, { checks: [...def.checks ?? [], ...chks.map((ch) => typeof ch === "function" ? { _zod: {
				check: ch,
				def: { check: "custom" },
				onattach: []
			} } : ch)] }), { parent: true });
		},
		with(...chks) {
			return this.check(...chks);
		},
		clone(def, params) {
			return clone(this, def, params);
		},
		brand() {
			return this;
		},
		register(reg, meta) {
			reg.add(this, meta);
			return this;
		},
		refine(check, params) {
			return this.check(refine(check, params));
		},
		superRefine(refinement, params) {
			return this.check(superRefine(refinement, params));
		},
		overwrite(fn) {
			return this.check(/* @__PURE__ */ _overwrite(fn));
		},
		optional() {
			return optional(this);
		},
		exactOptional() {
			return exactOptional(this);
		},
		nullable() {
			return nullable(this);
		},
		nullish() {
			return optional(nullable(this));
		},
		nonoptional(params) {
			return nonoptional(this, params);
		},
		array() {
			return array(this);
		},
		or(arg) {
			return union([this, arg]);
		},
		and(arg) {
			return intersection(this, arg);
		},
		transform(tx) {
			return pipe(this, transform(tx));
		},
		default(d) {
			return _default(this, d);
		},
		prefault(d) {
			return prefault(this, d);
		},
		catch(params) {
			return _catch(this, params);
		},
		pipe(target) {
			return pipe(this, target);
		},
		readonly() {
			return readonly(this);
		},
		describe(description) {
			const cl = this.clone();
			globalRegistry.add(cl, { description });
			return cl;
		},
		meta(...args) {
			if (args.length === 0) return globalRegistry.get(this);
			const cl = this.clone();
			globalRegistry.add(cl, args[0]);
			return cl;
		},
		isOptional() {
			return this.safeParse(void 0).success;
		},
		isNullable() {
			return this.safeParse(null).success;
		},
		apply(fn) {
			return fn(this);
		}
	});
	Object.defineProperty(inst, "description", {
		get() {
			return globalRegistry.get(inst)?.description;
		},
		configurable: true
	});
	return inst;
});
/** @internal */
var _ZodString = /*@__PURE__*/ $constructor("_ZodString", (inst, def) => {
	$ZodString.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => stringProcessor(inst, ctx, json, params);
	const bag = inst._zod.bag;
	inst.format = bag.format ?? null;
	inst.minLength = bag.minimum ?? null;
	inst.maxLength = bag.maximum ?? null;
	_installLazyMethods(inst, "_ZodString", {
		regex(...args) {
			return this.check(/* @__PURE__ */ _regex(...args));
		},
		includes(...args) {
			return this.check(/* @__PURE__ */ _includes(...args));
		},
		startsWith(...args) {
			return this.check(/* @__PURE__ */ _startsWith(...args));
		},
		endsWith(...args) {
			return this.check(/* @__PURE__ */ _endsWith(...args));
		},
		min(...args) {
			return this.check(/* @__PURE__ */ _minLength(...args));
		},
		max(...args) {
			return this.check(/* @__PURE__ */ _maxLength(...args));
		},
		length(...args) {
			return this.check(/* @__PURE__ */ _length(...args));
		},
		nonempty(...args) {
			return this.check(/* @__PURE__ */ _minLength(1, ...args));
		},
		lowercase(params) {
			return this.check(/* @__PURE__ */ _lowercase(params));
		},
		uppercase(params) {
			return this.check(/* @__PURE__ */ _uppercase(params));
		},
		trim() {
			return this.check(/* @__PURE__ */ _trim());
		},
		normalize(...args) {
			return this.check(/* @__PURE__ */ _normalize(...args));
		},
		toLowerCase() {
			return this.check(/* @__PURE__ */ _toLowerCase());
		},
		toUpperCase() {
			return this.check(/* @__PURE__ */ _toUpperCase());
		},
		slugify() {
			return this.check(/* @__PURE__ */ _slugify());
		}
	});
});
var ZodString = /*@__PURE__*/ $constructor("ZodString", (inst, def) => {
	$ZodString.init(inst, def);
	_ZodString.init(inst, def);
	inst.email = (params) => inst.check(/* @__PURE__ */ _email(ZodEmail, params));
	inst.url = (params) => inst.check(/* @__PURE__ */ _url(ZodURL, params));
	inst.jwt = (params) => inst.check(/* @__PURE__ */ _jwt(ZodJWT, params));
	inst.emoji = (params) => inst.check(/* @__PURE__ */ _emoji(ZodEmoji, params));
	inst.guid = (params) => inst.check(/* @__PURE__ */ _guid(ZodGUID, params));
	inst.uuid = (params) => inst.check(/* @__PURE__ */ _uuid(ZodUUID, params));
	inst.uuidv4 = (params) => inst.check(/* @__PURE__ */ _uuidv4(ZodUUID, params));
	inst.uuidv6 = (params) => inst.check(/* @__PURE__ */ _uuidv6(ZodUUID, params));
	inst.uuidv7 = (params) => inst.check(/* @__PURE__ */ _uuidv7(ZodUUID, params));
	inst.nanoid = (params) => inst.check(/* @__PURE__ */ _nanoid(ZodNanoID, params));
	inst.guid = (params) => inst.check(/* @__PURE__ */ _guid(ZodGUID, params));
	inst.cuid = (params) => inst.check(/* @__PURE__ */ _cuid(ZodCUID, params));
	inst.cuid2 = (params) => inst.check(/* @__PURE__ */ _cuid2(ZodCUID2, params));
	inst.ulid = (params) => inst.check(/* @__PURE__ */ _ulid(ZodULID, params));
	inst.base64 = (params) => inst.check(/* @__PURE__ */ _base64(ZodBase64, params));
	inst.base64url = (params) => inst.check(/* @__PURE__ */ _base64url(ZodBase64URL, params));
	inst.xid = (params) => inst.check(/* @__PURE__ */ _xid(ZodXID, params));
	inst.ksuid = (params) => inst.check(/* @__PURE__ */ _ksuid(ZodKSUID, params));
	inst.ipv4 = (params) => inst.check(/* @__PURE__ */ _ipv4(ZodIPv4, params));
	inst.ipv6 = (params) => inst.check(/* @__PURE__ */ _ipv6(ZodIPv6, params));
	inst.cidrv4 = (params) => inst.check(/* @__PURE__ */ _cidrv4(ZodCIDRv4, params));
	inst.cidrv6 = (params) => inst.check(/* @__PURE__ */ _cidrv6(ZodCIDRv6, params));
	inst.e164 = (params) => inst.check(/* @__PURE__ */ _e164(ZodE164, params));
	inst.datetime = (params) => inst.check(datetime(params));
	inst.date = (params) => inst.check(date$2(params));
	inst.time = (params) => inst.check(time(params));
	inst.duration = (params) => inst.check(duration(params));
});
function string$1(params) {
	return /* @__PURE__ */ _string(ZodString, params);
}
var ZodStringFormat = /*@__PURE__*/ $constructor("ZodStringFormat", (inst, def) => {
	$ZodStringFormat.init(inst, def);
	_ZodString.init(inst, def);
});
var ZodEmail = /*@__PURE__*/ $constructor("ZodEmail", (inst, def) => {
	$ZodEmail.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function email(params) {
	return /* @__PURE__ */ _email(ZodEmail, params);
}
var ZodGUID = /*@__PURE__*/ $constructor("ZodGUID", (inst, def) => {
	$ZodGUID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function guid(params) {
	return /* @__PURE__ */ _guid(ZodGUID, params);
}
var ZodUUID = /*@__PURE__*/ $constructor("ZodUUID", (inst, def) => {
	$ZodUUID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function uuid(params) {
	return /* @__PURE__ */ _uuid(ZodUUID, params);
}
function uuidv4(params) {
	return /* @__PURE__ */ _uuidv4(ZodUUID, params);
}
function uuidv6(params) {
	return /* @__PURE__ */ _uuidv6(ZodUUID, params);
}
function uuidv7(params) {
	return /* @__PURE__ */ _uuidv7(ZodUUID, params);
}
var ZodURL = /*@__PURE__*/ $constructor("ZodURL", (inst, def) => {
	$ZodURL.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function url(params) {
	return /* @__PURE__ */ _url(ZodURL, params);
}
function httpUrl(params) {
	return /* @__PURE__ */ _url(ZodURL, {
		protocol: httpProtocol,
		hostname: domain,
		...normalizeParams(params)
	});
}
var ZodEmoji = /*@__PURE__*/ $constructor("ZodEmoji", (inst, def) => {
	$ZodEmoji.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function emoji(params) {
	return /* @__PURE__ */ _emoji(ZodEmoji, params);
}
var ZodNanoID = /*@__PURE__*/ $constructor("ZodNanoID", (inst, def) => {
	$ZodNanoID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function nanoid(params) {
	return /* @__PURE__ */ _nanoid(ZodNanoID, params);
}
/**
* @deprecated CUID v1 is deprecated by its authors due to information leakage
* (timestamps embedded in the id). Use {@link ZodCUID2} instead.
* See https://github.com/paralleldrive/cuid.
*/
var ZodCUID = /*@__PURE__*/ $constructor("ZodCUID", (inst, def) => {
	$ZodCUID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
/**
* Validates a CUID v1 string.
*
* @deprecated CUID v1 is deprecated by its authors due to information leakage
* (timestamps embedded in the id). Use {@link cuid2 | `z.cuid2()`} instead.
* See https://github.com/paralleldrive/cuid.
*/
function cuid(params) {
	return /* @__PURE__ */ _cuid(ZodCUID, params);
}
var ZodCUID2 = /*@__PURE__*/ $constructor("ZodCUID2", (inst, def) => {
	$ZodCUID2.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function cuid2(params) {
	return /* @__PURE__ */ _cuid2(ZodCUID2, params);
}
var ZodULID = /*@__PURE__*/ $constructor("ZodULID", (inst, def) => {
	$ZodULID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function ulid(params) {
	return /* @__PURE__ */ _ulid(ZodULID, params);
}
var ZodXID = /*@__PURE__*/ $constructor("ZodXID", (inst, def) => {
	$ZodXID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function xid(params) {
	return /* @__PURE__ */ _xid(ZodXID, params);
}
var ZodKSUID = /*@__PURE__*/ $constructor("ZodKSUID", (inst, def) => {
	$ZodKSUID.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function ksuid(params) {
	return /* @__PURE__ */ _ksuid(ZodKSUID, params);
}
var ZodIPv4 = /*@__PURE__*/ $constructor("ZodIPv4", (inst, def) => {
	$ZodIPv4.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function ipv4(params) {
	return /* @__PURE__ */ _ipv4(ZodIPv4, params);
}
var ZodMAC = /*@__PURE__*/ $constructor("ZodMAC", (inst, def) => {
	$ZodMAC.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function mac(params) {
	return /* @__PURE__ */ _mac(ZodMAC, params);
}
var ZodIPv6 = /*@__PURE__*/ $constructor("ZodIPv6", (inst, def) => {
	$ZodIPv6.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function ipv6(params) {
	return /* @__PURE__ */ _ipv6(ZodIPv6, params);
}
var ZodCIDRv4 = /*@__PURE__*/ $constructor("ZodCIDRv4", (inst, def) => {
	$ZodCIDRv4.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function cidrv4(params) {
	return /* @__PURE__ */ _cidrv4(ZodCIDRv4, params);
}
var ZodCIDRv6 = /*@__PURE__*/ $constructor("ZodCIDRv6", (inst, def) => {
	$ZodCIDRv6.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function cidrv6(params) {
	return /* @__PURE__ */ _cidrv6(ZodCIDRv6, params);
}
var ZodBase64 = /*@__PURE__*/ $constructor("ZodBase64", (inst, def) => {
	$ZodBase64.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function base64(params) {
	return /* @__PURE__ */ _base64(ZodBase64, params);
}
var ZodBase64URL = /*@__PURE__*/ $constructor("ZodBase64URL", (inst, def) => {
	$ZodBase64URL.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function base64url(params) {
	return /* @__PURE__ */ _base64url(ZodBase64URL, params);
}
var ZodE164 = /*@__PURE__*/ $constructor("ZodE164", (inst, def) => {
	$ZodE164.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function e164(params) {
	return /* @__PURE__ */ _e164(ZodE164, params);
}
var ZodJWT = /*@__PURE__*/ $constructor("ZodJWT", (inst, def) => {
	$ZodJWT.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function jwt(params) {
	return /* @__PURE__ */ _jwt(ZodJWT, params);
}
var ZodCustomStringFormat = /*@__PURE__*/ $constructor("ZodCustomStringFormat", (inst, def) => {
	$ZodCustomStringFormat.init(inst, def);
	ZodStringFormat.init(inst, def);
});
function stringFormat(format, fnOrRegex, _params = {}) {
	return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);
}
function hostname(_params) {
	return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, "hostname", hostname$1, _params);
}
function hex(_params) {
	return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, "hex", hex$1, _params);
}
function hash(alg, params) {
	const format = `${alg}_${params?.enc ?? "hex"}`;
	const regex = regexes_exports[format];
	if (!regex) throw new Error(`Unrecognized hash format: ${format}`);
	return /* @__PURE__ */ _stringFormat(ZodCustomStringFormat, format, regex, params);
}
var ZodNumber = /*@__PURE__*/ $constructor("ZodNumber", (inst, def) => {
	$ZodNumber.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => numberProcessor(inst, ctx, json, params);
	_installLazyMethods(inst, "ZodNumber", {
		gt(value, params) {
			return this.check(/* @__PURE__ */ _gt(value, params));
		},
		gte(value, params) {
			return this.check(/* @__PURE__ */ _gte(value, params));
		},
		min(value, params) {
			return this.check(/* @__PURE__ */ _gte(value, params));
		},
		lt(value, params) {
			return this.check(/* @__PURE__ */ _lt(value, params));
		},
		lte(value, params) {
			return this.check(/* @__PURE__ */ _lte(value, params));
		},
		max(value, params) {
			return this.check(/* @__PURE__ */ _lte(value, params));
		},
		int(params) {
			return this.check(int(params));
		},
		safe(params) {
			return this.check(int(params));
		},
		positive(params) {
			return this.check(/* @__PURE__ */ _gt(0, params));
		},
		nonnegative(params) {
			return this.check(/* @__PURE__ */ _gte(0, params));
		},
		negative(params) {
			return this.check(/* @__PURE__ */ _lt(0, params));
		},
		nonpositive(params) {
			return this.check(/* @__PURE__ */ _lte(0, params));
		},
		multipleOf(value, params) {
			return this.check(/* @__PURE__ */ _multipleOf(value, params));
		},
		step(value, params) {
			return this.check(/* @__PURE__ */ _multipleOf(value, params));
		},
		finite() {
			return this;
		}
	});
	const bag = inst._zod.bag;
	inst.minValue = Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null;
	inst.maxValue = Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null;
	inst.isInt = (bag.format ?? "").includes("int") || Number.isSafeInteger(bag.multipleOf ?? .5);
	inst.isFinite = true;
	inst.format = bag.format ?? null;
});
function number$1(params) {
	return /* @__PURE__ */ _number(ZodNumber, params);
}
var ZodNumberFormat = /*@__PURE__*/ $constructor("ZodNumberFormat", (inst, def) => {
	$ZodNumberFormat.init(inst, def);
	ZodNumber.init(inst, def);
});
function int(params) {
	return /* @__PURE__ */ _int(ZodNumberFormat, params);
}
function float32(params) {
	return /* @__PURE__ */ _float32(ZodNumberFormat, params);
}
function float64(params) {
	return /* @__PURE__ */ _float64(ZodNumberFormat, params);
}
function int32(params) {
	return /* @__PURE__ */ _int32(ZodNumberFormat, params);
}
function uint32(params) {
	return /* @__PURE__ */ _uint32(ZodNumberFormat, params);
}
var ZodBoolean = /*@__PURE__*/ $constructor("ZodBoolean", (inst, def) => {
	$ZodBoolean.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => booleanProcessor(inst, ctx, json, params);
});
function boolean$1(params) {
	return /* @__PURE__ */ _boolean(ZodBoolean, params);
}
var ZodBigInt = /*@__PURE__*/ $constructor("ZodBigInt", (inst, def) => {
	$ZodBigInt.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => bigintProcessor(inst, ctx, json, params);
	inst.gte = (value, params) => inst.check(/* @__PURE__ */ _gte(value, params));
	inst.min = (value, params) => inst.check(/* @__PURE__ */ _gte(value, params));
	inst.gt = (value, params) => inst.check(/* @__PURE__ */ _gt(value, params));
	inst.gte = (value, params) => inst.check(/* @__PURE__ */ _gte(value, params));
	inst.min = (value, params) => inst.check(/* @__PURE__ */ _gte(value, params));
	inst.lt = (value, params) => inst.check(/* @__PURE__ */ _lt(value, params));
	inst.lte = (value, params) => inst.check(/* @__PURE__ */ _lte(value, params));
	inst.max = (value, params) => inst.check(/* @__PURE__ */ _lte(value, params));
	inst.positive = (params) => inst.check(/* @__PURE__ */ _gt(BigInt(0), params));
	inst.negative = (params) => inst.check(/* @__PURE__ */ _lt(BigInt(0), params));
	inst.nonpositive = (params) => inst.check(/* @__PURE__ */ _lte(BigInt(0), params));
	inst.nonnegative = (params) => inst.check(/* @__PURE__ */ _gte(BigInt(0), params));
	inst.multipleOf = (value, params) => inst.check(/* @__PURE__ */ _multipleOf(value, params));
	const bag = inst._zod.bag;
	inst.minValue = bag.minimum ?? null;
	inst.maxValue = bag.maximum ?? null;
	inst.format = bag.format ?? null;
});
function bigint$1(params) {
	return /* @__PURE__ */ _bigint(ZodBigInt, params);
}
var ZodBigIntFormat = /*@__PURE__*/ $constructor("ZodBigIntFormat", (inst, def) => {
	$ZodBigIntFormat.init(inst, def);
	ZodBigInt.init(inst, def);
});
function int64(params) {
	return /* @__PURE__ */ _int64(ZodBigIntFormat, params);
}
function uint64(params) {
	return /* @__PURE__ */ _uint64(ZodBigIntFormat, params);
}
var ZodSymbol = /*@__PURE__*/ $constructor("ZodSymbol", (inst, def) => {
	$ZodSymbol.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => symbolProcessor(inst, ctx, json, params);
});
function symbol(params) {
	return /* @__PURE__ */ _symbol(ZodSymbol, params);
}
var ZodUndefined = /*@__PURE__*/ $constructor("ZodUndefined", (inst, def) => {
	$ZodUndefined.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => undefinedProcessor(inst, ctx, json, params);
});
function _undefined(params) {
	return /* @__PURE__ */ _undefined$1(ZodUndefined, params);
}
var ZodNull = /*@__PURE__*/ $constructor("ZodNull", (inst, def) => {
	$ZodNull.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => nullProcessor(inst, ctx, json, params);
});
function _null(params) {
	return /* @__PURE__ */ _null$1(ZodNull, params);
}
var ZodAny = /*@__PURE__*/ $constructor("ZodAny", (inst, def) => {
	$ZodAny.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => void 0;
});
function any() {
	return /* @__PURE__ */ _any(ZodAny);
}
var ZodUnknown = /*@__PURE__*/ $constructor("ZodUnknown", (inst, def) => {
	$ZodUnknown.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => void 0;
});
function unknown() {
	return /* @__PURE__ */ _unknown(ZodUnknown);
}
var ZodNever = /*@__PURE__*/ $constructor("ZodNever", (inst, def) => {
	$ZodNever.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => neverProcessor(inst, ctx, json, params);
});
function never(params) {
	return /* @__PURE__ */ _never(ZodNever, params);
}
var ZodVoid = /*@__PURE__*/ $constructor("ZodVoid", (inst, def) => {
	$ZodVoid.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => voidProcessor(inst, ctx, json, params);
});
function _void(params) {
	return /* @__PURE__ */ _void$1(ZodVoid, params);
}
var ZodDate = /*@__PURE__*/ $constructor("ZodDate", (inst, def) => {
	$ZodDate.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => dateProcessor(inst, ctx, json, params);
	inst.min = (value, params) => inst.check(/* @__PURE__ */ _gte(value, params));
	inst.max = (value, params) => inst.check(/* @__PURE__ */ _lte(value, params));
	const c = inst._zod.bag;
	inst.minDate = c.minimum ? new Date(c.minimum) : null;
	inst.maxDate = c.maximum ? new Date(c.maximum) : null;
});
function date$1(params) {
	return /* @__PURE__ */ _date(ZodDate, params);
}
var ZodArray = /*@__PURE__*/ $constructor("ZodArray", (inst, def) => {
	$ZodArray.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => arrayProcessor(inst, ctx, json, params);
	inst.element = def.element;
	_installLazyMethods(inst, "ZodArray", {
		min(n, params) {
			return this.check(/* @__PURE__ */ _minLength(n, params));
		},
		nonempty(params) {
			return this.check(/* @__PURE__ */ _minLength(1, params));
		},
		max(n, params) {
			return this.check(/* @__PURE__ */ _maxLength(n, params));
		},
		length(n, params) {
			return this.check(/* @__PURE__ */ _length(n, params));
		},
		unwrap() {
			return this.element;
		}
	});
});
function array(element, params) {
	return /* @__PURE__ */ _array(ZodArray, element, params);
}
function keyof(schema) {
	const shape = schema._zod.def.shape;
	return _enum(Object.keys(shape));
}
var ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => {
	$ZodObjectJIT.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => objectProcessor(inst, ctx, json, params);
	defineLazy(inst, "shape", () => {
		return def.shape;
	});
	_installLazyMethods(inst, "ZodObject", {
		keyof() {
			return _enum(Object.keys(this._zod.def.shape));
		},
		catchall(catchall) {
			return this.clone({
				...this._zod.def,
				catchall
			});
		},
		passthrough() {
			return this.clone({
				...this._zod.def,
				catchall: unknown()
			});
		},
		loose() {
			return this.clone({
				...this._zod.def,
				catchall: unknown()
			});
		},
		strict() {
			return this.clone({
				...this._zod.def,
				catchall: never()
			});
		},
		strip() {
			return this.clone({
				...this._zod.def,
				catchall: void 0
			});
		},
		extend(incoming) {
			return extend(this, incoming);
		},
		safeExtend(incoming) {
			return safeExtend(this, incoming);
		},
		merge(other) {
			return merge(this, other);
		},
		pick(mask) {
			return pick(this, mask);
		},
		omit(mask) {
			return omit(this, mask);
		},
		partial(...args) {
			return partial(ZodOptional, this, args[0]);
		},
		required(...args) {
			return required(ZodNonOptional, this, args[0]);
		}
	});
});
function object(shape, params) {
	return new ZodObject({
		type: "object",
		shape: shape ?? {},
		...normalizeParams(params)
	});
}
function strictObject(shape, params) {
	return new ZodObject({
		type: "object",
		shape,
		catchall: never(),
		...normalizeParams(params)
	});
}
function looseObject(shape, params) {
	return new ZodObject({
		type: "object",
		shape,
		catchall: unknown(),
		...normalizeParams(params)
	});
}
var ZodUnion = /*@__PURE__*/ $constructor("ZodUnion", (inst, def) => {
	$ZodUnion.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => unionProcessor(inst, ctx, json, params);
	inst.options = def.options;
});
function union(options, params) {
	return new ZodUnion({
		type: "union",
		options,
		...normalizeParams(params)
	});
}
var ZodXor = /*@__PURE__*/ $constructor("ZodXor", (inst, def) => {
	ZodUnion.init(inst, def);
	$ZodXor.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => unionProcessor(inst, ctx, json, params);
	inst.options = def.options;
});
/** Creates an exclusive union (XOR) where exactly one option must match.
* Unlike regular unions that succeed when any option matches, xor fails if
* zero or more than one option matches the input. */
function xor(options, params) {
	return new ZodXor({
		type: "union",
		options,
		inclusive: false,
		...normalizeParams(params)
	});
}
var ZodDiscriminatedUnion = /*@__PURE__*/ $constructor("ZodDiscriminatedUnion", (inst, def) => {
	ZodUnion.init(inst, def);
	$ZodDiscriminatedUnion.init(inst, def);
});
function discriminatedUnion(discriminator, options, params) {
	return new ZodDiscriminatedUnion({
		type: "union",
		options,
		discriminator,
		...normalizeParams(params)
	});
}
var ZodIntersection = /*@__PURE__*/ $constructor("ZodIntersection", (inst, def) => {
	$ZodIntersection.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => intersectionProcessor(inst, ctx, json, params);
});
function intersection(left, right) {
	return new ZodIntersection({
		type: "intersection",
		left,
		right
	});
}
var ZodTuple = /*@__PURE__*/ $constructor("ZodTuple", (inst, def) => {
	$ZodTuple.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => tupleProcessor(inst, ctx, json, params);
	inst.rest = (rest) => inst.clone({
		...inst._zod.def,
		rest
	});
});
function tuple(items, _paramsOrRest, _params) {
	const hasRest = _paramsOrRest instanceof $ZodType;
	return new ZodTuple({
		type: "tuple",
		items,
		rest: hasRest ? _paramsOrRest : null,
		...normalizeParams(hasRest ? _params : _paramsOrRest)
	});
}
var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
	$ZodRecord.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
	inst.keyType = def.keyType;
	inst.valueType = def.valueType;
});
function record(keyType, valueType, params) {
	if (!valueType || !valueType._zod) return new ZodRecord({
		type: "record",
		keyType: string$1(),
		valueType: keyType,
		...normalizeParams(valueType)
	});
	return new ZodRecord({
		type: "record",
		keyType,
		valueType,
		...normalizeParams(params)
	});
}
function partialRecord(keyType, valueType, params) {
	const k = clone(keyType);
	k._zod.values = void 0;
	return new ZodRecord({
		type: "record",
		keyType: k,
		valueType,
		...normalizeParams(params)
	});
}
function looseRecord(keyType, valueType, params) {
	return new ZodRecord({
		type: "record",
		keyType,
		valueType,
		mode: "loose",
		...normalizeParams(params)
	});
}
var ZodMap = /*@__PURE__*/ $constructor("ZodMap", (inst, def) => {
	$ZodMap.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => mapProcessor(inst, ctx, json, params);
	inst.keyType = def.keyType;
	inst.valueType = def.valueType;
	inst.min = (...args) => inst.check(/* @__PURE__ */ _minSize(...args));
	inst.nonempty = (params) => inst.check(/* @__PURE__ */ _minSize(1, params));
	inst.max = (...args) => inst.check(/* @__PURE__ */ _maxSize(...args));
	inst.size = (...args) => inst.check(/* @__PURE__ */ _size(...args));
});
function map(keyType, valueType, params) {
	return new ZodMap({
		type: "map",
		keyType,
		valueType,
		...normalizeParams(params)
	});
}
var ZodSet = /*@__PURE__*/ $constructor("ZodSet", (inst, def) => {
	$ZodSet.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => setProcessor(inst, ctx, json, params);
	inst.min = (...args) => inst.check(/* @__PURE__ */ _minSize(...args));
	inst.nonempty = (params) => inst.check(/* @__PURE__ */ _minSize(1, params));
	inst.max = (...args) => inst.check(/* @__PURE__ */ _maxSize(...args));
	inst.size = (...args) => inst.check(/* @__PURE__ */ _size(...args));
});
function set(valueType, params) {
	return new ZodSet({
		type: "set",
		valueType,
		...normalizeParams(params)
	});
}
var ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
	$ZodEnum.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => enumProcessor(inst, ctx, json, params);
	inst.enum = def.entries;
	inst.options = Object.values(def.entries);
	const keys = new Set(Object.keys(def.entries));
	inst.extract = (values, params) => {
		const newEntries = {};
		for (const value of values) if (keys.has(value)) newEntries[value] = def.entries[value];
		else throw new Error(`Key ${value} not found in enum`);
		return new ZodEnum({
			...def,
			checks: [],
			...normalizeParams(params),
			entries: newEntries
		});
	};
	inst.exclude = (values, params) => {
		const newEntries = { ...def.entries };
		for (const value of values) if (keys.has(value)) delete newEntries[value];
		else throw new Error(`Key ${value} not found in enum`);
		return new ZodEnum({
			...def,
			checks: [],
			...normalizeParams(params),
			entries: newEntries
		});
	};
});
function _enum(values, params) {
	return new ZodEnum({
		type: "enum",
		entries: Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values,
		...normalizeParams(params)
	});
}
/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.
*
* ```ts
* enum Colors { red, green, blue }
* z.enum(Colors);
* ```
*/
function nativeEnum(entries, params) {
	return new ZodEnum({
		type: "enum",
		entries,
		...normalizeParams(params)
	});
}
var ZodLiteral = /*@__PURE__*/ $constructor("ZodLiteral", (inst, def) => {
	$ZodLiteral.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => literalProcessor(inst, ctx, json, params);
	inst.values = new Set(def.values);
	Object.defineProperty(inst, "value", { get() {
		if (def.values.length > 1) throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");
		return def.values[0];
	} });
});
function literal(value, params) {
	return new ZodLiteral({
		type: "literal",
		values: Array.isArray(value) ? value : [value],
		...normalizeParams(params)
	});
}
var ZodFile = /*@__PURE__*/ $constructor("ZodFile", (inst, def) => {
	$ZodFile.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => fileProcessor(inst, ctx, json, params);
	inst.min = (size, params) => inst.check(/* @__PURE__ */ _minSize(size, params));
	inst.max = (size, params) => inst.check(/* @__PURE__ */ _maxSize(size, params));
	inst.mime = (types, params) => inst.check(/* @__PURE__ */ _mime(Array.isArray(types) ? types : [types], params));
});
function file(params) {
	return /* @__PURE__ */ _file(ZodFile, params);
}
var ZodTransform = /*@__PURE__*/ $constructor("ZodTransform", (inst, def) => {
	$ZodTransform.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => transformProcessor(inst, ctx, json, params);
	inst._zod.parse = (payload, _ctx) => {
		if (_ctx.direction === "backward") throw new $ZodEncodeError(inst.constructor.name);
		payload.addIssue = (issue$1) => {
			if (typeof issue$1 === "string") payload.issues.push(issue(issue$1, payload.value, def));
			else {
				const _issue = issue$1;
				if (_issue.fatal) _issue.continue = false;
				_issue.code ?? (_issue.code = "custom");
				_issue.input ?? (_issue.input = payload.value);
				_issue.inst ?? (_issue.inst = inst);
				payload.issues.push(issue(_issue));
			}
		};
		const output = def.transform(payload.value, payload);
		if (output instanceof Promise) return output.then((output) => {
			payload.value = output;
			payload.fallback = true;
			return payload;
		});
		payload.value = output;
		payload.fallback = true;
		return payload;
	};
});
function transform(fn) {
	return new ZodTransform({
		type: "transform",
		transform: fn
	});
}
var ZodOptional = /*@__PURE__*/ $constructor("ZodOptional", (inst, def) => {
	$ZodOptional.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => optionalProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function optional(innerType) {
	return new ZodOptional({
		type: "optional",
		innerType
	});
}
var ZodExactOptional = /*@__PURE__*/ $constructor("ZodExactOptional", (inst, def) => {
	$ZodExactOptional.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => optionalProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function exactOptional(innerType) {
	return new ZodExactOptional({
		type: "optional",
		innerType
	});
}
var ZodNullable = /*@__PURE__*/ $constructor("ZodNullable", (inst, def) => {
	$ZodNullable.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => nullableProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function nullable(innerType) {
	return new ZodNullable({
		type: "nullable",
		innerType
	});
}
function nullish(innerType) {
	return optional(nullable(innerType));
}
var ZodDefault = /*@__PURE__*/ $constructor("ZodDefault", (inst, def) => {
	$ZodDefault.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => defaultProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
	inst.removeDefault = inst.unwrap;
});
function _default(innerType, defaultValue) {
	return new ZodDefault({
		type: "default",
		innerType,
		get defaultValue() {
			return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue);
		}
	});
}
var ZodPrefault = /*@__PURE__*/ $constructor("ZodPrefault", (inst, def) => {
	$ZodPrefault.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => prefaultProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function prefault(innerType, defaultValue) {
	return new ZodPrefault({
		type: "prefault",
		innerType,
		get defaultValue() {
			return typeof defaultValue === "function" ? defaultValue() : shallowClone(defaultValue);
		}
	});
}
var ZodNonOptional = /*@__PURE__*/ $constructor("ZodNonOptional", (inst, def) => {
	$ZodNonOptional.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => nonoptionalProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function nonoptional(innerType, params) {
	return new ZodNonOptional({
		type: "nonoptional",
		innerType,
		...normalizeParams(params)
	});
}
var ZodSuccess = /*@__PURE__*/ $constructor("ZodSuccess", (inst, def) => {
	$ZodSuccess.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => successProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function success(innerType) {
	return new ZodSuccess({
		type: "success",
		innerType
	});
}
var ZodCatch = /*@__PURE__*/ $constructor("ZodCatch", (inst, def) => {
	$ZodCatch.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => catchProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
	inst.removeCatch = inst.unwrap;
});
function _catch(innerType, catchValue) {
	return new ZodCatch({
		type: "catch",
		innerType,
		catchValue: typeof catchValue === "function" ? catchValue : () => catchValue
	});
}
var ZodNaN = /*@__PURE__*/ $constructor("ZodNaN", (inst, def) => {
	$ZodNaN.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => nanProcessor(inst, ctx, json, params);
});
function nan(params) {
	return /* @__PURE__ */ _nan(ZodNaN, params);
}
var ZodPipe = /*@__PURE__*/ $constructor("ZodPipe", (inst, def) => {
	$ZodPipe.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => pipeProcessor(inst, ctx, json, params);
	inst.in = def.in;
	inst.out = def.out;
});
function pipe(in_, out) {
	return new ZodPipe({
		type: "pipe",
		in: in_,
		out
	});
}
var ZodCodec = /*@__PURE__*/ $constructor("ZodCodec", (inst, def) => {
	ZodPipe.init(inst, def);
	$ZodCodec.init(inst, def);
});
function codec(in_, out, params) {
	return new ZodCodec({
		type: "pipe",
		in: in_,
		out,
		transform: params.decode,
		reverseTransform: params.encode
	});
}
function invertCodec(codec) {
	const def = codec._zod.def;
	return new ZodCodec({
		type: "pipe",
		in: def.out,
		out: def.in,
		transform: def.reverseTransform,
		reverseTransform: def.transform
	});
}
var ZodPreprocess = /*@__PURE__*/ $constructor("ZodPreprocess", (inst, def) => {
	ZodPipe.init(inst, def);
	$ZodPreprocess.init(inst, def);
});
var ZodReadonly = /*@__PURE__*/ $constructor("ZodReadonly", (inst, def) => {
	$ZodReadonly.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => readonlyProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function readonly(innerType) {
	return new ZodReadonly({
		type: "readonly",
		innerType
	});
}
var ZodTemplateLiteral = /*@__PURE__*/ $constructor("ZodTemplateLiteral", (inst, def) => {
	$ZodTemplateLiteral.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => templateLiteralProcessor(inst, ctx, json, params);
});
function templateLiteral(parts, params) {
	return new ZodTemplateLiteral({
		type: "template_literal",
		parts,
		...normalizeParams(params)
	});
}
var ZodLazy = /*@__PURE__*/ $constructor("ZodLazy", (inst, def) => {
	$ZodLazy.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => lazyProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.getter();
});
function lazy(getter) {
	return new ZodLazy({
		type: "lazy",
		getter
	});
}
var ZodPromise = /*@__PURE__*/ $constructor("ZodPromise", (inst, def) => {
	$ZodPromise.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => promiseProcessor(inst, ctx, json, params);
	inst.unwrap = () => inst._zod.def.innerType;
});
function promise(innerType) {
	return new ZodPromise({
		type: "promise",
		innerType
	});
}
var ZodFunction = /*@__PURE__*/ $constructor("ZodFunction", (inst, def) => {
	$ZodFunction.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => functionProcessor(inst, ctx, json, params);
});
function _function(params) {
	return new ZodFunction({
		type: "function",
		input: Array.isArray(params?.input) ? tuple(params?.input) : params?.input ?? array(unknown()),
		output: params?.output ?? unknown()
	});
}
var ZodCustom = /*@__PURE__*/ $constructor("ZodCustom", (inst, def) => {
	$ZodCustom.init(inst, def);
	ZodType.init(inst, def);
	inst._zod.processJSONSchema = (ctx, json, params) => customProcessor(inst, ctx, json, params);
});
function check(fn) {
	const ch = new $ZodCheck({ check: "custom" });
	ch._zod.check = fn;
	return ch;
}
function custom(fn, _params) {
	return /* @__PURE__ */ _custom(ZodCustom, fn ?? (() => true), _params);
}
function refine(fn, _params = {}) {
	return /* @__PURE__ */ _refine(ZodCustom, fn, _params);
}
function superRefine(fn, params) {
	return /* @__PURE__ */ _superRefine(fn, params);
}
var describe = describe$1;
var meta = meta$1;
function _instanceof(cls, params = {}) {
	const inst = new ZodCustom({
		type: "custom",
		check: "custom",
		fn: (data) => data instanceof cls,
		abort: true,
		...normalizeParams(params)
	});
	inst._zod.bag.Class = cls;
	inst._zod.check = (payload) => {
		if (!(payload.value instanceof cls)) payload.issues.push({
			code: "invalid_type",
			expected: cls.name,
			input: payload.value,
			inst,
			path: [...inst._zod.def.path ?? []]
		});
	};
	return inst;
}
var stringbool = (...args) => /* @__PURE__ */ _stringbool({
	Codec: ZodCodec,
	Boolean: ZodBoolean,
	String: ZodString
}, ...args);
function json(params) {
	const jsonSchema = lazy(() => {
		return union([
			string$1(params),
			number$1(),
			boolean$1(),
			_null(),
			array(jsonSchema),
			record(string$1(), jsonSchema)
		]);
	});
	return jsonSchema;
}
function preprocess(fn, schema) {
	return new ZodPreprocess({
		type: "pipe",
		in: transform(fn),
		out: schema
	});
}
//#endregion
//#region node_modules/zod/v4/classic/compat.js
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
var ZodIssueCode = {
	invalid_type: "invalid_type",
	too_big: "too_big",
	too_small: "too_small",
	invalid_format: "invalid_format",
	not_multiple_of: "not_multiple_of",
	unrecognized_keys: "unrecognized_keys",
	invalid_union: "invalid_union",
	invalid_key: "invalid_key",
	invalid_element: "invalid_element",
	invalid_value: "invalid_value",
	custom: "custom"
};
/** @deprecated Use `z.config(params)` instead. */
function setErrorMap(map) {
	config({ customError: map });
}
/** @deprecated Use `z.config()` instead. */
function getErrorMap() {
	return config().customError;
}
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
var ZodFirstPartyTypeKind;
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
//#endregion
//#region node_modules/zod/v4/classic/from-json-schema.js
var z = {
	...schemas_exports,
	...checks_exports,
	iso: iso_exports
};
var RECOGNIZED_KEYS = /*@__PURE__*/ new Set([
	"$schema",
	"$ref",
	"$defs",
	"definitions",
	"$id",
	"id",
	"$comment",
	"$anchor",
	"$vocabulary",
	"$dynamicRef",
	"$dynamicAnchor",
	"type",
	"enum",
	"const",
	"anyOf",
	"oneOf",
	"allOf",
	"not",
	"properties",
	"required",
	"additionalProperties",
	"patternProperties",
	"propertyNames",
	"minProperties",
	"maxProperties",
	"items",
	"prefixItems",
	"additionalItems",
	"minItems",
	"maxItems",
	"uniqueItems",
	"contains",
	"minContains",
	"maxContains",
	"minLength",
	"maxLength",
	"pattern",
	"format",
	"minimum",
	"maximum",
	"exclusiveMinimum",
	"exclusiveMaximum",
	"multipleOf",
	"description",
	"default",
	"contentEncoding",
	"contentMediaType",
	"contentSchema",
	"unevaluatedItems",
	"unevaluatedProperties",
	"if",
	"then",
	"else",
	"dependentSchemas",
	"dependentRequired",
	"nullable",
	"readOnly"
]);
function detectVersion(schema, defaultTarget) {
	const $schema = schema.$schema;
	if ($schema === "https://json-schema.org/draft/2020-12/schema") return "draft-2020-12";
	if ($schema === "http://json-schema.org/draft-07/schema#") return "draft-7";
	if ($schema === "http://json-schema.org/draft-04/schema#") return "draft-4";
	return defaultTarget ?? "draft-2020-12";
}
function resolveRef(ref, ctx) {
	if (!ref.startsWith("#")) throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
	const path = ref.slice(1).split("/").filter(Boolean);
	if (path.length === 0) return ctx.rootSchema;
	const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
	if (path[0] === defsKey) {
		const key = path[1];
		if (!key || !ctx.defs[key]) throw new Error(`Reference not found: ${ref}`);
		return ctx.defs[key];
	}
	throw new Error(`Reference not found: ${ref}`);
}
function convertBaseSchema(schema, ctx) {
	if (schema.not !== void 0) {
		if (typeof schema.not === "object" && Object.keys(schema.not).length === 0) return z.never();
		throw new Error("not is not supported in Zod (except { not: {} } for never)");
	}
	if (schema.unevaluatedItems !== void 0) throw new Error("unevaluatedItems is not supported");
	if (schema.unevaluatedProperties !== void 0) throw new Error("unevaluatedProperties is not supported");
	if (schema.if !== void 0 || schema.then !== void 0 || schema.else !== void 0) throw new Error("Conditional schemas (if/then/else) are not supported");
	if (schema.dependentSchemas !== void 0 || schema.dependentRequired !== void 0) throw new Error("dependentSchemas and dependentRequired are not supported");
	if (schema.$ref) {
		const refPath = schema.$ref;
		if (ctx.refs.has(refPath)) return ctx.refs.get(refPath);
		if (ctx.processing.has(refPath)) return z.lazy(() => {
			if (!ctx.refs.has(refPath)) throw new Error(`Circular reference not resolved: ${refPath}`);
			return ctx.refs.get(refPath);
		});
		ctx.processing.add(refPath);
		const zodSchema = convertSchema(resolveRef(refPath, ctx), ctx);
		ctx.refs.set(refPath, zodSchema);
		ctx.processing.delete(refPath);
		return zodSchema;
	}
	if (schema.enum !== void 0) {
		const enumValues = schema.enum;
		if (ctx.version === "openapi-3.0" && schema.nullable === true && enumValues.length === 1 && enumValues[0] === null) return z.null();
		if (enumValues.length === 0) return z.never();
		if (enumValues.length === 1) return z.literal(enumValues[0]);
		if (enumValues.every((v) => typeof v === "string")) return z.enum(enumValues);
		const literalSchemas = enumValues.map((v) => z.literal(v));
		if (literalSchemas.length < 2) return literalSchemas[0];
		return z.union([
			literalSchemas[0],
			literalSchemas[1],
			...literalSchemas.slice(2)
		]);
	}
	if (schema.const !== void 0) return z.literal(schema.const);
	const type = schema.type;
	if (Array.isArray(type)) {
		const typeSchemas = type.map((t) => {
			return convertBaseSchema({
				...schema,
				type: t
			}, ctx);
		});
		if (typeSchemas.length === 0) return z.never();
		if (typeSchemas.length === 1) return typeSchemas[0];
		return z.union(typeSchemas);
	}
	if (!type) return z.any();
	let zodSchema;
	switch (type) {
		case "string": {
			let stringSchema = z.string();
			if (schema.format) {
				const format = schema.format;
				if (format === "email") stringSchema = stringSchema.check(z.email());
				else if (format === "uri" || format === "uri-reference") stringSchema = stringSchema.check(z.url());
				else if (format === "uuid" || format === "guid") stringSchema = stringSchema.check(z.uuid());
				else if (format === "date-time") stringSchema = stringSchema.check(z.iso.datetime());
				else if (format === "date") stringSchema = stringSchema.check(z.iso.date());
				else if (format === "time") stringSchema = stringSchema.check(z.iso.time());
				else if (format === "duration") stringSchema = stringSchema.check(z.iso.duration());
				else if (format === "ipv4") stringSchema = stringSchema.check(z.ipv4());
				else if (format === "ipv6") stringSchema = stringSchema.check(z.ipv6());
				else if (format === "mac") stringSchema = stringSchema.check(z.mac());
				else if (format === "cidr") stringSchema = stringSchema.check(z.cidrv4());
				else if (format === "cidr-v6") stringSchema = stringSchema.check(z.cidrv6());
				else if (format === "base64") stringSchema = stringSchema.check(z.base64());
				else if (format === "base64url") stringSchema = stringSchema.check(z.base64url());
				else if (format === "e164") stringSchema = stringSchema.check(z.e164());
				else if (format === "jwt") stringSchema = stringSchema.check(z.jwt());
				else if (format === "emoji") stringSchema = stringSchema.check(z.emoji());
				else if (format === "nanoid") stringSchema = stringSchema.check(z.nanoid());
				else if (format === "cuid") stringSchema = stringSchema.check(z.cuid());
				else if (format === "cuid2") stringSchema = stringSchema.check(z.cuid2());
				else if (format === "ulid") stringSchema = stringSchema.check(z.ulid());
				else if (format === "xid") stringSchema = stringSchema.check(z.xid());
				else if (format === "ksuid") stringSchema = stringSchema.check(z.ksuid());
			}
			if (typeof schema.minLength === "number") stringSchema = stringSchema.min(schema.minLength);
			if (typeof schema.maxLength === "number") stringSchema = stringSchema.max(schema.maxLength);
			if (schema.pattern) stringSchema = stringSchema.regex(new RegExp(schema.pattern));
			zodSchema = stringSchema;
			break;
		}
		case "number":
		case "integer": {
			let numberSchema = type === "integer" ? z.number().int() : z.number();
			if (typeof schema.minimum === "number") numberSchema = numberSchema.min(schema.minimum);
			if (typeof schema.maximum === "number") numberSchema = numberSchema.max(schema.maximum);
			if (typeof schema.exclusiveMinimum === "number") numberSchema = numberSchema.gt(schema.exclusiveMinimum);
			else if (schema.exclusiveMinimum === true && typeof schema.minimum === "number") numberSchema = numberSchema.gt(schema.minimum);
			if (typeof schema.exclusiveMaximum === "number") numberSchema = numberSchema.lt(schema.exclusiveMaximum);
			else if (schema.exclusiveMaximum === true && typeof schema.maximum === "number") numberSchema = numberSchema.lt(schema.maximum);
			if (typeof schema.multipleOf === "number") numberSchema = numberSchema.multipleOf(schema.multipleOf);
			zodSchema = numberSchema;
			break;
		}
		case "boolean":
			zodSchema = z.boolean();
			break;
		case "null":
			zodSchema = z.null();
			break;
		case "object": {
			const shape = {};
			const properties = schema.properties || {};
			const requiredSet = new Set(schema.required || []);
			for (const [key, propSchema] of Object.entries(properties)) {
				const propZodSchema = convertSchema(propSchema, ctx);
				shape[key] = requiredSet.has(key) ? propZodSchema : propZodSchema.optional();
			}
			if (schema.propertyNames) {
				const keySchema = convertSchema(schema.propertyNames, ctx);
				const valueSchema = schema.additionalProperties && typeof schema.additionalProperties === "object" ? convertSchema(schema.additionalProperties, ctx) : z.any();
				if (Object.keys(shape).length === 0) {
					zodSchema = z.record(keySchema, valueSchema);
					break;
				}
				const objectSchema = z.object(shape).passthrough();
				const recordSchema = z.looseRecord(keySchema, valueSchema);
				zodSchema = z.intersection(objectSchema, recordSchema);
				break;
			}
			if (schema.patternProperties) {
				const patternProps = schema.patternProperties;
				const patternKeys = Object.keys(patternProps);
				const looseRecords = [];
				for (const pattern of patternKeys) {
					const patternValue = convertSchema(patternProps[pattern], ctx);
					const keySchema = z.string().regex(new RegExp(pattern));
					looseRecords.push(z.looseRecord(keySchema, patternValue));
				}
				const schemasToIntersect = [];
				if (Object.keys(shape).length > 0) schemasToIntersect.push(z.object(shape).passthrough());
				schemasToIntersect.push(...looseRecords);
				if (schemasToIntersect.length === 0) zodSchema = z.object({}).passthrough();
				else if (schemasToIntersect.length === 1) zodSchema = schemasToIntersect[0];
				else {
					let result = z.intersection(schemasToIntersect[0], schemasToIntersect[1]);
					for (let i = 2; i < schemasToIntersect.length; i++) result = z.intersection(result, schemasToIntersect[i]);
					zodSchema = result;
				}
				break;
			}
			const objectSchema = z.object(shape);
			if (schema.additionalProperties === false) zodSchema = objectSchema.strict();
			else if (typeof schema.additionalProperties === "object") zodSchema = objectSchema.catchall(convertSchema(schema.additionalProperties, ctx));
			else zodSchema = objectSchema.passthrough();
			break;
		}
		case "array": {
			const prefixItems = schema.prefixItems;
			const items = schema.items;
			if (prefixItems && Array.isArray(prefixItems)) {
				const tupleItems = prefixItems.map((item) => convertSchema(item, ctx));
				const rest = items && typeof items === "object" && !Array.isArray(items) ? convertSchema(items, ctx) : void 0;
				if (rest) zodSchema = z.tuple(tupleItems).rest(rest);
				else zodSchema = z.tuple(tupleItems);
				if (typeof schema.minItems === "number") zodSchema = zodSchema.check(z.minLength(schema.minItems));
				if (typeof schema.maxItems === "number") zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
			} else if (Array.isArray(items)) {
				const tupleItems = items.map((item) => convertSchema(item, ctx));
				const rest = schema.additionalItems && typeof schema.additionalItems === "object" ? convertSchema(schema.additionalItems, ctx) : void 0;
				if (rest) zodSchema = z.tuple(tupleItems).rest(rest);
				else zodSchema = z.tuple(tupleItems);
				if (typeof schema.minItems === "number") zodSchema = zodSchema.check(z.minLength(schema.minItems));
				if (typeof schema.maxItems === "number") zodSchema = zodSchema.check(z.maxLength(schema.maxItems));
			} else if (items !== void 0) {
				const element = convertSchema(items, ctx);
				let arraySchema = z.array(element);
				if (typeof schema.minItems === "number") arraySchema = arraySchema.min(schema.minItems);
				if (typeof schema.maxItems === "number") arraySchema = arraySchema.max(schema.maxItems);
				zodSchema = arraySchema;
			} else zodSchema = z.array(z.any());
			break;
		}
		default: throw new Error(`Unsupported type: ${type}`);
	}
	return zodSchema;
}
function convertSchema(schema, ctx) {
	if (typeof schema === "boolean") return schema ? z.any() : z.never();
	let baseSchema = convertBaseSchema(schema, ctx);
	const hasExplicitType = schema.type || schema.enum !== void 0 || schema.const !== void 0;
	if (schema.anyOf && Array.isArray(schema.anyOf)) {
		const options = schema.anyOf.map((s) => convertSchema(s, ctx));
		const anyOfUnion = z.union(options);
		baseSchema = hasExplicitType ? z.intersection(baseSchema, anyOfUnion) : anyOfUnion;
	}
	if (schema.oneOf && Array.isArray(schema.oneOf)) {
		const options = schema.oneOf.map((s) => convertSchema(s, ctx));
		const oneOfUnion = z.xor(options);
		baseSchema = hasExplicitType ? z.intersection(baseSchema, oneOfUnion) : oneOfUnion;
	}
	if (schema.allOf && Array.isArray(schema.allOf)) if (schema.allOf.length === 0) baseSchema = hasExplicitType ? baseSchema : z.any();
	else {
		let result = hasExplicitType ? baseSchema : convertSchema(schema.allOf[0], ctx);
		const startIdx = hasExplicitType ? 0 : 1;
		for (let i = startIdx; i < schema.allOf.length; i++) result = z.intersection(result, convertSchema(schema.allOf[i], ctx));
		baseSchema = result;
	}
	if (schema.nullable === true && ctx.version === "openapi-3.0") baseSchema = z.nullable(baseSchema);
	if (schema.readOnly === true) baseSchema = z.readonly(baseSchema);
	if (schema.default !== void 0) baseSchema = baseSchema.default(schema.default);
	const extraMeta = {};
	for (const key of [
		"$id",
		"id",
		"$comment",
		"$anchor",
		"$vocabulary",
		"$dynamicRef",
		"$dynamicAnchor"
	]) if (key in schema) extraMeta[key] = schema[key];
	for (const key of [
		"contentEncoding",
		"contentMediaType",
		"contentSchema"
	]) if (key in schema) extraMeta[key] = schema[key];
	for (const key of Object.keys(schema)) if (!RECOGNIZED_KEYS.has(key)) extraMeta[key] = schema[key];
	if (Object.keys(extraMeta).length > 0) ctx.registry.add(baseSchema, extraMeta);
	if (schema.description) baseSchema = baseSchema.describe(schema.description);
	return baseSchema;
}
/**
* Converts a JSON Schema to a Zod schema. This function should be considered semi-experimental. It's behavior is liable to change. */
function fromJSONSchema(schema, params) {
	if (typeof schema === "boolean") return schema ? z.any() : z.never();
	let normalized;
	try {
		normalized = JSON.parse(JSON.stringify(schema));
	} catch {
		throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
	}
	const ctx = {
		version: detectVersion(normalized, params?.defaultTarget),
		defs: normalized.$defs || normalized.definitions || {},
		refs: /* @__PURE__ */ new Map(),
		processing: /* @__PURE__ */ new Set(),
		rootSchema: normalized,
		registry: params?.registry ?? globalRegistry
	};
	return convertSchema(normalized, ctx);
}
//#endregion
//#region node_modules/zod/v4/classic/coerce.js
var coerce_exports = /* @__PURE__ */ __exportAll({
	bigint: () => bigint,
	boolean: () => boolean,
	date: () => date,
	number: () => number,
	string: () => string
});
function string(params) {
	return /* @__PURE__ */ _coercedString(ZodString, params);
}
function number(params) {
	return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
}
function boolean(params) {
	return /* @__PURE__ */ _coercedBoolean(ZodBoolean, params);
}
function bigint(params) {
	return /* @__PURE__ */ _coercedBigint(ZodBigInt, params);
}
function date(params) {
	return /* @__PURE__ */ _coercedDate(ZodDate, params);
}
//#endregion
//#region node_modules/zod/v4/classic/external.js
var external_exports = /* @__PURE__ */ __exportAll({
	$brand: () => $brand,
	$input: () => $input,
	$output: () => $output,
	NEVER: () => NEVER,
	TimePrecision: () => TimePrecision,
	ZodAny: () => ZodAny,
	ZodArray: () => ZodArray,
	ZodBase64: () => ZodBase64,
	ZodBase64URL: () => ZodBase64URL,
	ZodBigInt: () => ZodBigInt,
	ZodBigIntFormat: () => ZodBigIntFormat,
	ZodBoolean: () => ZodBoolean,
	ZodCIDRv4: () => ZodCIDRv4,
	ZodCIDRv6: () => ZodCIDRv6,
	ZodCUID: () => ZodCUID,
	ZodCUID2: () => ZodCUID2,
	ZodCatch: () => ZodCatch,
	ZodCodec: () => ZodCodec,
	ZodCustom: () => ZodCustom,
	ZodCustomStringFormat: () => ZodCustomStringFormat,
	ZodDate: () => ZodDate,
	ZodDefault: () => ZodDefault,
	ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
	ZodE164: () => ZodE164,
	ZodEmail: () => ZodEmail,
	ZodEmoji: () => ZodEmoji,
	ZodEnum: () => ZodEnum,
	ZodError: () => ZodError,
	ZodExactOptional: () => ZodExactOptional,
	ZodFile: () => ZodFile,
	ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
	ZodFunction: () => ZodFunction,
	ZodGUID: () => ZodGUID,
	ZodIPv4: () => ZodIPv4,
	ZodIPv6: () => ZodIPv6,
	ZodISODate: () => ZodISODate,
	ZodISODateTime: () => ZodISODateTime,
	ZodISODuration: () => ZodISODuration,
	ZodISOTime: () => ZodISOTime,
	ZodIntersection: () => ZodIntersection,
	ZodIssueCode: () => ZodIssueCode,
	ZodJWT: () => ZodJWT,
	ZodKSUID: () => ZodKSUID,
	ZodLazy: () => ZodLazy,
	ZodLiteral: () => ZodLiteral,
	ZodMAC: () => ZodMAC,
	ZodMap: () => ZodMap,
	ZodNaN: () => ZodNaN,
	ZodNanoID: () => ZodNanoID,
	ZodNever: () => ZodNever,
	ZodNonOptional: () => ZodNonOptional,
	ZodNull: () => ZodNull,
	ZodNullable: () => ZodNullable,
	ZodNumber: () => ZodNumber,
	ZodNumberFormat: () => ZodNumberFormat,
	ZodObject: () => ZodObject,
	ZodOptional: () => ZodOptional,
	ZodPipe: () => ZodPipe,
	ZodPrefault: () => ZodPrefault,
	ZodPreprocess: () => ZodPreprocess,
	ZodPromise: () => ZodPromise,
	ZodReadonly: () => ZodReadonly,
	ZodRealError: () => ZodRealError,
	ZodRecord: () => ZodRecord,
	ZodSet: () => ZodSet,
	ZodString: () => ZodString,
	ZodStringFormat: () => ZodStringFormat,
	ZodSuccess: () => ZodSuccess,
	ZodSymbol: () => ZodSymbol,
	ZodTemplateLiteral: () => ZodTemplateLiteral,
	ZodTransform: () => ZodTransform,
	ZodTuple: () => ZodTuple,
	ZodType: () => ZodType,
	ZodULID: () => ZodULID,
	ZodURL: () => ZodURL,
	ZodUUID: () => ZodUUID,
	ZodUndefined: () => ZodUndefined,
	ZodUnion: () => ZodUnion,
	ZodUnknown: () => ZodUnknown,
	ZodVoid: () => ZodVoid,
	ZodXID: () => ZodXID,
	ZodXor: () => ZodXor,
	_ZodString: () => _ZodString,
	_default: () => _default,
	_function: () => _function,
	any: () => any,
	array: () => array,
	base64: () => base64,
	base64url: () => base64url,
	bigint: () => bigint$1,
	boolean: () => boolean$1,
	catch: () => _catch,
	check: () => check,
	cidrv4: () => cidrv4,
	cidrv6: () => cidrv6,
	clone: () => clone,
	codec: () => codec,
	coerce: () => coerce_exports,
	config: () => config,
	core: () => core_exports,
	cuid: () => cuid,
	cuid2: () => cuid2,
	custom: () => custom,
	date: () => date$1,
	decode: () => decode$1,
	decodeAsync: () => decodeAsync,
	describe: () => describe,
	discriminatedUnion: () => discriminatedUnion,
	e164: () => e164,
	email: () => email,
	emoji: () => emoji,
	encode: () => encode$1,
	encodeAsync: () => encodeAsync,
	endsWith: () => _endsWith,
	enum: () => _enum,
	exactOptional: () => exactOptional,
	file: () => file,
	flattenError: () => flattenError,
	float32: () => float32,
	float64: () => float64,
	formatError: () => formatError,
	fromJSONSchema: () => fromJSONSchema,
	function: () => _function,
	getErrorMap: () => getErrorMap,
	globalRegistry: () => globalRegistry,
	gt: () => _gt,
	gte: () => _gte,
	guid: () => guid,
	hash: () => hash,
	hex: () => hex,
	hostname: () => hostname,
	httpUrl: () => httpUrl,
	includes: () => _includes,
	instanceof: () => _instanceof,
	int: () => int,
	int32: () => int32,
	int64: () => int64,
	intersection: () => intersection,
	invertCodec: () => invertCodec,
	ipv4: () => ipv4,
	ipv6: () => ipv6,
	iso: () => iso_exports,
	json: () => json,
	jwt: () => jwt,
	keyof: () => keyof,
	ksuid: () => ksuid,
	lazy: () => lazy,
	length: () => _length,
	literal: () => literal,
	locales: () => locales_exports,
	looseObject: () => looseObject,
	looseRecord: () => looseRecord,
	lowercase: () => _lowercase,
	lt: () => _lt,
	lte: () => _lte,
	mac: () => mac,
	map: () => map,
	maxLength: () => _maxLength,
	maxSize: () => _maxSize,
	meta: () => meta,
	mime: () => _mime,
	minLength: () => _minLength,
	minSize: () => _minSize,
	multipleOf: () => _multipleOf,
	nan: () => nan,
	nanoid: () => nanoid,
	nativeEnum: () => nativeEnum,
	negative: () => _negative,
	never: () => never,
	nonnegative: () => _nonnegative,
	nonoptional: () => nonoptional,
	nonpositive: () => _nonpositive,
	normalize: () => _normalize,
	null: () => _null,
	nullable: () => nullable,
	nullish: () => nullish,
	number: () => number$1,
	object: () => object,
	optional: () => optional,
	overwrite: () => _overwrite,
	parse: () => parse,
	parseAsync: () => parseAsync,
	partialRecord: () => partialRecord,
	pipe: () => pipe,
	positive: () => _positive,
	prefault: () => prefault,
	preprocess: () => preprocess,
	prettifyError: () => prettifyError,
	promise: () => promise,
	property: () => _property,
	readonly: () => readonly,
	record: () => record,
	refine: () => refine,
	regex: () => _regex,
	regexes: () => regexes_exports,
	registry: () => registry,
	safeDecode: () => safeDecode,
	safeDecodeAsync: () => safeDecodeAsync,
	safeEncode: () => safeEncode,
	safeEncodeAsync: () => safeEncodeAsync,
	safeParse: () => safeParse,
	safeParseAsync: () => safeParseAsync,
	set: () => set,
	setErrorMap: () => setErrorMap,
	size: () => _size,
	slugify: () => _slugify,
	startsWith: () => _startsWith,
	strictObject: () => strictObject,
	string: () => string$1,
	stringFormat: () => stringFormat,
	stringbool: () => stringbool,
	success: () => success,
	superRefine: () => superRefine,
	symbol: () => symbol,
	templateLiteral: () => templateLiteral,
	toJSONSchema: () => toJSONSchema,
	toLowerCase: () => _toLowerCase,
	toUpperCase: () => _toUpperCase,
	transform: () => transform,
	treeifyError: () => treeifyError,
	trim: () => _trim,
	tuple: () => tuple,
	uint32: () => uint32,
	uint64: () => uint64,
	ulid: () => ulid,
	undefined: () => _undefined,
	union: () => union,
	unknown: () => unknown,
	uppercase: () => _uppercase,
	url: () => url,
	util: () => util_exports,
	uuid: () => uuid,
	uuidv4: () => uuidv4,
	uuidv6: () => uuidv6,
	uuidv7: () => uuidv7,
	void: () => _void,
	xid: () => xid,
	xor: () => xor
});
config(en_default());
//#endregion
//#region node_modules/zod/index.js
var zod_default = external_exports;
//#endregion
//#region src/milky/common/api.ts
function defineApi(endpoint, validator, outputTypeInfo, handler) {
	return {
		endpoint,
		validator,
		handler
	};
}
function Ok(data) {
	return {
		status: "ok",
		retcode: 0,
		data
	};
}
function Failed(retcode, message) {
	return {
		status: "failed",
		retcode,
		message
	};
}
function encodeZodIssues(issues) {
	return issues.map((issue) => `[${issue.code}] ${issue.path.join("/")}: ${issue.message}`).join(" ");
}
var MilkyApiCollection = class {
	ctx;
	apiMap = /* @__PURE__ */ new Map();
	constructor(ctx, apiList) {
		this.ctx = ctx;
		apiList.forEach((api) => {
			if (this.apiMap.has(api.endpoint)) throw new Error(`API endpoint "${api.endpoint}" is already defined.`);
			this.apiMap.set(api.endpoint, api);
		});
	}
	/**
	* Checks if the API endpoint is defined.
	*/
	hasApi(endpoint) {
		return this.apiMap.has(endpoint);
	}
	async handle(endpoint, payload) {
		const api = this.apiMap.get(endpoint);
		try {
			const parsedPayload = api.validator.safeParse(payload);
			if (!parsedPayload.success) return Failed(-400, "Invalid payload: " + encodeZodIssues(parsedPayload.error.issues));
			const response = await api.handler(this.ctx, parsedPayload.data);
			if (response.status === "failed") this.ctx.logger.warn("Milky", `Error while handling API /${endpoint}: ${response.message}`);
			return response;
		} catch (e) {
			this.ctx.logger.warn("Milky", `Error while handling API /${endpoint}: ${e instanceof Error ? e.message + "\n" + e.stack : String(e)}`);
			if (e instanceof ZodError) return Failed(-400, "Zod error: " + encodeZodIssues(e.issues));
			return Failed(500, "Internal error: " + (e instanceof Error ? e.message : String(e)));
		}
	}
};
//#endregion
//#region src/milky/network/http.ts
var MilkyHttpHandler = class {
	milkyAdapter;
	ctx;
	config;
	eventPushClients = /* @__PURE__ */ new Set();
	sseClients = /* @__PURE__ */ new Set();
	app;
	httpServer;
	/**
	* Extract token from Authorization header or query parameter
	*/
	extractToken(headers, query) {
		const authHeader = headers["authorization"];
		if (authHeader?.toLowerCase().startsWith("bearer ")) return authHeader.slice(7).trim();
		return query["access_token"];
	}
	/**
	* Validate access token
	*/
	validateToken(inputToken) {
		if (!this.config.accessToken) return true;
		return inputToken === this.config.accessToken;
	}
	constructor(milkyAdapter, ctx, config) {
		this.milkyAdapter = milkyAdapter;
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		this.app = new Hono();
		this.app.use(`${this.config.prefix}/api/*`, cors(), async (c, next) => {
			if (!c.req.header("Content-Type")?.includes("application/json")) {
				this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} (Content-Type not application/json)`);
				return c.json(Failed(415, "Unsupported Media Type"), 415);
			}
			await next();
		});
		if (this.config.accessToken) this.app.post(`${this.config.prefix}/api/*`, async (c, next) => {
			const authorization = c.req.header("Authorization");
			if (!authorization || !authorization.startsWith("Bearer ")) {
				this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} (Credentials missing)`);
				return c.json(Failed(401, "Unauthorized"), 401);
			}
			if (authorization.slice(7) !== this.config.accessToken) {
				this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} (Credentials wrong)`);
				return c.json(Failed(401, "Unauthorized"), 401);
			}
			await next();
		});
		this.app.post(`${this.config.prefix}/api/:endpoint`, async (c) => {
			const endpoint = c.req.param("endpoint");
			if (!this.milkyAdapter.apiCollection.hasApi(endpoint)) {
				this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} (API not found)`);
				return c.json(Failed(404, "API not found"), 404);
			}
			const start = Date.now();
			const payload = await c.req.json();
			const response = await this.milkyAdapter.apiCollection.handle(endpoint, payload);
			const end = Date.now();
			this.ctx.logger.info("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} (${response.retcode === 0 ? "OK" : response.retcode} ${end - start}ms)`, payload);
			return c.json(response);
		});
		this.app.get(`${this.config.prefix}/event`, upgradeWebSocket((c) => {
			return {
				onOpen: (event, ws) => {
					if (this.config.accessToken) {
						const inputToken = this.extractToken(c.req.header(), c.req.query());
						if (!this.validateToken(inputToken)) {
							this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} WS (Credentials invalid)`);
							return ws.close(1008, "Unauthorized");
						}
					}
					this.eventPushClients.add(ws);
					this.ctx.logger.info("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} WS (Connected)`);
				},
				onClose: (event, ws) => {
					this.eventPushClients.delete(ws);
					this.ctx.logger.info("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} WS (Disconnected)`);
				}
			};
		}, { onError: (error) => {
			this.ctx.logger.warn("MilkyHttp", `WebSocket error: ${error.message}`);
		} }), cors(), async (c) => {
			if (this.config.accessToken) {
				const inputToken = this.extractToken(c.req.header(), c.req.query());
				if (!this.validateToken(inputToken)) {
					this.ctx.logger.warn("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} SSE (Credentials invalid)`);
					return c.json(Failed(401, "Unauthorized"), 401);
				}
			}
			return streamSSE(c, async (stream) => {
				this.sseClients.add(stream);
				this.ctx.logger.info("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} SSE (Connected)`);
				stream.onAbort(() => {
					this.sseClients.delete(stream);
					this.ctx.logger.info("MilkyHttp", `${c.env.incoming.socket.remoteAddress} -> ${c.req.path} SSE (Disconnected)`);
				});
				return new Promise((resolve) => {
					stream.onAbort(resolve);
				});
			});
		});
		const wss = new WebSocketServer({
			noServer: true,
			maxPayload: constants$1.MAX_STRING_LENGTH
		});
		this.httpServer = serve({
			fetch: this.app.fetch,
			websocket: { server: wss },
			port: this.config.port,
			hostname: this.config.host
		}, () => {
			const displayHost = this.config.host || "0.0.0.0";
			this.ctx.logger.info("MilkyHttp", `HTTP server started at ${displayHost}:${this.config.port}${this.config.prefix}`);
		});
	}
	stop() {
		for (const stream of this.sseClients) stream.abort();
		this.sseClients.clear();
		for (const ws of this.eventPushClients) ws.close();
		this.eventPushClients.clear();
		this.httpServer?.close();
		this.app = void 0;
	}
	broadcast(msg) {
		for (const ws of this.eventPushClients) try {
			if (ws.readyState === WebSocket.OPEN) ws.send(msg);
		} catch (e) {
			this.ctx.logger.warn("MilkyHttp", `Failed to send WebSocket message: ${e}`);
		}
		for (const stream of this.sseClients) stream.writeSSE({
			data: msg,
			event: "milky_event"
		}).catch((e) => {
			this.ctx.logger.warn("MilkyHttp", `Failed to send SSE message: ${e}`);
			this.sseClients.delete(stream);
		});
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
};
//#endregion
//#region src/milky/network/webhook.ts
var MilkyWebhookHandler = class {
	milkyAdapter;
	ctx;
	config;
	activated = false;
	constructor(milkyAdapter, ctx, config) {
		this.milkyAdapter = milkyAdapter;
		this.ctx = ctx;
		this.config = config;
	}
	start() {
		this.activated = true;
	}
	stop() {
		this.activated = false;
	}
	async broadcast(msg) {
		if (!this.activated || this.config.urls.length === 0) return;
		const sendResult = await Promise.allSettled(this.config.urls.map(async (url) => {
			try {
				const headers = new Headers({ "Content-Type": "application/json" });
				if (this.config.accessToken) headers.append("Authorization", `Bearer ${this.config.accessToken}`);
				await fetch(url, {
					method: "POST",
					headers,
					body: msg
				});
			} catch (e) {
				this.ctx.logger.warn("MilkyWebhook", `Failed to send message to ${url}: ${e instanceof Error ? e.stack : e}`);
				throw e;
			}
		}));
		this.ctx.logger.debug("MilkyWebhook", `Broadcasted message to ${sendResult.filter((result) => result.status === "fulfilled").length} URLs`);
	}
	updateConfig(config) {
		Object.assign(this.config, config);
	}
};
//#endregion
//#region src/milky/transform/entity.ts
function transformGender(gender) {
	if (gender === Sex.Male) return "male";
	if (gender === Sex.Female) return "female";
	return "unknown";
}
function transformFriend(friend) {
	return {
		user_id: friend.uin,
		nickname: friend.nick,
		sex: transformGender(friend.gender),
		qid: friend.qid,
		remark: friend.remark,
		category: {
			category_id: friend.categoryId,
			category_name: friend.categoryName
		}
	};
}
function transformGroup(group) {
	return {
		group_id: group.groupCode,
		group_name: group.groupName,
		member_count: group.memberCount,
		max_member_count: group.maxMemberCount,
		remark: group.remark,
		created_time: group.createdAt,
		description: group.description,
		question: group.question,
		announcement: group.announcementPreview
	};
}
function transformGroupMemberRole(role) {
	if (role === GroupMemberRole.Owner) return "owner";
	if (role === GroupMemberRole.Admin) return "admin";
	return "member";
}
function transformGroupMember(member, groupId) {
	return {
		user_id: member.uin,
		nickname: member.nick,
		sex: "unknown",
		group_id: groupId,
		card: member.cardName,
		title: member.specialTitle,
		level: member.level,
		role: transformGroupMemberRole(member.role),
		join_time: member.joinedAt,
		last_sent_time: member.lastSpokeAt,
		shut_up_end_time: member.shutupExpireTime || void 0
	};
}
function transformGroupFileList(items, groupId) {
	const files = [];
	const folders = [];
	for (const item of items) if (item.folderInfo) folders.push({
		group_id: groupId,
		folder_id: item.folderInfo.folderId,
		parent_folder_id: item.folderInfo.parentFolderId,
		folder_name: item.folderInfo.folderName,
		created_time: item.folderInfo.createTime,
		last_modified_time: item.folderInfo.modifyTime,
		creator_id: item.folderInfo.createUin,
		file_count: item.folderInfo.totalFileCount
	});
	else if (item.fileInfo) files.push({
		group_id: groupId,
		file_id: item.fileInfo.fileId,
		file_name: item.fileInfo.fileName,
		parent_folder_id: item.fileInfo.parentDirectory,
		file_size: item.fileInfo.fileSize,
		uploaded_time: item.fileInfo.uploadedTime,
		expire_time: item.fileInfo.expireTime || void 0,
		uploader_id: item.fileInfo.uploaderUin,
		downloaded_times: item.fileInfo.downloadedTimes
	});
	return {
		files,
		folders
	};
}
//#endregion
//#region src/milky/transform/system.ts
function transformProtocolOsType(type) {
	if (type === "Linux") return "linux";
	else if (type === "Darwin") return "macos";
	else return "windows";
}
//#endregion
//#region src/milky/generated/schema.ts
var zUin = number$1().int().min(10001).max(4294967295);
function zDropBadElementArray(element) {
	return array(element.catch(null)).transform((val) => val.filter((item) => item !== null));
}
var BotOfflineEventData = object({ reason: string$1().describe("下线原因") }).describe("机器人离线事件");
var MessageRecallEventData = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("消息场景"),
	peer_id: zUin.describe("好友 QQ 号或群号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	sender_id: zUin.describe("被撤回的消息的发送者 QQ 号"),
	operator_id: zUin.describe("操作者 QQ 号"),
	display_suffix: string$1().describe("撤回提示的后缀文本")
}).describe("消息撤回事件");
var PeerPinChangeEventData = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("发生改变的会话的消息场景"),
	peer_id: zUin.describe("发生改变的好友 QQ 号或群号"),
	is_pinned: boolean$1().describe("是否被置顶, `false` 表示取消置顶")
}).describe("会话置顶变更事件");
var FriendRequestEventData = object({
	initiator_id: zUin.describe("申请好友的用户 QQ 号"),
	initiator_uid: string$1().describe("用户 UID"),
	comment: string$1().describe("申请附加信息"),
	via: string$1().describe("申请来源")
}).describe("好友请求事件");
var GroupJoinRequestEventData = object({
	group_id: zUin.describe("群号"),
	notification_seq: number$1().int().nonnegative().describe("请求对应的通知序列号"),
	is_filtered: boolean$1().describe("请求是否被过滤（发起自风险账户）"),
	initiator_id: zUin.describe("申请入群的用户 QQ 号"),
	comment: string$1().describe("申请附加信息")
}).describe("入群请求事件");
var GroupInvitedJoinRequestEventData = object({
	group_id: zUin.describe("群号"),
	notification_seq: number$1().int().nonnegative().describe("请求对应的通知序列号"),
	initiator_id: zUin.describe("邀请者 QQ 号"),
	target_user_id: zUin.describe("被邀请者 QQ 号")
}).describe("群成员邀请他人入群请求事件");
var GroupInvitationEventData = object({
	group_id: zUin.describe("群号"),
	invitation_seq: number$1().int().nonnegative().describe("邀请序列号"),
	initiator_id: zUin.describe("邀请者 QQ 号"),
	source_group_id: number$1().int().nonnegative().nullish().describe("来源群号，如果是通过 QQ 群邀请")
}).describe("他人邀请自身入群事件");
var FriendNudgeEventData = object({
	user_id: zUin.describe("好友 QQ 号"),
	is_self_send: boolean$1().describe("是否是自己发送的戳一戳"),
	is_self_receive: boolean$1().describe("是否是自己接收的戳一戳"),
	display_action: string$1().describe("戳一戳提示的动作文本"),
	display_suffix: string$1().describe("戳一戳提示的后缀文本"),
	display_action_img_url: string$1().describe("戳一戳提示的动作图片 URL，用于取代动作提示文本")
}).describe("好友戳一戳事件");
var FriendFileUploadEventData = object({
	user_id: zUin.describe("好友 QQ 号"),
	file_id: string$1().describe("文件 ID"),
	file_name: string$1().describe("文件名称"),
	file_size: number$1().int().nonnegative().describe("文件大小（字节）"),
	file_hash: string$1().describe("文件的 TriSHA1 哈希值"),
	is_self: boolean$1().describe("是否是自己发送的文件")
}).describe("好友文件上传事件");
var GroupAdminChangeEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发生变更的用户 QQ 号"),
	operator_id: zUin.describe("操作者 QQ 号"),
	is_set: boolean$1().describe("是否被设置为管理员，`false` 表示被取消管理员")
}).describe("群管理员变更事件");
var GroupEssenceMessageChangeEventData = object({
	group_id: zUin.describe("群号"),
	message_seq: number$1().int().nonnegative().describe("发生变更的消息序列号"),
	operator_id: zUin.describe("操作者 QQ 号"),
	is_set: boolean$1().describe("是否被设置为精华，`false` 表示被取消精华")
}).describe("群精华消息变更事件");
var GroupMemberIncreaseEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发生变更的用户 QQ 号"),
	operator_id: number$1().int().nonnegative().nullish().describe("管理员 QQ 号，如果是管理员同意入群"),
	invitor_id: number$1().int().nonnegative().nullish().describe("邀请者 QQ 号，如果是邀请入群")
}).describe("群成员增加事件");
var GroupMemberDecreaseEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发生变更的用户 QQ 号"),
	operator_id: number$1().int().nonnegative().nullish().describe("管理员 QQ 号，如果是管理员踢出")
}).describe("群成员减少事件");
var GroupDisbandEventData = object({
	group_id: zUin.describe("群号"),
	operator_id: zUin.describe("操作者 QQ 号")
}).describe("群解散事件");
var GroupNameChangeEventData = object({
	group_id: zUin.describe("群号"),
	new_group_name: string$1().describe("新的群名称"),
	operator_id: zUin.describe("操作者 QQ 号")
}).describe("群名称变更事件");
var GroupMessageReactionEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发送回应者 QQ 号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	face_id: string$1().describe("表情 ID"),
	reaction_type: _enum(["face", "emoji"]).describe("收到的回应类型"),
	is_add: boolean$1().describe("是否为添加，`false` 表示取消回应")
}).describe("群消息表情回应事件");
var GroupMuteEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发生变更的用户 QQ 号"),
	operator_id: zUin.describe("操作者 QQ 号"),
	duration: number$1().int().nonnegative().describe("禁言时长（秒），为 0 表示取消禁言")
}).describe("群禁言事件");
var GroupWholeMuteEventData = object({
	group_id: zUin.describe("群号"),
	operator_id: zUin.describe("操作者 QQ 号"),
	is_mute: boolean$1().describe("是否全员禁言，`false` 表示取消全员禁言")
}).describe("群全体禁言事件");
var GroupNudgeEventData = object({
	group_id: zUin.describe("群号"),
	sender_id: zUin.describe("发送者 QQ 号"),
	receiver_id: zUin.describe("接收者 QQ 号"),
	display_action: string$1().describe("戳一戳提示的动作文本"),
	display_suffix: string$1().describe("戳一戳提示的后缀文本"),
	display_action_img_url: string$1().describe("戳一戳提示的动作图片 URL，用于取代动作提示文本")
}).describe("群戳一戳事件");
var GroupFileUploadEventData = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("发送者 QQ 号"),
	file_id: string$1().describe("文件 ID"),
	file_name: string$1().describe("文件名称"),
	file_size: number$1().int().nonnegative().describe("文件大小（字节）")
}).describe("群文件上传事件");
discriminatedUnion("event_type", [
	object({
		event_type: literal("bot_offline"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: BotOfflineEventData.describe("机器人离线事件")
	}).describe("机器人离线事件"),
	object({
		event_type: literal("message_receive"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: lazy(() => IncomingMessage).describe("消息接收事件")
	}).describe("消息接收事件"),
	object({
		event_type: literal("message_recall"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: MessageRecallEventData.describe("消息撤回事件")
	}).describe("消息撤回事件"),
	object({
		event_type: literal("peer_pin_change"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: PeerPinChangeEventData.describe("会话置顶变更事件")
	}).describe("会话置顶变更事件"),
	object({
		event_type: literal("friend_request"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: FriendRequestEventData.describe("好友请求事件")
	}).describe("好友请求事件"),
	object({
		event_type: literal("group_join_request"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupJoinRequestEventData.describe("入群请求事件")
	}).describe("入群请求事件"),
	object({
		event_type: literal("group_invited_join_request"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupInvitedJoinRequestEventData.describe("群成员邀请他人入群请求事件")
	}).describe("群成员邀请他人入群请求事件"),
	object({
		event_type: literal("group_invitation"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupInvitationEventData.describe("他人邀请自身入群事件")
	}).describe("他人邀请自身入群事件"),
	object({
		event_type: literal("friend_nudge"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: FriendNudgeEventData.describe("好友戳一戳事件")
	}).describe("好友戳一戳事件"),
	object({
		event_type: literal("friend_file_upload"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: FriendFileUploadEventData.describe("好友文件上传事件")
	}).describe("好友文件上传事件"),
	object({
		event_type: literal("group_admin_change"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupAdminChangeEventData.describe("群管理员变更事件")
	}).describe("群管理员变更事件"),
	object({
		event_type: literal("group_essence_message_change"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupEssenceMessageChangeEventData.describe("群精华消息变更事件")
	}).describe("群精华消息变更事件"),
	object({
		event_type: literal("group_member_increase"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupMemberIncreaseEventData.describe("群成员增加事件")
	}).describe("群成员增加事件"),
	object({
		event_type: literal("group_member_decrease"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupMemberDecreaseEventData.describe("群成员减少事件")
	}).describe("群成员减少事件"),
	object({
		event_type: literal("group_disband"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupDisbandEventData.describe("群解散事件")
	}).describe("群解散事件"),
	object({
		event_type: literal("group_name_change"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupNameChangeEventData.describe("群名称变更事件")
	}).describe("群名称变更事件"),
	object({
		event_type: literal("group_message_reaction"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupMessageReactionEventData.describe("群消息表情回应事件")
	}).describe("群消息表情回应事件"),
	object({
		event_type: literal("group_mute"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupMuteEventData.describe("群禁言事件")
	}).describe("群禁言事件"),
	object({
		event_type: literal("group_whole_mute"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupWholeMuteEventData.describe("群全体禁言事件")
	}).describe("群全体禁言事件"),
	object({
		event_type: literal("group_nudge"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupNudgeEventData.describe("群戳一戳事件")
	}).describe("群戳一戳事件"),
	object({
		event_type: literal("group_file_upload"),
		time: number$1().int().nonnegative().describe("事件 Unix 时间戳（秒）"),
		self_id: zUin.describe("机器人 QQ 号"),
		data: GroupFileUploadEventData.describe("群文件上传事件")
	}).describe("群文件上传事件")
]).describe("事件");
var FriendEntity = object({
	user_id: zUin.describe("用户 QQ 号"),
	nickname: string$1().describe("用户昵称"),
	sex: _enum([
		"male",
		"female",
		"unknown"
	]).describe("用户性别"),
	qid: string$1().describe("用户 QID"),
	remark: string$1().describe("好友备注"),
	category: lazy(() => FriendCategoryEntity).describe("好友分组")
}).describe("好友实体");
var FriendCategoryEntity = object({
	category_id: number$1().int().nonnegative().describe("好友分组 ID"),
	category_name: string$1().describe("好友分组名称")
}).describe("好友分组实体");
var GroupEntity = object({
	group_id: zUin.describe("群号"),
	group_name: string$1().describe("群名称"),
	member_count: number$1().int().nonnegative().describe("群成员数量"),
	max_member_count: number$1().int().nonnegative().describe("群容量"),
	remark: string$1().describe("群备注"),
	created_time: number$1().int().nonnegative().describe("群创建时间，Unix 时间戳（秒）"),
	description: string$1().describe("群简介"),
	question: string$1().describe("加群验证问题"),
	announcement: string$1().describe("群公告预览")
}).describe("群实体");
var GroupMemberEntity = object({
	user_id: zUin.describe("用户 QQ 号"),
	nickname: string$1().describe("用户昵称"),
	sex: _enum([
		"male",
		"female",
		"unknown"
	]).describe("用户性别"),
	group_id: zUin.describe("群号"),
	card: string$1().describe("成员备注"),
	title: string$1().describe("专属头衔"),
	level: number$1().int().nonnegative().describe("群等级，注意和 QQ 等级区分"),
	role: _enum([
		"owner",
		"admin",
		"member"
	]).describe("权限等级"),
	join_time: number$1().int().nonnegative().describe("入群时间，Unix 时间戳（秒）"),
	last_sent_time: number$1().int().nonnegative().describe("最后发言时间，Unix 时间戳（秒）"),
	shut_up_end_time: number$1().int().nonnegative().nullish().describe("禁言结束时间，Unix 时间戳（秒）")
}).describe("群成员实体");
var GroupAnnouncementEntity = object({
	group_id: zUin.describe("群号"),
	announcement_id: string$1().describe("公告 ID"),
	user_id: zUin.describe("发送者 QQ 号"),
	time: number$1().int().nonnegative().describe("Unix 时间戳（秒）"),
	content: string$1().describe("公告内容"),
	image_url: string$1().nullish().describe("公告图片 URL")
}).describe("群公告实体");
var GroupFileEntity = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID"),
	file_name: string$1().describe("文件名称"),
	parent_folder_id: string$1().describe("父文件夹 ID"),
	file_size: number$1().int().nonnegative().describe("文件大小（字节）"),
	uploaded_time: number$1().int().nonnegative().describe("上传时的 Unix 时间戳（秒）"),
	expire_time: number$1().int().nonnegative().nullish().describe("过期时的 Unix 时间戳（秒）"),
	uploader_id: zUin.describe("上传者 QQ 号"),
	downloaded_times: number$1().int().nonnegative().describe("下载次数")
}).describe("群文件实体");
var GroupFolderEntity = object({
	group_id: zUin.describe("群号"),
	folder_id: string$1().describe("文件夹 ID"),
	parent_folder_id: string$1().describe("父文件夹 ID"),
	folder_name: string$1().describe("文件夹名称"),
	created_time: number$1().int().nonnegative().describe("创建时的 Unix 时间戳（秒）"),
	last_modified_time: number$1().int().nonnegative().describe("最后修改时的 Unix 时间戳（秒）"),
	creator_id: zUin.describe("创建者 QQ 号"),
	file_count: number$1().int().nonnegative().describe("文件数量")
}).describe("群文件夹实体");
var FriendRequest = object({
	time: number$1().int().nonnegative().describe("请求发起时的 Unix 时间戳（秒）"),
	initiator_id: zUin.describe("请求发起者 QQ 号"),
	initiator_uid: string$1().describe("请求发起者 UID"),
	target_user_id: zUin.describe("目标用户 QQ 号"),
	target_user_uid: string$1().describe("目标用户 UID"),
	state: _enum([
		"pending",
		"accepted",
		"rejected",
		"ignored"
	]).describe("请求状态"),
	comment: string$1().describe("申请附加信息"),
	via: string$1().describe("申请来源"),
	is_filtered: boolean$1().describe("请求是否被过滤（发起自风险账户）")
}).describe("好友请求实体");
var GroupNotification = discriminatedUnion("type", [
	object({
		type: literal("join_request"),
		group_id: zUin.describe("群号"),
		notification_seq: number$1().int().nonnegative().describe("通知序列号"),
		is_filtered: boolean$1().describe("请求是否被过滤（发起自风险账户）"),
		initiator_id: zUin.describe("发起者 QQ 号"),
		state: _enum([
			"pending",
			"accepted",
			"rejected",
			"ignored"
		]).describe("请求状态"),
		operator_id: number$1().int().nonnegative().nullish().describe("处理请求的管理员 QQ 号"),
		comment: string$1().describe("入群请求附加信息")
	}).describe("用户入群请求"),
	object({
		type: literal("admin_change"),
		group_id: zUin.describe("群号"),
		notification_seq: number$1().int().nonnegative().describe("通知序列号"),
		target_user_id: zUin.describe("被设置/取消用户 QQ 号"),
		is_set: boolean$1().describe("是否被设置为管理员，`false` 表示被取消管理员"),
		operator_id: zUin.describe("操作者（群主）QQ 号")
	}).describe("群管理员变更通知"),
	object({
		type: literal("kick"),
		group_id: zUin.describe("群号"),
		notification_seq: number$1().int().nonnegative().describe("通知序列号"),
		target_user_id: zUin.describe("被移除用户 QQ 号"),
		operator_id: zUin.describe("移除用户的管理员 QQ 号")
	}).describe("群成员被移除通知"),
	object({
		type: literal("quit"),
		group_id: zUin.describe("群号"),
		notification_seq: number$1().int().nonnegative().describe("通知序列号"),
		target_user_id: zUin.describe("退群用户 QQ 号")
	}).describe("群成员退群通知"),
	object({
		type: literal("invited_join_request"),
		group_id: zUin.describe("群号"),
		notification_seq: number$1().int().nonnegative().describe("通知序列号"),
		initiator_id: zUin.describe("邀请者 QQ 号"),
		target_user_id: zUin.describe("被邀请用户 QQ 号"),
		state: _enum([
			"pending",
			"accepted",
			"rejected",
			"ignored"
		]).describe("请求状态"),
		operator_id: number$1().int().nonnegative().nullish().describe("处理请求的管理员 QQ 号")
	}).describe("群成员邀请他人入群请求")
]).describe("群通知实体");
var IncomingMessage = discriminatedUnion("message_scene", [
	object({
		message_scene: literal("friend"),
		peer_id: zUin.describe("好友 QQ 号或群号"),
		message_seq: number$1().int().nonnegative().describe("消息序列号"),
		sender_id: zUin.describe("发送者 QQ 号"),
		time: number$1().int().nonnegative().describe("消息 Unix 时间戳（秒）"),
		segments: array(lazy(() => IncomingSegment)).describe("消息段列表"),
		friend: lazy(() => FriendEntity).describe("好友信息")
	}).describe("好友消息"),
	object({
		message_scene: literal("group"),
		peer_id: zUin.describe("好友 QQ 号或群号"),
		message_seq: number$1().int().nonnegative().describe("消息序列号"),
		sender_id: zUin.describe("发送者 QQ 号"),
		time: number$1().int().nonnegative().describe("消息 Unix 时间戳（秒）"),
		segments: array(lazy(() => IncomingSegment)).describe("消息段列表"),
		group: lazy(() => GroupEntity).describe("群信息"),
		group_member: lazy(() => GroupMemberEntity).describe("群成员信息")
	}).describe("群消息"),
	object({
		message_scene: literal("temp"),
		peer_id: zUin.describe("好友 QQ 号或群号"),
		message_seq: number$1().int().nonnegative().describe("消息序列号"),
		sender_id: zUin.describe("发送者 QQ 号"),
		time: number$1().int().nonnegative().describe("消息 Unix 时间戳（秒）"),
		segments: array(lazy(() => IncomingSegment)).describe("消息段列表"),
		group: lazy(() => GroupEntity).nullish().describe("临时会话发送者的所在的群信息")
	}).describe("临时会话消息")
]).describe("接收消息");
var IncomingForwardedMessage = object({
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	sender_name: string$1().describe("发送者名称"),
	avatar_url: string$1().describe("发送者头像 URL"),
	time: number$1().int().nonnegative().describe("消息 Unix 时间戳（秒）"),
	segments: array(lazy(() => IncomingSegment)).describe("消息段列表")
}).describe("接收转发消息");
var GroupEssenceMessage = object({
	group_id: zUin.describe("群号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	message_time: number$1().int().nonnegative().describe("消息发送时的 Unix 时间戳（秒）"),
	sender_id: zUin.describe("发送者 QQ 号"),
	sender_name: string$1().describe("发送者名称"),
	operator_id: zUin.describe("设置精华的操作者 QQ 号"),
	operator_name: string$1().describe("设置精华的操作者名称"),
	operation_time: number$1().int().nonnegative().describe("消息被设置精华时的 Unix 时间戳（秒）"),
	segments: array(lazy(() => IncomingSegment)).describe("消息段列表")
}).describe("群精华消息");
var IncomingTextSegmentData = object({ text: string$1().describe("文本内容") }).describe("文本消息段");
var IncomingMentionSegmentData = object({
	user_id: zUin.describe("提及的 QQ 号"),
	name: string$1().describe("去掉 `@` 前缀的提及的名称")
}).describe("提及消息段");
var IncomingMentionAllSegmentData = object({}).describe("提及全体消息段");
var IncomingFaceSegmentData = object({
	face_id: string$1().describe("表情 ID"),
	is_large: boolean$1().describe("是否为超级表情")
}).describe("表情消息段");
var IncomingReplySegmentData = object({
	message_seq: number$1().int().nonnegative().describe("被引用的消息序列号"),
	sender_id: zUin.describe("被引用的消息发送者 QQ 号"),
	sender_name: string$1().nullish().describe("被引用的消息发送者名称，仅在合并转发中能够获取"),
	time: number$1().int().nonnegative().describe("被引用的消息的 Unix 时间戳（秒）"),
	get segments() {
		return array(lazy(() => IncomingSegment)).describe("回复消息内容");
	}
}).describe("回复消息段");
var IncomingImageSegmentData = object({
	resource_id: string$1().describe("资源 ID"),
	temp_url: string$1().describe("临时 URL"),
	width: number$1().int().nonnegative().describe("图片宽度"),
	height: number$1().int().nonnegative().describe("图片高度"),
	summary: string$1().describe("图片预览文本"),
	sub_type: _enum(["normal", "sticker"]).describe("图片类型")
}).describe("图片消息段");
var IncomingRecordSegmentData = object({
	resource_id: string$1().describe("资源 ID"),
	temp_url: string$1().describe("临时 URL"),
	duration: number$1().int().nonnegative().describe("语音时长（秒）")
}).describe("语音消息段");
var IncomingVideoSegmentData = object({
	resource_id: string$1().describe("资源 ID"),
	temp_url: string$1().describe("临时 URL"),
	width: number$1().int().nonnegative().describe("视频宽度"),
	height: number$1().int().nonnegative().describe("视频高度"),
	duration: number$1().int().nonnegative().describe("视频时长（秒）")
}).describe("视频消息段");
var IncomingFileSegmentData = object({
	file_id: string$1().describe("文件 ID"),
	file_name: string$1().describe("文件名称"),
	file_size: number$1().int().nonnegative().describe("文件大小（字节）"),
	file_hash: string$1().nullish().describe("文件的 TriSHA1 哈希值，仅在私聊文件中存在")
}).describe("文件消息段");
var IncomingForwardSegmentData = object({
	forward_id: string$1().describe("合并转发 ID"),
	title: string$1().describe("合并转发标题"),
	preview: array(string$1()).describe("合并转发预览文本"),
	summary: string$1().describe("合并转发摘要")
}).describe("合并转发消息段");
var IncomingMarketFaceSegmentData = object({
	emoji_package_id: number$1().int().nonnegative().describe("市场表情包 ID"),
	emoji_id: string$1().describe("市场表情 ID"),
	key: string$1().describe("市场表情 Key"),
	summary: string$1().describe("市场表情预览文本"),
	url: string$1().describe("市场表情 URL")
}).describe("市场表情消息段");
var IncomingLightAppSegmentData = object({
	app_name: string$1().describe("小程序名称"),
	json_payload: string$1().describe("小程序 JSON 数据")
}).describe("小程序消息段");
var IncomingXmlSegmentData = object({
	service_id: number$1().int().nonnegative().describe("服务 ID"),
	xml_payload: string$1().describe("XML 数据")
}).describe("XML 消息段");
var IncomingMarkdownSegmentData = object({ content: string$1().describe("Markdown 内容") }).describe("Markdown 消息段");
var IncomingSegment = discriminatedUnion("type", [
	object({
		type: literal("text"),
		data: IncomingTextSegmentData.describe("文本消息段")
	}).describe("文本消息段"),
	object({
		type: literal("mention"),
		data: IncomingMentionSegmentData.describe("提及消息段")
	}).describe("提及消息段"),
	object({
		type: literal("mention_all"),
		data: IncomingMentionAllSegmentData.describe("提及全体消息段")
	}).describe("提及全体消息段"),
	object({
		type: literal("face"),
		data: IncomingFaceSegmentData.describe("表情消息段")
	}).describe("表情消息段"),
	object({
		type: literal("reply"),
		data: IncomingReplySegmentData.describe("回复消息段")
	}).describe("回复消息段"),
	object({
		type: literal("image"),
		data: IncomingImageSegmentData.describe("图片消息段")
	}).describe("图片消息段"),
	object({
		type: literal("record"),
		data: IncomingRecordSegmentData.describe("语音消息段")
	}).describe("语音消息段"),
	object({
		type: literal("video"),
		data: IncomingVideoSegmentData.describe("视频消息段")
	}).describe("视频消息段"),
	object({
		type: literal("file"),
		data: IncomingFileSegmentData.describe("文件消息段")
	}).describe("文件消息段"),
	object({
		type: literal("forward"),
		data: IncomingForwardSegmentData.describe("合并转发消息段")
	}).describe("合并转发消息段"),
	object({
		type: literal("market_face"),
		data: IncomingMarketFaceSegmentData.describe("市场表情消息段")
	}).describe("市场表情消息段"),
	object({
		type: literal("light_app"),
		data: IncomingLightAppSegmentData.describe("小程序消息段")
	}).describe("小程序消息段"),
	object({
		type: literal("xml"),
		data: IncomingXmlSegmentData.describe("XML 消息段")
	}).describe("XML 消息段"),
	object({
		type: literal("markdown"),
		data: IncomingMarkdownSegmentData.describe("Markdown 消息段")
	}).describe("Markdown 消息段")
]).catch({
	type: "text",
	data: { text: "[unknown]" }
}).describe("接收消息段");
var OutgoingForwardedMessage = object({
	user_id: zUin.describe("发送者 QQ 号"),
	sender_name: string$1().describe("发送者名称"),
	time: number$1().int().nonnegative().nullish().describe("消息 Unix 时间戳（秒）"),
	segments: array(lazy(() => OutgoingSegment)).describe("消息段列表")
}).describe("发送转发消息");
var OutgoingTextSegmentData = object({ text: string$1().describe("文本内容") }).describe("文本消息段");
var OutgoingMentionSegmentData = object({ user_id: zUin.describe("提及的 QQ 号") }).describe("提及消息段");
var OutgoingMentionAllSegmentData = object({}).describe("提及全体消息段");
var OutgoingFaceSegmentData = object({
	face_id: string$1().describe("表情 ID"),
	is_large: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否为超级表情")
}).describe("表情消息段");
var OutgoingReplySegmentData = object({ message_seq: number$1().int().nonnegative().describe("被引用的消息序列号") }).describe("回复消息段");
var OutgoingImageSegmentData = object({
	uri: string$1().describe("文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式"),
	sub_type: _enum(["normal", "sticker"]).nullish().default("normal").transform((val) => val ?? "normal").describe("图片类型"),
	summary: string$1().nullish().describe("图片预览文本")
}).describe("图片消息段");
var OutgoingRecordSegmentData = object({ uri: string$1().describe("文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式") }).describe("语音消息段");
var OutgoingVideoSegmentData = object({
	uri: string$1().describe("文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式"),
	thumb_uri: string$1().nullish().describe("封面图片 URI")
}).describe("视频消息段");
var OutgoingForwardSegmentData = object({
	get messages() {
		return array(lazy(() => OutgoingForwardedMessage)).describe("转发消息内容");
	},
	title: string$1().nullish().describe("合并转发标题"),
	preview: array(string$1()).nullish().describe("合并转发预览文本，若提供，至少 1 条，至多 4 条"),
	summary: string$1().nullish().describe("合并转发摘要"),
	prompt: string$1().nullish().describe("合并转发的预览外显文本，仅对移动端 QQ 有效")
}).describe("合并转发消息段");
var OutgoingLightAppSegmentData = object({ json_payload: string$1().describe("小程序 JSON 数据") }).describe("小程序消息段");
var OutgoingSegment = discriminatedUnion("type", [
	object({
		type: literal("text"),
		data: OutgoingTextSegmentData.describe("文本消息段")
	}).describe("文本消息段"),
	object({
		type: literal("mention"),
		data: OutgoingMentionSegmentData.describe("提及消息段")
	}).describe("提及消息段"),
	object({
		type: literal("mention_all"),
		data: OutgoingMentionAllSegmentData.describe("提及全体消息段")
	}).describe("提及全体消息段"),
	object({
		type: literal("face"),
		data: OutgoingFaceSegmentData.describe("表情消息段")
	}).describe("表情消息段"),
	object({
		type: literal("reply"),
		data: OutgoingReplySegmentData.describe("回复消息段")
	}).describe("回复消息段"),
	object({
		type: literal("image"),
		data: OutgoingImageSegmentData.describe("图片消息段")
	}).describe("图片消息段"),
	object({
		type: literal("record"),
		data: OutgoingRecordSegmentData.describe("语音消息段")
	}).describe("语音消息段"),
	object({
		type: literal("video"),
		data: OutgoingVideoSegmentData.describe("视频消息段")
	}).describe("视频消息段"),
	object({
		type: literal("forward"),
		data: OutgoingForwardSegmentData.describe("合并转发消息段")
	}).describe("合并转发消息段"),
	object({
		type: literal("light_app"),
		data: OutgoingLightAppSegmentData.describe("小程序消息段")
	}).describe("小程序消息段")
]).describe("发送消息段");
var GetLoginInfoOutput = object({
	uin: zUin.describe("登录 QQ 号"),
	nickname: string$1().describe("登录昵称")
}).describe("get_login_info 响应数据");
var GetImplInfoOutput = object({
	impl_name: string$1().describe("协议端名称"),
	impl_version: string$1().describe("协议端版本"),
	qq_protocol_version: string$1().describe("协议端使用的 QQ 协议版本"),
	qq_protocol_type: _enum([
		"windows",
		"linux",
		"macos",
		"android_pad",
		"android_phone",
		"ipad",
		"iphone",
		"harmony",
		"watch"
	]).describe("协议端使用的 QQ 协议平台"),
	milky_version: string$1().describe("协议端实现的 Milky 协议版本，目前为 \"1.2\"")
}).describe("get_impl_info 响应数据");
var GetUserProfileInput = object({ user_id: zUin.describe("用户 QQ 号") }).describe("get_user_profile 请求参数");
var GetUserProfileOutput = object({
	nickname: string$1().describe("昵称"),
	qid: string$1().describe("QID"),
	age: number$1().int().nonnegative().describe("年龄"),
	sex: _enum([
		"male",
		"female",
		"unknown"
	]).describe("性别"),
	remark: string$1().describe("备注"),
	bio: string$1().describe("个性签名"),
	level: number$1().int().nonnegative().describe("QQ 等级"),
	country: string$1().describe("国家或地区"),
	city: string$1().describe("城市"),
	school: string$1().describe("学校")
}).describe("get_user_profile 响应数据");
var GetFriendListInput = object({ no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存") }).describe("get_friend_list 请求参数");
var GetFriendListOutput = object({ friends: array(lazy(() => FriendEntity)).describe("好友列表") }).describe("get_friend_list 响应数据");
var GetFriendInfoInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存")
}).describe("get_friend_info 请求参数");
var GetFriendInfoOutput = object({ friend: lazy(() => FriendEntity).describe("好友信息") }).describe("get_friend_info 响应数据");
var GetGroupListInput = object({ no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存") }).describe("get_group_list 请求参数");
var GetGroupListOutput = object({ groups: array(lazy(() => GroupEntity)).describe("群列表") }).describe("get_group_list 响应数据");
var GetGroupInfoInput = object({
	group_id: zUin.describe("群号"),
	no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存")
}).describe("get_group_info 请求参数");
var GetGroupInfoOutput = object({ group: lazy(() => GroupEntity).describe("群信息") }).describe("get_group_info 响应数据");
var GetGroupMemberListInput = object({
	group_id: zUin.describe("群号"),
	no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存")
}).describe("get_group_member_list 请求参数");
var GetGroupMemberListOutput = object({ members: array(lazy(() => GroupMemberEntity)).describe("群成员列表") }).describe("get_group_member_list 响应数据");
var GetGroupMemberInfoInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("群成员 QQ 号"),
	no_cache: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否强制不使用缓存")
}).describe("get_group_member_info 请求参数");
var GetGroupMemberInfoOutput = object({ member: lazy(() => GroupMemberEntity).describe("群成员信息") }).describe("get_group_member_info 响应数据");
var GetPeerPinsOutput = object({
	friends: array(lazy(() => FriendEntity)).describe("置顶的好友列表"),
	groups: array(lazy(() => GroupEntity)).describe("置顶的群列表")
}).describe("get_peer_pins 响应数据");
var SetPeerPinInput = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("要设置的会话的消息场景"),
	peer_id: zUin.describe("要设置的好友 QQ 号或群号"),
	is_pinned: boolean$1().nullish().default(true).transform((val) => val ?? true).describe("是否置顶, `false` 表示取消置顶")
}).describe("set_peer_pin 请求参数");
var SetAvatarInput = object({ uri: string$1().describe("头像文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式") }).describe("set_avatar 请求参数");
var SetNicknameInput = object({ new_nickname: string$1().describe("新昵称") }).describe("set_nickname 请求参数");
var SetBioInput = object({ new_bio: string$1().describe("新个性签名") }).describe("set_bio 请求参数");
var GetCustomFaceUrlListOutput = object({ urls: array(string$1()).describe("自定义表情 URL 列表") }).describe("get_custom_face_url_list 响应数据");
var GetCookiesInput = object({ domain: string$1().describe("需要获取 Cookies 的域名") }).describe("get_cookies 请求参数");
var GetCookiesOutput = object({ cookies: string$1().describe("域名对应的 Cookies 字符串") }).describe("get_cookies 响应数据");
var GetCSRFTokenOutput = object({ csrf_token: string$1().describe("CSRF Token") }).describe("get_csrf_token 响应数据");
var SendPrivateMessageInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	message: array(lazy(() => OutgoingSegment)).describe("消息内容")
}).describe("send_private_message 请求参数");
var SendPrivateMessageOutput = object({
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	time: number$1().int().nonnegative().describe("消息发送时间")
}).describe("send_private_message 响应数据");
var SendGroupMessageInput = object({
	group_id: zUin.describe("群号"),
	message: array(lazy(() => OutgoingSegment)).describe("消息内容")
}).describe("send_group_message 请求参数");
var SendGroupMessageOutput = object({
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	time: number$1().int().nonnegative().describe("消息发送时间")
}).describe("send_group_message 响应数据");
var RecallPrivateMessageInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号")
}).describe("recall_private_message 请求参数");
var RecallGroupMessageInput = object({
	group_id: zUin.describe("群号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号")
}).describe("recall_group_message 请求参数");
var GetMessageInput = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("消息场景"),
	peer_id: zUin.describe("好友 QQ 号或群号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号")
}).describe("get_message 请求参数");
var GetMessageOutput = object({ message: lazy(() => IncomingMessage).describe("消息内容") }).describe("get_message 响应数据");
var GetHistoryMessagesInput = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("消息场景"),
	peer_id: zUin.describe("好友 QQ 号或群号"),
	start_message_seq: number$1().int().nonnegative().nullish().describe("起始消息序列号，由此开始从新到旧查询，不提供则从最新消息开始"),
	limit: number$1().int().nonnegative().nullish().default(20).transform((val) => val ?? 20).describe("期望获取到的消息数量，最多 30 条")
}).describe("get_history_messages 请求参数");
var GetHistoryMessagesOutput = object({
	messages: array(lazy(() => IncomingMessage)).describe("获取到的消息（message_seq 升序排列），部分消息可能不存在，如撤回的消息"),
	next_message_seq: number$1().int().nonnegative().nullish().describe("下一页起始消息序列号")
}).describe("get_history_messages 响应数据");
var GetResourceTempUrlInput = object({ resource_id: string$1().describe("资源 ID") }).describe("get_resource_temp_url 请求参数");
var GetResourceTempUrlOutput = object({ url: string$1().describe("临时资源链接") }).describe("get_resource_temp_url 响应数据");
var GetForwardedMessagesInput = object({ forward_id: string$1().describe("转发消息 ID") }).describe("get_forwarded_messages 请求参数");
var GetForwardedMessagesOutput = object({ messages: array(lazy(() => IncomingForwardedMessage)).describe("转发消息内容") }).describe("get_forwarded_messages 响应数据");
var MarkMessageAsReadInput = object({
	message_scene: _enum([
		"friend",
		"group",
		"temp"
	]).describe("消息场景"),
	peer_id: zUin.describe("好友 QQ 号或群号"),
	message_seq: number$1().int().nonnegative().describe("标为已读的消息序列号，该消息及更早的消息将被标记为已读")
}).describe("mark_message_as_read 请求参数");
var SendFriendNudgeInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	is_self: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否戳自己")
}).describe("send_friend_nudge 请求参数");
var SendProfileLikeInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	count: number$1().int().nonnegative().nullish().default(1).transform((val) => val ?? 1).describe("点赞数量")
}).describe("send_profile_like 请求参数");
var DeleteFriendInput = object({ user_id: zUin.describe("好友 QQ 号") }).describe("delete_friend 请求参数");
var GetFriendRequestsInput = object({
	limit: number$1().int().nonnegative().nullish().default(20).transform((val) => val ?? 20).describe("获取的最大请求数量"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("`true` 表示只获取被过滤（由风险账号发起）的通知，`false` 表示只获取未被过滤的通知")
}).describe("get_friend_requests 请求参数");
var GetFriendRequestsOutput = object({ requests: array(lazy(() => FriendRequest)).describe("好友请求列表") }).describe("get_friend_requests 响应数据");
var AcceptFriendRequestInput = object({
	initiator_uid: string$1().describe("请求发起者 UID"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否是被过滤的请求")
}).describe("accept_friend_request 请求参数");
var RejectFriendRequestInput = object({
	initiator_uid: string$1().describe("请求发起者 UID"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否是被过滤的请求"),
	reason: string$1().nullish().describe("拒绝理由")
}).describe("reject_friend_request 请求参数");
var SetGroupNameInput = object({
	group_id: zUin.describe("群号"),
	new_group_name: string$1().describe("新群名称")
}).describe("set_group_name 请求参数");
var SetGroupAvatarInput = object({
	group_id: zUin.describe("群号"),
	image_uri: string$1().describe("头像文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式")
}).describe("set_group_avatar 请求参数");
var SetGroupMemberCardInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被设置的群成员 QQ 号"),
	card: string$1().describe("新群名片")
}).describe("set_group_member_card 请求参数");
var SetGroupMemberSpecialTitleInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被设置的群成员 QQ 号"),
	special_title: string$1().describe("新专属头衔")
}).describe("set_group_member_special_title 请求参数");
var SetGroupMemberAdminInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被设置的 QQ 号"),
	is_set: boolean$1().nullish().default(true).transform((val) => val ?? true).describe("是否设置为管理员，`false` 表示取消管理员")
}).describe("set_group_member_admin 请求参数");
var SetGroupMemberMuteInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被设置的 QQ 号"),
	duration: number$1().int().nonnegative().nullish().default(0).transform((val) => val ?? 0).describe("禁言持续时间（秒），设为 `0` 为取消禁言")
}).describe("set_group_member_mute 请求参数");
var SetGroupWholeMuteInput = object({
	group_id: zUin.describe("群号"),
	is_mute: boolean$1().nullish().default(true).transform((val) => val ?? true).describe("是否开启全员禁言，`false` 表示取消全员禁言")
}).describe("set_group_whole_mute 请求参数");
var KickGroupMemberInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被踢的 QQ 号"),
	reject_add_request: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否拒绝加群申请，`false` 表示不拒绝")
}).describe("kick_group_member 请求参数");
var GetGroupAnnouncementsInput = object({ group_id: zUin.describe("群号") }).describe("get_group_announcements 请求参数");
var GetGroupAnnouncementsOutput = object({ announcements: array(lazy(() => GroupAnnouncementEntity)).describe("群公告列表") }).describe("get_group_announcements 响应数据");
var SendGroupAnnouncementInput = object({
	group_id: zUin.describe("群号"),
	content: string$1().describe("公告内容"),
	image_uri: string$1().nullish().describe("公告附带图像文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式")
}).describe("send_group_announcement 请求参数");
var DeleteGroupAnnouncementInput = object({
	group_id: zUin.describe("群号"),
	announcement_id: string$1().describe("公告 ID")
}).describe("delete_group_announcement 请求参数");
var GetGroupEssenceMessagesInput = object({
	group_id: zUin.describe("群号"),
	page_index: number$1().int().nonnegative().describe("页码索引，从 0 开始"),
	page_size: number$1().int().nonnegative().describe("每页包含的精华消息数量")
}).describe("get_group_essence_messages 请求参数");
var GetGroupEssenceMessagesOutput = object({
	messages: array(lazy(() => GroupEssenceMessage)).describe("精华消息列表"),
	is_end: boolean$1().describe("是否已到最后一页")
}).describe("get_group_essence_messages 响应数据");
var SetGroupEssenceMessageInput = object({
	group_id: zUin.describe("群号"),
	message_seq: number$1().int().nonnegative().describe("消息序列号"),
	is_set: boolean$1().nullish().default(true).transform((val) => val ?? true).describe("是否设置为精华消息，`false` 表示取消精华")
}).describe("set_group_essence_message 请求参数");
var QuitGroupInput = object({ group_id: zUin.describe("群号") }).describe("quit_group 请求参数");
var SendGroupMessageReactionInput = object({
	group_id: zUin.describe("群号"),
	message_seq: number$1().int().nonnegative().describe("要回应的消息序列号"),
	reaction: string$1().describe("发送的回应的表情 ID"),
	reaction_type: _enum(["face", "emoji"]).nullish().default("face").transform((val) => val ?? "face").describe("发送的回应类型"),
	is_add: boolean$1().nullish().default(true).transform((val) => val ?? true).describe("是否添加表情，`false` 表示取消")
}).describe("send_group_message_reaction 请求参数");
var SendGroupNudgeInput = object({
	group_id: zUin.describe("群号"),
	user_id: zUin.describe("被戳的群成员 QQ 号")
}).describe("send_group_nudge 请求参数");
var GetGroupNotificationsInput = object({
	start_notification_seq: number$1().int().nonnegative().nullish().describe("起始通知序列号"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("`true` 表示只获取被过滤（由风险账号发起）的通知，`false` 表示只获取未被过滤的通知"),
	limit: number$1().int().nonnegative().nullish().default(20).transform((val) => val ?? 20).describe("获取的最大通知数量")
}).describe("get_group_notifications 请求参数");
var GetGroupNotificationsOutput = object({
	notifications: zDropBadElementArray(GroupNotification).describe("获取到的群通知（notification_seq 降序排列），序列号不一定连续"),
	next_notification_seq: number$1().int().nonnegative().nullish().describe("下一页起始通知序列号")
}).describe("get_group_notifications 响应数据");
var AcceptGroupRequestInput = object({
	notification_seq: number$1().int().nonnegative().describe("请求对应的通知序列号"),
	notification_type: _enum(["join_request", "invited_join_request"]).describe("请求对应的通知类型"),
	group_id: zUin.describe("请求所在的群号"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否是被过滤的请求")
}).describe("accept_group_request 请求参数");
var RejectGroupRequestInput = object({
	notification_seq: number$1().int().nonnegative().describe("请求对应的通知序列号"),
	notification_type: _enum(["join_request", "invited_join_request"]).describe("请求对应的通知类型"),
	group_id: zUin.describe("请求所在的群号"),
	is_filtered: boolean$1().nullish().default(false).transform((val) => val ?? false).describe("是否是被过滤的请求"),
	reason: string$1().nullish().describe("拒绝理由")
}).describe("reject_group_request 请求参数");
var AcceptGroupInvitationInput = object({
	group_id: zUin.describe("群号"),
	invitation_seq: number$1().int().nonnegative().describe("邀请序列号")
}).describe("accept_group_invitation 请求参数");
var RejectGroupInvitationInput = object({
	group_id: zUin.describe("群号"),
	invitation_seq: number$1().int().nonnegative().describe("邀请序列号")
}).describe("reject_group_invitation 请求参数");
var UploadPrivateFileInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	file_uri: string$1().describe("文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式"),
	file_name: string$1().describe("文件名称")
}).describe("upload_private_file 请求参数");
var UploadPrivateFileOutput = object({ file_id: string$1().describe("文件 ID") }).describe("upload_private_file 响应数据");
var UploadGroupFileInput = object({
	group_id: zUin.describe("群号"),
	parent_folder_id: string$1().nullish().default("/").transform((val) => val ?? "/").describe("目标文件夹 ID"),
	file_uri: string$1().describe("文件 URI，支持 `file://` `http(s)://` `base64://` 三种格式"),
	file_name: string$1().describe("文件名称")
}).describe("upload_group_file 请求参数");
var UploadGroupFileOutput = object({ file_id: string$1().describe("文件 ID") }).describe("upload_group_file 响应数据");
var GetPrivateFileDownloadUrlInput = object({
	user_id: zUin.describe("好友 QQ 号"),
	file_id: string$1().describe("文件 ID"),
	file_hash: string$1().describe("文件的 TriSHA1 哈希值")
}).describe("get_private_file_download_url 请求参数");
var GetPrivateFileDownloadUrlOutput = object({ download_url: string$1().describe("文件下载链接") }).describe("get_private_file_download_url 响应数据");
var GetGroupFileDownloadUrlInput = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID")
}).describe("get_group_file_download_url 请求参数");
var GetGroupFileDownloadUrlOutput = object({ download_url: string$1().describe("文件下载链接") }).describe("get_group_file_download_url 响应数据");
var GetGroupFilesInput = object({
	group_id: zUin.describe("群号"),
	parent_folder_id: string$1().nullish().default("/").transform((val) => val ?? "/").describe("父文件夹 ID")
}).describe("get_group_files 请求参数");
var GetGroupFilesOutput = object({
	files: array(lazy(() => GroupFileEntity)).describe("文件列表"),
	folders: array(lazy(() => GroupFolderEntity)).describe("文件夹列表")
}).describe("get_group_files 响应数据");
var MoveGroupFileInput = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID"),
	parent_folder_id: string$1().nullish().default("/").transform((val) => val ?? "/").describe("文件所在的文件夹 ID"),
	target_folder_id: string$1().nullish().default("/").transform((val) => val ?? "/").describe("目标文件夹 ID")
}).describe("move_group_file 请求参数");
var RenameGroupFileInput = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID"),
	parent_folder_id: string$1().nullish().default("/").transform((val) => val ?? "/").describe("文件所在的文件夹 ID"),
	new_file_name: string$1().describe("新文件名称")
}).describe("rename_group_file 请求参数");
var DeleteGroupFileInput = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID")
}).describe("delete_group_file 请求参数");
var PersistGroupFileInput = object({
	group_id: zUin.describe("群号"),
	file_id: string$1().describe("文件 ID")
}).describe("persist_group_file 请求参数");
var CreateGroupFolderInput = object({
	group_id: zUin.describe("群号"),
	folder_name: string$1().describe("文件夹名称")
}).describe("create_group_folder 请求参数");
var CreateGroupFolderOutput = object({ folder_id: string$1().describe("文件夹 ID") }).describe("create_group_folder 响应数据");
var RenameGroupFolderInput = object({
	group_id: zUin.describe("群号"),
	folder_id: string$1().describe("文件夹 ID"),
	new_folder_name: string$1().describe("新文件夹名")
}).describe("rename_group_folder 请求参数");
var DeleteGroupFolderInput = object({
	group_id: zUin.describe("群号"),
	folder_id: string$1().describe("文件夹 ID")
}).describe("delete_group_folder 请求参数");
//#endregion
//#region src/milky/common/download.ts
async function getResponse(url, headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0 Win64 x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36" }, useReferer = false) {
	if (useReferer && !headers["Referer"]) headers["Referer"] = url;
	return await fetch(url, { headers });
}
async function download(url, headers) {
	let resp = await getResponse(url, headers, false);
	if (resp.status === 403 && !headers) resp = await getResponse(url, headers, true);
	if (!resp.ok) throw new Error(`Failed to download file from ${url}: ${resp.status} ${resp.statusText}`);
	const bytes = await resp.blob().then((b) => b.arrayBuffer());
	return Buffer.from(bytes);
}
async function resolveMilkyUri(uri) {
	if (uri.startsWith("file://")) return await fsPromise.readFile(fileURLToPath(uri));
	if (uri.startsWith("http://") || uri.startsWith("https://")) return await download(uri);
	if (uri.startsWith("base64://")) return Buffer.from(uri.slice(9), "base64");
	throw new Error(`Unsupported URI scheme: ${uri}`);
}
var SystemApi = [
	defineApi("get_login_info", zod_default.object({}), GetLoginInfoOutput, async (ctx) => {
		for (let i = 0; i < 5; i++) try {
			await ctx.ntUserApi.getSelfNick(true);
			break;
		} catch {
			await sleep(500);
		}
		return Ok({
			uin: +selfInfo.uin,
			nickname: selfInfo.nick
		});
	}),
	defineApi("get_impl_info", zod_default.object({}), GetImplInfoOutput, async (ctx) => {
		const deviceInfo = await ctx.ntSystemApi.getDeviceInfo();
		return Ok({
			impl_name: "LLBot",
			impl_version: version$3,
			qq_protocol_version: deviceInfo.buildVer,
			qq_protocol_type: transformProtocolOsType(deviceInfo.devType),
			milky_version: "1.3"
		});
	}),
	defineApi("get_user_profile", GetUserProfileInput, GetUserProfileOutput, async (ctx, payload) => {
		const info = await ctx.ntUserApi.getUserByUin(payload.user_id);
		return Ok({
			nickname: info.nick,
			qid: info.qid,
			age: info.age,
			sex: transformGender(info.gender),
			remark: info.remark,
			bio: info.bio,
			level: info.level,
			country: info.country,
			city: info.city,
			school: info.school
		});
	}),
	defineApi("get_friend_list", GetFriendListInput, GetFriendListOutput, async (ctx, payload) => {
		const result = await ctx.ntFriendApi.getFriends(payload.no_cache);
		const friendList = [];
		for (const friend of result.friends) friendList.push(transformFriend(friend));
		return Ok({ friends: friendList });
	}),
	defineApi("get_friend_info", GetFriendInfoInput, GetFriendInfoOutput, async (ctx, payload) => {
		const result = await ctx.ntFriendApi.getFriendByUin(payload.user_id, payload.no_cache);
		if (!result) return Failed(-404, "Friend not found");
		return Ok({ friend: transformFriend(result) });
	}),
	defineApi("get_group_list", GetGroupListInput, GetGroupListOutput, async (ctx, payload) => {
		return Ok({ groups: (await ctx.ntGroupApi.getGroups(payload.no_cache)).map((e) => {
			return {
				group_id: e.groupCode,
				group_name: e.groupName,
				member_count: e.memberCount,
				max_member_count: e.maxMemberCount,
				remark: e.remark,
				created_time: e.createdAt,
				description: e.description,
				question: e.question,
				announcement: e.announcementPreview
			};
		}) });
	}),
	defineApi("get_group_info", GetGroupInfoInput, GetGroupInfoOutput, async (ctx, payload) => {
		return Ok({ group: transformGroup(await ctx.ntGroupApi.getGroup(payload.group_id, payload.no_cache)) });
	}),
	defineApi("get_group_member_list", GetGroupMemberListInput, GetGroupMemberListOutput, async (ctx, payload) => {
		return Ok({ members: (await ctx.ntGroupApi.getGroupMembers(payload.group_id, payload.no_cache)).map((e) => transformGroupMember(e, payload.group_id)) });
	}),
	defineApi("get_group_member_info", GetGroupMemberInfoInput, GetGroupMemberInfoOutput, async (ctx, payload) => {
		const member = await ctx.ntGroupApi.getGroupMemberByUin(payload.group_id, payload.user_id, payload.no_cache);
		if (!member) return Failed(-404, "Member not found");
		return Ok({ member: transformGroupMember(member, payload.group_id) });
	}),
	defineApi("get_peer_pins", zod_default.object({}), GetPeerPinsOutput, async (ctx) => {
		const result = await ctx.ntMsgApi.getPins();
		return Ok({
			friends: await Promise.all(result.friends.map(async (e) => {
				return transformFriend(await ctx.ntFriendApi.getFriendByUid(e.uid, false));
			})),
			groups: await Promise.all(result.groups.map(async (e) => {
				return transformGroup(await ctx.ntGroupApi.getGroup(e.groupCode, false));
			}))
		});
	}),
	defineApi("set_peer_pin", SetPeerPinInput, zod_default.object({}), async (ctx, payload) => {
		if (payload.message_scene === "friend") {
			const uid = await ctx.ntUserApi.getUidByUin(payload.peer_id);
			await ctx.ntFriendApi.setFriendPin(uid, payload.is_pinned);
		} else if (payload.message_scene === "group") await ctx.ntGroupApi.setGroupPin(payload.peer_id, payload.is_pinned);
		else return Failed(-400, `Unknown message scene: ${payload.message_scene}`);
		return Ok({});
	}),
	defineApi("set_avatar", SetAvatarInput, zod_default.object({}), async (ctx, payload) => {
		const data = await resolveMilkyUri(payload.uri);
		const tempPath = path.join(TEMP_DIR, `avatar-${randomUUID()}`);
		await writeFile(tempPath, data);
		const result = await ctx.ntUserApi.setSelfAvatar(tempPath);
		unlink(tempPath).catch(noop);
		if (result.result !== 0) return Failed(-500, result.errMsg);
		return Ok({});
	}),
	defineApi("set_nickname", SetNicknameInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntUserApi.modifySelfProfile({ nick: payload.new_nickname });
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_bio", SetBioInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntUserApi.modifySelfProfile({ bio: payload.new_bio });
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("get_custom_face_url_list", zod_default.object({}), GetCustomFaceUrlListOutput, async (ctx) => {
		const result = await ctx.ntMsgApi.getCustomFaceList();
		if (result.retCode !== 0) return Failed(-500, result.errMsg);
		return Ok({ urls: result.emojiInfoList.map((e) => e.url) });
	}),
	defineApi("get_cookies", GetCookiesInput, GetCookiesOutput, async (ctx, payload) => {
		if (["pay.qq.com"].includes(payload.domain)) throw new Error("该域名禁止获取cookie");
		const cookiesObject = await ctx.ntWebApi.getCookies(payload.domain);
		if (!cookiesObject.p_skey) {
			const pSkey = (await ctx.ntUserApi.getPSkey([payload.domain])).get(payload.domain);
			if (pSkey) cookiesObject.p_skey = pSkey;
		}
		return Ok({ cookies: Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join("; ") });
	}),
	defineApi("get_csrf_token", zod_default.object({}), GetCSRFTokenOutput, async (ctx) => {
		const cookiesObject = await ctx.ntWebApi.getCookies("h5.qzone.qq.com");
		return Ok({ csrf_token: ctx.ntWebApi.genBkn(cookiesObject.skey) });
	})
];
//#endregion
//#region src/milky/transform/message/outgoing.ts
async function transformOutgoingMessage(ctx, segments, peerUid, isGroup, isInsideForward) {
	const elements = [];
	const deleteAfterSentFiles = [];
	for (const segment of segments) try {
		if (segment.type === "text") elements.push(SendElement.text(segment.data.text));
		else if (segment.type === "mention" && isGroup) {
			const memberUin = segment.data.user_id;
			const info = await ctx.ntGroupApi.getGroupMemberByUin(+peerUid, memberUin, false);
			elements.push(SendElement.at(memberUin, AtType.One, `@${info?.cardName || info?.nick || ""}`));
		} else if (segment.type === "mention_all" && isGroup) elements.push(SendElement.at(0, AtType.All, "@全体成员"));
		else if (segment.type === "face") elements.push(SendElement.face(+segment.data.face_id, segment.data.is_large ? 3 : void 0));
		else if (segment.type === "reply") {
			const peer = {
				chatType: isGroup ? 2 : 1,
				peerUid,
				guildId: ""
			};
			let msg = ctx.store.getMsgBySeq(peer.peerUid, segment.data.message_seq);
			let srcMsg;
			let fetchFromServer = false;
			if (!msg) {
				const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, segment.data.message_seq);
				msg = msgList[0];
				fetchFromServer = true;
			}
			if (!msg) throw new Error("被回复的消息未找到");
			if (isInsideForward) {
				if (msg.rawPb) srcMsg = Buffer.from(msg.rawPb, "hex");
				else if (!fetchFromServer) {
					const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, segment.data.message_seq);
					srcMsg = msgList[0]?.rawPb ? Buffer.from(msgList[0].rawPb, "hex") : void 0;
				}
			}
			elements.push(SendElement.reply(segment.data.message_seq, msg.senderUin, msg.senderUid, msg.msgTime, msg.clientSeq, srcMsg));
		} else if (segment.type === "image") {
			const imageBuffer = await resolveMilkyUri(segment.data.uri);
			const tempPath = path.join(TEMP_DIR, `image-${randomUUID()}`);
			await writeFile(tempPath, imageBuffer);
			const subType = segment.data.sub_type === "sticker" ? 1 : 0;
			const picElement = await SendElement.pic(ctx, tempPath, segment.data.summary ?? "", subType);
			elements.push(picElement);
			deleteAfterSentFiles.push(tempPath);
		} else if (segment.type === "record") {
			const recordBuffer = await resolveMilkyUri(segment.data.uri);
			const tempPath = path.join(TEMP_DIR, `audio-${randomUUID()}`);
			await writeFile(tempPath, recordBuffer);
			const pttElement = await SendElement.ptt(ctx, tempPath);
			elements.push(pttElement);
			deleteAfterSentFiles.push(tempPath);
		} else if (segment.type === "video") {
			const videoBuffer = await resolveMilkyUri(segment.data.uri);
			const tempPath = path.join(TEMP_DIR, `video-${randomUUID()}`);
			await writeFile(tempPath, videoBuffer);
			let thumbTempPath = void 0;
			if (segment.data.thumb_uri) {
				const thumbBuffer = await resolveMilkyUri(segment.data.thumb_uri);
				thumbTempPath = path.join(TEMP_DIR, `thumb-${randomUUID()}`);
				await writeFile(thumbTempPath, thumbBuffer);
				deleteAfterSentFiles.push(thumbTempPath);
			}
			const videoElement = await SendElement.video(ctx, tempPath, thumbTempPath);
			elements.push(videoElement);
			deleteAfterSentFiles.push(tempPath);
		} else if (segment.type === "forward") {
			const { data } = segment;
			const nodes = [];
			let seq = Math.trunc(Math.random() * 65430);
			for (const item of data.messages) {
				const res = await transformOutgoingMessage(ctx, item.segments, peerUid, isGroup, true);
				deleteAfterSentFiles.push(...res.deleteAfterSentFiles);
				nodes.push({
					senderUin: item.user_id,
					senderName: item.sender_name,
					elements: res.elements,
					msgSeq: seq++,
					msgTime: item.time ?? void 0
				});
			}
			elements.push(SendElement.forward(nodes, data.title, data.preview, data.summary, data.prompt));
		} else if (segment.type === "light_app") {
			const arkElement = SendElement.ark(segment.data.json_payload);
			elements.push(arkElement);
		}
	} catch (error) {
		ctx.logger.error("MilkyTransform", `Failed to transform segment ${segment.type}: ${error}`);
	}
	return {
		elements,
		deleteAfterSentFiles
	};
}
//#endregion
//#region src/milky/transform/message/incoming.ts
async function transformIncomingPrivateMessage(ctx, friend, message) {
	return {
		message_scene: "friend",
		peer_id: +message.peerUin,
		message_seq: +message.msgSeq,
		sender_id: +message.senderUin,
		time: +message.msgTime,
		segments: await transformIncomingSegments(ctx, message),
		friend: transformFriend(friend)
	};
}
async function transformIncomingGroupMessage(ctx, group, member, message) {
	return {
		message_scene: "group",
		peer_id: +message.peerUin,
		message_seq: +message.msgSeq,
		sender_id: +message.senderUin,
		time: +message.msgTime,
		segments: await transformIncomingSegments(ctx, message),
		group: transformGroup(group),
		group_member: transformGroupMember(member, +group.groupCode)
	};
}
async function transformIncomingTempMessage(ctx, group, message) {
	return {
		message_scene: "temp",
		peer_id: +message.peerUin,
		message_seq: +message.msgSeq,
		sender_id: +message.senderUin,
		time: +message.msgTime,
		segments: await transformIncomingSegments(ctx, message),
		group: transformGroup(group)
	};
}
async function transformIncomingSegments(ctx, message) {
	const segments = [];
	const markdown = message.elements.find((e) => e.markdownElement);
	if (markdown) segments.push({
		type: "markdown",
		data: { content: markdown.markdownElement.content }
	});
	else for (const element of message.elements) switch (element.elementType) {
		case ElementType.Text:
			if (element.textElement?.atType === AtType.All) segments.push({
				type: "mention_all",
				data: {}
			});
			else if (element.textElement?.atType === AtType.One) segments.push({
				type: "mention",
				data: {
					user_id: element.textElement.atUin,
					name: element.textElement.content.slice(1)
				}
			});
			else if (element.textElement?.content) segments.push({
				type: "text",
				data: { text: element.textElement.content }
			});
			break;
		case ElementType.Face:
			segments.push({
				type: "face",
				data: {
					face_id: element.faceElement.faceIndex.toString(),
					is_large: element.faceElement.faceType === 3
				}
			});
			break;
		case ElementType.Reply: {
			const { replyMsgSeq, senderUin, replyMsgTime, replyMsgClientSeq } = element.replyElement;
			const peer = {
				chatType: message.chatType,
				peerUid: message.peerUid
			};
			let msg = ctx.store.getMsgBySeq(message.peerUid, replyMsgSeq);
			if (!msg) {
				const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, replyMsgSeq);
				msg = msgList[0];
			}
			if (!msg && peer.chatType !== ChatType.Group) {
				const { msgList } = await ctx.ntMsgApi.getC2CMsgsByTimeAndCount(peer, replyMsgTime + 1, 3, true);
				msg = msgList.find((e) => e.clientSeq === replyMsgClientSeq);
			}
			segments.push({
				type: "reply",
				data: {
					message_seq: replyMsgSeq,
					sender_id: senderUin,
					time: replyMsgTime,
					segments: msg ? await transformIncomingSegments(ctx, msg) : []
				}
			});
			break;
		}
		case ElementType.Pic:
			segments.push({
				type: "image",
				data: {
					resource_id: element.picElement.fileUuid,
					temp_url: await ctx.ntFileApi.getImageUrl(element.picElement.originImageUrl, element.picElement.md5HexStr),
					width: element.picElement.picWidth,
					height: element.picElement.picHeight,
					summary: element.picElement.summary || "[图片]",
					sub_type: element.picElement.picSubType === 1 ? "sticker" : "normal"
				}
			});
			break;
		case ElementType.Ptt:
			segments.push({
				type: "record",
				data: {
					resource_id: element.pttElement.fileUuid,
					temp_url: await ctx.ntFileApi.getPttUrl(element.pttElement.fileUuid, message.chatType === 2),
					duration: element.pttElement.duration
				}
			});
			break;
		case ElementType.Video:
			segments.push({
				type: "video",
				data: {
					resource_id: element.videoElement.fileUuid,
					temp_url: await ctx.ntFileApi.getVideoUrl(element.videoElement.fileUuid, message.chatType === ChatType.Group),
					width: element.videoElement.thumbWidth,
					height: element.videoElement.thumbHeight,
					duration: element.videoElement.fileTime
				}
			});
			break;
		case ElementType.File:
			segments.push({
				type: "file",
				data: {
					file_id: element.fileElement.fileUuid,
					file_name: element.fileElement.fileName,
					file_size: +element.fileElement.fileSize
				}
			});
			break;
		case ElementType.MultiForward: {
			const content = new XMLParser().parse(element.multiForwardMsgElement.xmlContent);
			segments.push({
				type: "forward",
				data: {
					forward_id: element.multiForwardMsgElement.resId,
					title: content.msg.item.title[0],
					preview: content.msg.item.title.slice(1),
					summary: content.msg.item.summary
				}
			});
			break;
		}
		case ElementType.MarketFace:
			segments.push({
				type: "market_face",
				data: {
					emoji_package_id: element.marketFaceElement.emojiPackageId,
					emoji_id: element.marketFaceElement.emojiId,
					key: element.marketFaceElement.key,
					summary: element.marketFaceElement.faceName,
					url: `https://gxh.vip.qq.com/club/item/parcel/item/${element.marketFaceElement.emojiId.substring(0, 2)}/${element.marketFaceElement.emojiId}/raw300.gif`
				}
			});
			break;
		case ElementType.Ark: {
			const { arkElement } = element;
			const match = arkElement.bytesData.match(/"app"\s*:\s*"([^"]*)"/);
			if (match?.[1]) if (match[1] === "com.tencent.multimsg") {
				const data = JSON.parse(arkElement.bytesData);
				segments.push({
					type: "forward",
					data: {
						forward_id: data.meta.detail.resid,
						title: data.meta.detail.source,
						preview: data.meta.detail.news.map((item) => item.text),
						summary: data.meta.detail.summary
					}
				});
			} else segments.push({
				type: "light_app",
				data: {
					app_name: match[1],
					json_payload: arkElement.bytesData
				}
			});
			break;
		}
	}
	return segments;
}
async function transformIncomingForwardedMessage(ctx, message) {
	return {
		message_seq: message.msgSeq,
		sender_name: message.sendNickName,
		avatar_url: message.forwardAvatar,
		time: message.msgTime,
		segments: await transformIncomingSegments(ctx, message)
	};
}
//#endregion
//#region src/milky/api/message.ts
var SendPrivateMessage = defineApi("send_private_message", SendPrivateMessageInput, SendPrivateMessageOutput, async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(payload.user_id);
	if (!uid) return Failed(-404, "User not found");
	const peer = {
		chatType: 1,
		peerUid: uid,
		guildId: ""
	};
	if (!await ctx.ntFriendApi.isFriend(uid)) peer.chatType = 100;
	const { elements, deleteAfterSentFiles } = await transformOutgoingMessage(ctx, payload.message, uid, false, false);
	const result = await ctx.app.sendMessage(ctx, peer, elements, deleteAfterSentFiles);
	return Ok({
		message_seq: +result.msgSeq,
		time: +result.msgTime
	});
});
var SendGroupMessage = defineApi("send_group_message", SendGroupMessageInput, SendGroupMessageOutput, async (ctx, payload) => {
	const groupCode = payload.group_id.toString();
	const peer = {
		chatType: 2,
		peerUid: groupCode,
		guildId: ""
	};
	const { elements, deleteAfterSentFiles } = await transformOutgoingMessage(ctx, payload.message, groupCode, true, false);
	const result = await ctx.app.sendMessage(ctx, peer, elements, deleteAfterSentFiles);
	return Ok({
		message_seq: +result.msgSeq,
		time: +result.msgTime
	});
});
var RecallPrivateMessage = defineApi("recall_private_message", RecallPrivateMessageInput, zod_default.object({}), async (ctx, payload) => {
	const uid = await ctx.ntUserApi.getUidByUin(payload.user_id);
	if (!uid) return Failed(-404, "User not found");
	const peer = {
		chatType: ChatType.C2C,
		peerUid: uid,
		guildId: ""
	};
	if (!await ctx.ntFriendApi.isFriend(uid)) peer.chatType = ChatType.TempC2CFromGroup;
	let msg = ctx.store.getMsgBySeq(peer.peerUid, payload.message_seq);
	if (!msg) {
		const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, payload.message_seq);
		msg = msgList[0];
	}
	await ctx.ntMsgApi.recallMsg(peer, msg.msgSeq, msg.clientSeq, msg.msgRandom, +msg.msgTime);
	return Ok({});
});
var RecallGroupMessage = defineApi("recall_group_message", RecallGroupMessageInput, zod_default.object({}), async (ctx, payload) => {
	const peer = {
		chatType: ChatType.Group,
		peerUid: payload.group_id.toString(),
		guildId: ""
	};
	await ctx.ntMsgApi.recallMsg(peer, payload.message_seq);
	return Ok({});
});
var MessageApi = [
	SendPrivateMessage,
	SendGroupMessage,
	defineApi("get_message", GetMessageInput, GetMessageOutput, async (ctx, payload) => {
		const peer = {
			chatType: {
				friend: ChatType.C2C,
				group: ChatType.Group,
				temp: ChatType.TempC2CFromGroup
			}[payload.message_scene],
			peerUid: payload.peer_id.toString(),
			guildId: ""
		};
		if (peer.chatType === ChatType.C2C || peer.chatType === ChatType.TempC2CFromGroup) {
			const uid = await ctx.ntUserApi.getUidByUin(+peer.peerUid);
			if (!uid) return Failed(-404, "User not found");
			peer.peerUid = uid;
		}
		const msgResult = await ctx.ntMsgApi.getSingleMsg(peer, payload.message_seq);
		if (msgResult.msgList.length === 0) return Failed(-404, "Message not found");
		const rawMsg = msgResult.msgList[0];
		let message;
		if (payload.message_scene === "friend") message = await transformIncomingPrivateMessage(ctx, await ctx.ntFriendApi.getFriendByUid(rawMsg.senderUid, false), rawMsg);
		else if (payload.message_scene === "group") message = await transformIncomingGroupMessage(ctx, await ctx.ntGroupApi.getGroup(rawMsg.peerUin, false), {
			...await ctx.ntGroupApi.getGroupMemberByUid(rawMsg.peerUin, rawMsg.senderUid, false),
			role: rawMsg.memberRole
		}, rawMsg);
		else message = await transformIncomingTempMessage(ctx, await ctx.ntGroupApi.getGroup(rawMsg.tempFromGroupCode, false), rawMsg);
		if (message.segments.length === 0) return Failed(-404, "Message not found");
		return Ok({ message });
	}),
	defineApi("get_history_messages", GetHistoryMessagesInput, GetHistoryMessagesOutput, async (ctx, payload) => {
		const peer = {
			chatType: {
				friend: 1,
				group: 2,
				temp: 100
			}[payload.message_scene],
			peerUid: payload.peer_id.toString(),
			guildId: ""
		};
		if (peer.chatType === 1 || peer.chatType === 100) {
			const uid = await ctx.ntUserApi.getUidByUin(+peer.peerUid);
			if (!uid) return Failed(-404, "User not found");
			peer.peerUid = uid;
		}
		let msgList;
		if (!payload.start_message_seq) {
			const latestSeq = await ctx.ntMsgApi.getLatestMsgSeq(peer);
			msgList = (await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, latestSeq, payload.limit, true)).msgList;
		} else msgList = (await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, payload.start_message_seq, payload.limit, true)).msgList;
		if (msgList.length === 0) return Ok({
			messages: [],
			next_message_seq: void 0
		});
		const transformedMessages = [];
		if (payload.message_scene === "friend") {
			const friend = await ctx.ntFriendApi.getFriendByUid(msgList[0].peerUid, false);
			for (const msg of msgList) transformedMessages.push(await transformIncomingPrivateMessage(ctx, friend, msg));
		} else if (payload.message_scene === "group") {
			const group = await ctx.ntGroupApi.getGroup(payload.peer_id, false);
			const infos = /* @__PURE__ */ new Map();
			for (const msg of msgList) {
				const member = await ctx.ntGroupApi.getGroupMemberByUid(msg.peerUin, msg.senderUid, false);
				if (member) transformedMessages.push(await transformIncomingGroupMessage(ctx, group, {
					...member,
					role: msg.memberRole
				}, msg));
				else {
					let info;
					if (infos.has(msg.senderUid)) info = infos.get(msg.senderUid);
					else {
						info = await ctx.ntUserApi.getUserByUid(msg.senderUid);
						infos.set(msg.senderUid, info);
					}
					transformedMessages.push(await transformIncomingGroupMessage(ctx, group, {
						uin: info.uin,
						uid: msg.senderUid,
						nick: info.nick,
						cardName: "",
						specialTitle: "",
						level: 0,
						joinedAt: 0,
						lastSpokeAt: 0,
						shutupExpireTime: 0,
						role: GroupMemberRole.Normal
					}, msg));
				}
			}
		} else {
			let group;
			for (const msg of msgList) {
				group ??= await ctx.ntGroupApi.getGroup(msg.tempFromGroupCode, false);
				transformedMessages.push(await transformIncomingTempMessage(ctx, group, msg));
			}
		}
		let nextMessageSeq = void 0;
		if (msgList.length > 0) {
			const seq = +msgList[0].msgSeq - 1;
			if (seq >= 0) nextMessageSeq = seq;
		}
		return Ok({
			messages: transformedMessages.filter((e) => e.segments.length > 0),
			next_message_seq: nextMessageSeq
		});
	}),
	defineApi("get_resource_temp_url", GetResourceTempUrlInput, GetResourceTempUrlOutput, async (ctx, payload) => {
		const buffer = Buffer.from(payload.resource_id, "base64url");
		const { appid } = Media.FileIdInfo.decode(buffer);
		if (appid === 1402 || appid === 1403) return Ok({ url: await ctx.ntFileApi.getPttUrl(payload.resource_id, appid === 1403) });
		else if (appid === 1406 || appid === 1407) {
			const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey(true);
			const rkey = appid === 1406 ? rkeyData.private_rkey : rkeyData.group_rkey;
			return Ok({ url: `${IMAGE_HTTP_HOST_NT}/download?appid=${appid}&fileid=${payload.resource_id}&spec=0${rkey}` });
		} else if (appid === 1413 || appid === 1415) return Ok({ url: await ctx.ntFileApi.getVideoUrl(payload.resource_id, appid === 1415) });
		else {
			ctx.logger.warn(`GetResourceTempUrl: not yet supported appid: ${appid}`);
			return Ok({ url: "" });
		}
	}),
	RecallPrivateMessage,
	RecallGroupMessage,
	defineApi("get_forwarded_messages", GetForwardedMessagesInput, GetForwardedMessagesOutput, async (ctx, payload) => {
		const result = await ctx.ntMsgApi.getForwardedMsgs(payload.forward_id);
		return Ok({ messages: await Promise.all(result.msgList.map((e) => transformIncomingForwardedMessage(ctx, e))) });
	}),
	defineApi("mark_message_as_read", MarkMessageAsReadInput, zod_default.object({}), async (ctx, payload) => {
		const peer = {
			chatType: {
				friend: 1,
				group: 2,
				temp: 100
			}[payload.message_scene],
			peerUid: payload.peer_id.toString(),
			guildId: ""
		};
		if (peer.chatType === 1 || peer.chatType === 100) {
			const uid = await ctx.ntUserApi.getUidByUin(+peer.peerUid);
			if (!uid) return Failed(-404, "User not found");
			peer.peerUid = uid;
		}
		const result = await ctx.ntMsgApi.setMsgRead(peer, payload.message_seq);
		if (result.retCode !== 0) return Failed(-500, result.retMsg);
		return Ok({});
	})
];
var FriendApi = [
	defineApi("send_friend_nudge", SendFriendNudgeInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntFriendApi.sendFriendNudge(payload.user_id, payload.is_self);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("send_profile_like", SendProfileLikeInput, zod_default.object({}), async (ctx, payload) => {
		const uid = await ctx.ntUserApi.getUidByUin(payload.user_id);
		if (!uid) return Failed(-404, "User not found");
		const result = await ctx.ntUserApi.sendProfileLike(uid, payload.count);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("delete_friend", DeleteFriendInput, zod_default.object({}), async (ctx, payload) => {
		const uid = await ctx.ntUserApi.getUidByUin(payload.user_id);
		if (!uid) return Failed(-404, "User not found");
		const result = await ctx.ntFriendApi.deleteFriend(uid);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("get_friend_requests", GetFriendRequestsInput, GetFriendRequestsOutput, async (ctx, payload) => {
		if (payload.is_filtered) {
			const result = await ctx.ntFriendApi.getDoubtFriendRequests(payload.limit);
			return Ok({ requests: await Promise.all(result.map(async (e) => ({
				time: e.timestamp,
				initiator_id: Number(await ctx.ntUserApi.getUinByUid(e.sourceUid)),
				initiator_uid: e.sourceUid,
				target_user_id: Number(selfInfo.uin),
				target_user_uid: selfInfo.uid,
				state: "pending",
				comment: e.comment,
				via: e.source,
				is_filtered: true
			}))) });
		} else {
			const result = await ctx.ntFriendApi.getFriendRequests(payload.limit);
			return Ok({ requests: await Promise.all(result.map(async (e) => {
				const friendId = Number(await ctx.ntUserApi.getUinByUid(e.friendUid));
				const selfId = Number(selfInfo.uin);
				return {
					time: e.timestamp,
					initiator_id: e.isInitiator ? selfId : friendId,
					initiator_uid: e.isInitiator ? selfInfo.uid : e.friendUid,
					target_user_id: e.isInitiator ? friendId : selfId,
					target_user_uid: e.isInitiator ? e.friendUid : selfInfo.uid,
					state: {
						[FriendReqType.PeerInitiator]: "pending",
						[FriendReqType.MeInitiatorWaitPeerConfirm]: "pending",
						[FriendReqType.MeAgreed]: "accepted",
						[FriendReqType.MeAgreedAndAdded]: "accepted",
						[FriendReqType.PeerAgreed]: "accepted",
						[FriendReqType.PeerAgreedAndAdded]: "accepted",
						[FriendReqType.PeerRefused]: "rejected",
						[FriendReqType.MeRefused]: "rejected"
					}[e.state] ?? "pending",
					comment: e.comment,
					via: e.source,
					is_filtered: false
				};
			})) });
		}
	}),
	defineApi("accept_friend_request", AcceptFriendRequestInput, zod_default.object({}), async (ctx, payload) => {
		let result;
		if (payload.is_filtered) result = await ctx.ntFriendApi.approvalDoubtFriendRequest(payload.initiator_uid);
		else result = await ctx.ntFriendApi.approvalFriendRequest(payload.initiator_uid, true);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("reject_friend_request", RejectFriendRequestInput, zod_default.object({}), async (ctx, payload) => {
		if (!payload.is_filtered) {
			const result = await ctx.ntFriendApi.approvalFriendRequest(payload.initiator_uid, false);
			if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		}
		return Ok({});
	})
];
var GroupApi = [
	defineApi("set_group_name", SetGroupNameInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.setGroupName(payload.group_id, payload.new_group_name);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_group_avatar", SetGroupAvatarInput, zod_default.object({}), async (ctx, payload) => {
		const imageBuffer = await resolveMilkyUri(payload.image_uri);
		const tempPath = path.join(TEMP_DIR, `group-avatar-${randomUUID()}`);
		await writeFile(tempPath, imageBuffer);
		const result = await ctx.ntGroupApi.setGroupAvatar(payload.group_id.toString(), tempPath);
		unlink(tempPath).catch(noop);
		if (result.result !== 0) return Failed(-500, result.errMsg);
		return Ok({});
	}),
	defineApi("set_group_member_card", SetGroupMemberCardInput, zod_default.object({}), async (ctx, payload) => {
		const memberUid = await ctx.ntUserApi.getUidByUin(payload.user_id, payload.group_id);
		const result = await ctx.ntGroupApi.setGroupMemberCard(payload.group_id, memberUid, payload.card);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_group_member_special_title", SetGroupMemberSpecialTitleInput, zod_default.object({}), async (ctx, payload) => {
		const memberUid = await ctx.ntUserApi.getUidByUin(payload.user_id, payload.group_id);
		const result = await ctx.ntGroupApi.setGroupMemberSpecialTitle(payload.group_id, memberUid, payload.special_title);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_group_member_admin", SetGroupMemberAdminInput, zod_default.object({}), async (ctx, payload) => {
		const memberUid = await ctx.ntUserApi.getUidByUin(payload.user_id, payload.group_id);
		const result = await ctx.ntGroupApi.setGroupMemberAdmin(payload.group_id, memberUid, payload.is_set);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_group_member_mute", SetGroupMemberMuteInput, zod_default.object({}), async (ctx, payload) => {
		const uid = await ctx.ntUserApi.getUidByUin(payload.user_id, payload.group_id);
		const result = await ctx.ntGroupApi.muteGroupMember(payload.group_id, [{
			uid,
			duration: payload.duration
		}]);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("set_group_whole_mute", SetGroupWholeMuteInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.muteGroup(payload.group_id, payload.is_mute);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("kick_group_member", KickGroupMemberInput, zod_default.object({}), async (ctx, payload) => {
		const memberUid = await ctx.ntUserApi.getUidByUin(payload.user_id, payload.group_id);
		const result = await ctx.ntGroupApi.kickGroupMember(payload.group_id, [memberUid], payload.reject_add_request);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("get_group_announcements", GetGroupAnnouncementsInput, GetGroupAnnouncementsOutput, async (ctx, payload) => {
		const result = await ctx.ntWebApi.getGroupBulletinList(payload.group_id);
		if (result.ec !== 0) return Failed(-500, result.em);
		const feeds = result.feeds ?? [];
		const inst = result.inst ?? [];
		const announcements = [];
		for (const e of [...feeds, ...inst]) announcements.push({
			group_id: payload.group_id,
			announcement_id: e.fid,
			user_id: e.u,
			time: e.pubt,
			content: e.msg.text,
			image_url: e.msg.pics?.[0] ? `https://gdynamic.qpic.cn/gdynamic/${e.msg.pics[0].id}/0` : void 0
		});
		if (inst.length) announcements.sort((a, b) => b.time - a.time);
		return Ok({ announcements });
	}),
	defineApi("send_group_announcement", SendGroupAnnouncementInput, zod_default.object({}), async (ctx, payload) => {
		let picInfo;
		if (payload.image_uri) {
			const imageBuffer = await resolveMilkyUri(payload.image_uri);
			const tempPath = path.join(TEMP_DIR, `group-announcement-${randomUUID()}`);
			await writeFile(tempPath, imageBuffer);
			const result = await ctx.ntWebApi.uploadGroupBulletinPic(payload.group_id, tempPath);
			unlink(tempPath).catch(noop);
			if (result.errCode !== 0) return Failed(-500, result.errMsg);
			picInfo = result.picInfo;
		}
		const result = await ctx.ntWebApi.publishGroupBulletin(payload.group_id, payload.content, 0, 0, 0, 0, 1, picInfo?.id, picInfo?.width, picInfo?.height);
		if (result.ec !== 0) return Failed(-500, result.em);
		return Ok({});
	}),
	defineApi("delete_group_announcement", DeleteGroupAnnouncementInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntWebApi.deleteGroupBulletin(payload.group_id, payload.announcement_id);
		if (result.ec !== 0) return Failed(-500, result.em);
		return Ok({});
	}),
	defineApi("get_group_essence_messages", GetGroupEssenceMessagesInput, GetGroupEssenceMessagesOutput, async (ctx, payload) => {
		const peer = {
			guildId: "",
			chatType: 2,
			peerUid: payload.group_id.toString()
		};
		const result = await ctx.ntWebApi.getGroupEssenceList(payload.group_id, payload.page_index, payload.page_size);
		if (result.retcode !== 0) return Failed(-500, result.retmsg);
		const messages = [];
		for (const item of result.data.msg_list) {
			let msg = ctx.store.getMsgBySeq(peer.peerUid, item.msg_seq);
			if (!msg) {
				const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, item.msg_seq);
				msg = msgList[0];
			}
			if (!msg) continue;
			messages.push({
				group_id: +item.group_code,
				message_seq: item.msg_seq,
				message_time: +msg.msgTime,
				sender_id: +item.sender_uin,
				sender_name: item.sender_nick,
				operator_id: +item.add_digest_uin,
				operator_name: item.add_digest_nick,
				operation_time: item.add_digest_time,
				segments: await transformIncomingSegments(ctx, msg)
			});
		}
		return Ok({
			messages,
			is_end: result.data.is_end
		});
	}),
	defineApi("set_group_essence_message", SetGroupEssenceMessageInput, zod_default.object({}), async (ctx, payload) => {
		const peer = {
			chatType: ChatType.Group,
			peerUid: payload.group_id.toString(),
			guildId: ""
		};
		let msg = ctx.store.getMsgBySeq(peer.peerUid, payload.message_seq);
		if (!msg) {
			const { msgList } = await ctx.ntMsgApi.getSingleMsg(peer, payload.message_seq);
			msg = msgList[0];
		}
		if (payload.is_set) {
			const result = await ctx.ntGroupApi.addGroupEssence(payload.group_id, payload.message_seq, msg.msgRandom);
			if (result.retCode !== 0) return Failed(-500, result.retMsg);
		} else {
			const result = await ctx.ntGroupApi.removeGroupEssence(payload.group_id, payload.message_seq, msg.msgRandom);
			if (result.retCode !== 0) return Failed(-500, result.retMsg);
		}
		return Ok({});
	}),
	defineApi("quit_group", QuitGroupInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.quitGroup(payload.group_id);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("send_group_message_reaction", SendGroupMessageReactionInput, zod_default.object({}), async (ctx, payload) => {
		payload.group_id.toString();
		const result = await ctx.ntMsgApi.setGroupMsgReaction(payload.group_id, payload.message_seq, payload.reaction, payload.is_add, {
			face: 1,
			emoji: 2
		}[payload.reaction_type]);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("send_group_nudge", SendGroupNudgeInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.sendGroupNudge(payload.group_id, payload.user_id);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("get_group_notifications", GetGroupNotificationsInput, GetGroupNotificationsOutput, async (ctx, payload) => {
		const result = await ctx.ntGroupApi.getGroupNotifications(payload.is_filtered, payload.limit, payload.start_notification_seq ?? void 0);
		const notifications = [];
		for (const n of result.notifications) if (n.type === GroupNotificationType.JoinRequest) notifications.push({
			type: "join_request",
			group_id: n.group.groupCode,
			notification_seq: n.sequence,
			is_filtered: payload.is_filtered,
			initiator_id: await ctx.ntUserApi.getUinByUid(n.user1.uid),
			state: {
				[RequestState.Init]: "pending",
				[RequestState.Unhandle]: "pending",
				[RequestState.Agreed]: "accepted",
				[RequestState.Refused]: "rejected",
				[RequestState.Ignored]: "ignored"
			}[n.requestState] ?? "pending",
			operator_id: n.user2?.uid ? await ctx.ntUserApi.getUinByUid(n.user2.uid) : void 0,
			comment: n.comment ?? ""
		});
		else if (n.type === GroupNotificationType.SetAdmin || n.type === GroupNotificationType.UnsetAdmin) notifications.push({
			type: "admin_change",
			group_id: n.group.groupCode,
			notification_seq: n.sequence,
			target_user_id: await ctx.ntUserApi.getUinByUid(n.user1.uid),
			is_set: n.type === GroupNotificationType.SetAdmin,
			operator_id: await ctx.ntUserApi.getUinByUid(n.user2.uid)
		});
		else if (n.type === GroupNotificationType.Kick) notifications.push({
			type: "kick",
			group_id: n.group.groupCode,
			notification_seq: n.sequence,
			target_user_id: await ctx.ntUserApi.getUinByUid(n.user1.uid),
			operator_id: await ctx.ntUserApi.getUinByUid(n.user2?.uid ?? n.user3.uid)
		});
		else if (n.type === GroupNotificationType.Quit) notifications.push({
			type: "quit",
			group_id: n.group.groupCode,
			notification_seq: n.sequence,
			target_user_id: await ctx.ntUserApi.getUinByUid(n.user1.uid)
		});
		else if (n.type === GroupNotificationType.InvitedJoinRequest) notifications.push({
			type: "invited_join_request",
			group_id: n.group.groupCode,
			notification_seq: n.sequence,
			initiator_id: await ctx.ntUserApi.getUinByUid(n.user2.uid),
			target_user_id: await ctx.ntUserApi.getUinByUid(n.user1.uid),
			state: {
				[RequestState.Init]: "pending",
				[RequestState.Unhandle]: "pending",
				[RequestState.Agreed]: "accepted",
				[RequestState.Refused]: "rejected",
				[RequestState.Ignored]: "ignored"
			}[n.requestState] ?? "pending",
			operator_id: n.user3?.uid ? await ctx.ntUserApi.getUinByUid(n.user3.uid) : void 0
		});
		return Ok({
			notifications,
			next_notification_seq: Number(result.nextStartSeq)
		});
	}),
	defineApi("accept_group_request", AcceptGroupRequestInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.setGroupRequest(payload.is_filtered, payload.group_id, payload.notification_seq, payload.notification_type === "join_request" ? GroupNotificationType.JoinRequest : GroupNotificationType.InvitedJoinRequest, true);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("reject_group_request", RejectGroupRequestInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.setGroupRequest(payload.is_filtered, payload.group_id, payload.notification_seq, payload.notification_type === "join_request" ? GroupNotificationType.JoinRequest : GroupNotificationType.InvitedJoinRequest, false, payload.reason ?? void 0);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("accept_group_invitation", AcceptGroupInvitationInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.setGroupRequest(false, payload.group_id, payload.invitation_seq, GroupNotificationType.Invitation, true);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	}),
	defineApi("reject_group_invitation", RejectGroupInvitationInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.setGroupRequest(false, payload.group_id, payload.invitation_seq, GroupNotificationType.Invitation, false);
		if (result.errorCode !== 0) return Failed(-500, result.errorMsg);
		return Ok({});
	})
];
var FileApi = [
	defineApi("upload_private_file", UploadPrivateFileInput, UploadPrivateFileOutput, async (ctx, payload) => {
		const data = await resolveMilkyUri(payload.file_uri);
		const tempPath = path.join(TEMP_DIR, `file-${randomUUID()}`);
		await writeFile(tempPath, data);
		const uid = await ctx.ntUserApi.getUidByUin(payload.user_id);
		if (!uid) return Failed(-404, "User not found");
		const info = await ctx.ntFileApi.uploadPrivateFile(ChatType.C2C, uid, tempPath, payload.file_name);
		unlink(tempPath).catch(noop);
		const result = await ctx.ntMsgApi.sendPrivateFileMessage({
			toUin: payload.user_id,
			toUid: uid,
			fileUuid: info.fileId,
			fileName: payload.file_name,
			fileSize: info.fileSize,
			file10MMd5: info.file10MMd5,
			crcMedia: info.crcMedia
		});
		if (result.resultCode !== 0) return Failed(-500, result.errMsg ?? "");
		return Ok({ file_id: info.fileId });
	}),
	defineApi("upload_group_file", UploadGroupFileInput, UploadGroupFileOutput, async (ctx, payload) => {
		const data = await resolveMilkyUri(payload.file_uri);
		const tempPath = path.join(TEMP_DIR, `file-${randomUUID()}`);
		await writeFile(tempPath, data);
		const info = await ctx.ntFileApi.uploadGroupFile(payload.group_id, tempPath, payload.file_name, payload.parent_folder_id);
		unlink(tempPath).catch(noop);
		const result = await ctx.ntMsgApi.sendGroupFileMessage(payload.group_id, info.fileId, info.busId);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({ file_id: info.fileId });
	}),
	defineApi("get_private_file_download_url", GetPrivateFileDownloadUrlInput, GetPrivateFileDownloadUrlOutput, async (ctx, payload) => {
		const result = await ctx.ntFileApi.getFileUrl(payload.file_id, false);
		if (result.retCode !== 0) return Failed(-500, result.retMsg);
		return Ok({ download_url: result.url });
	}),
	defineApi("get_group_file_download_url", GetGroupFileDownloadUrlInput, GetGroupFileDownloadUrlOutput, async (ctx, payload) => {
		const result = await ctx.ntFileApi.getFileUrl(payload.file_id, true, payload.group_id);
		if (result.retCode !== 0) return Failed(-500, result.retMsg);
		return Ok({ download_url: result.url });
	}),
	defineApi("get_group_files", GetGroupFilesInput, GetGroupFilesOutput, async (ctx, payload) => {
		const allFiles = [];
		const allFolders = [];
		let nextIndex;
		while (nextIndex !== 0) {
			const data = await ctx.ntGroupApi.getGroupFileList(payload.group_id, payload.parent_folder_id, nextIndex ?? 0, 100);
			if (data.retCode !== 0) return Failed(-500, data.clientWording);
			const { files, folders } = transformGroupFileList(data.items, payload.group_id);
			allFiles.push(...files);
			allFolders.push(...folders);
			nextIndex = data.nextIndex;
		}
		return Ok({
			files: allFiles,
			folders: allFolders
		});
	}),
	defineApi("move_group_file", MoveGroupFileInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.moveGroupFile(payload.group_id, payload.file_id, payload.parent_folder_id, payload.target_folder_id);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	}),
	defineApi("rename_group_file", RenameGroupFileInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.renameGroupFile(payload.group_id, payload.file_id, payload.parent_folder_id, payload.new_file_name);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	}),
	defineApi("delete_group_file", DeleteGroupFileInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.deleteGroupFile(payload.group_id, payload.file_id);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	}),
	defineApi("persist_group_file", PersistGroupFileInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.persistGroupFile(payload.group_id, payload.file_id);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	}),
	defineApi("create_group_folder", CreateGroupFolderInput, CreateGroupFolderOutput, async (ctx, payload) => {
		const result = await ctx.ntGroupApi.createGroupFolder(payload.group_id, payload.folder_name);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({ folder_id: result.folderInfo.folderId });
	}),
	defineApi("rename_group_folder", RenameGroupFolderInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.renameGroupFolder(payload.group_id, payload.folder_id, payload.new_folder_name);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	}),
	defineApi("delete_group_folder", DeleteGroupFolderInput, zod_default.object({}), async (ctx, payload) => {
		const result = await ctx.ntGroupApi.deleteGroupFolder(payload.group_id, payload.folder_id);
		if (result.retCode !== 0) return Failed(-500, result.clientWording);
		return Ok({});
	})
];
//#endregion
//#region src/milky/transform/event.ts
/**
* Transform NTQQ message-created event to Milky message_receive event (private)
*/
async function transformPrivateMessageCreated(ctx, message) {
	try {
		const transformedMessage = await transformIncomingPrivateMessage(ctx, await ctx.ntFriendApi.getFriendByUid(message.senderUid, false), message);
		if (transformedMessage.segments.length === 0) return null;
		return transformedMessage;
	} catch (error) {
		ctx.logger.error("Failed to transform private message created event:", error);
		return null;
	}
}
/**
* Transform NTQQ message-created event to Milky message_receive event (group)
*/
async function transformGroupMessageCreated(ctx, message) {
	try {
		const transformedMessage = await transformIncomingGroupMessage(ctx, await ctx.ntGroupApi.getGroup(message.peerUin, false), {
			...await ctx.ntGroupApi.getGroupMemberByUid(message.peerUin, message.senderUid, false),
			role: message.memberRole
		}, message);
		if (transformedMessage.segments.length === 0) return null;
		return transformedMessage;
	} catch (error) {
		ctx.logger.error("Failed to transform group message created event:", error);
		return null;
	}
}
/**
* Transform NTQQ message-created event to Milky message_receive event (temp)
*/
async function transformTempMessageCreated(ctx, message) {
	try {
		const transformedMessage = await transformIncomingTempMessage(ctx, await ctx.ntGroupApi.getGroup(message.tempFromGroupCode, false), message);
		if (transformedMessage.segments.length === 0) return null;
		return transformedMessage;
	} catch (error) {
		ctx.logger.error("Failed to transform temp message created event:", error);
		return null;
	}
}
async function transformTempMessageRecall(ctx, data) {
	try {
		return {
			message_scene: "temp",
			peer_id: data.peerUin,
			message_seq: data.msgSeq,
			sender_id: data.senderUin,
			operator_id: data.senderUin,
			display_suffix: data.displaySuffix
		};
	} catch (error) {
		ctx.logger.error("Failed to transform temp message deleted event:", error);
		return null;
	}
}
async function transformFriendMessageRecall(ctx, data) {
	try {
		return {
			message_scene: "friend",
			peer_id: data.peerUin,
			message_seq: data.msgSeq,
			sender_id: data.senderUin,
			operator_id: data.senderUin,
			display_suffix: data.displaySuffix
		};
	} catch (error) {
		ctx.logger.error("Failed to transform private message deleted event:", error);
		return null;
	}
}
async function transformGroupMessageRecall(ctx, data) {
	try {
		return {
			message_scene: "group",
			peer_id: data.peerUin,
			message_seq: data.msgSeq,
			sender_id: data.senderUin,
			operator_id: data.operatorUin,
			display_suffix: data.displaySuffix
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group message deleted event:", error);
		return null;
	}
}
/**
* Transform NTQQ friend-request event to Milky friend_request event
*/
async function transformFriendRequestEvent(ctx, data) {
	try {
		return {
			initiator_id: data.initiatorUin,
			initiator_uid: data.initiatorUid,
			comment: data.comment,
			via: data.via
		};
	} catch (error) {
		ctx.logger.error("Failed to transform friend request event:", error);
		return null;
	}
}
async function transformGroupJoinRequestEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			notification_seq: Number(data.notificationSeq),
			is_filtered: data.isDoubt,
			initiator_id: data.initiatorUin,
			comment: data.comment
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group join request event:", error);
		return null;
	}
}
async function transformGroupInvitedJoinRequestEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			notification_seq: Number(data.notificationSeq),
			initiator_id: data.initiatorUin,
			target_user_id: data.targetUserUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group invited join request event:", error);
		return null;
	}
}
async function transformGroupInvitationEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			invitation_seq: Number(data.invitationSeq),
			initiator_id: data.initiatorUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group invitation event:", error);
		return null;
	}
}
async function transformGroupMemberIncreaseEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			user_id: data.memberUin,
			operator_id: data.operatorUin,
			invitor_id: data.invitorUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group member increase event:", error);
		return null;
	}
}
async function transformGroupMemberDecreaseEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			user_id: data.memberUin,
			operator_id: data.operatorUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group member decrease event:", error);
		return null;
	}
}
async function transformFriendNudgeEvent(ctx, data) {
	try {
		return {
			user_id: data.uin,
			is_self_send: data.isSelfSend,
			is_self_receive: data.isSelfReceive,
			display_action: data.displayAction,
			display_suffix: data.displaySuffix,
			display_action_img_url: data.displayActionImgUrl
		};
	} catch (error) {
		ctx.logger.error("Failed to transform friend nudge event:", error);
		return null;
	}
}
async function transformGroupNudgeEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			sender_id: data.senderUin,
			receiver_id: data.receiverUin,
			display_action: data.displayAction,
			display_suffix: data.displaySuffix,
			display_action_img_url: data.displayActionImgUrl
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group nudge event:", error);
		return null;
	}
}
async function transformGroupNameChangeEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			new_group_name: data.newGroupName,
			operator_id: data.operatorUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group name change event:", error);
		return null;
	}
}
async function transformGroupMuteEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			user_id: data.memberUin,
			operator_id: data.operatorUin,
			duration: data.duration
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group mute event:", error);
		return null;
	}
}
async function transformGroupWholeMuteEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			operator_id: data.operatorUin,
			is_mute: data.isMute
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group mute event:", error);
		return null;
	}
}
async function transformGroupAdminChangeEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			user_id: data.targetUin,
			operator_id: data.operatorUin,
			is_set: data.isSet
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group admin change event:", error);
		return null;
	}
}
async function transformPeerPinChangeEvent(ctx, data) {
	try {
		return {
			message_scene: data.chatType === ChatType.Group ? "group" : "friend",
			peer_id: data.peerUin,
			is_pinned: data.isPinned
		};
	} catch (error) {
		ctx.logger.error("Failed to transform peer pin change event:", error);
		return null;
	}
}
async function transformGroupMessageReactionEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			user_id: data.operatorUin,
			message_seq: data.msgSeq,
			face_id: data.faceId,
			reaction_type: data.type === 2 ? "emoji" : "face",
			is_add: data.isAdd
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group message reaction event:", error);
		return null;
	}
}
async function transformGroupEssenceMessageChangeEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			message_seq: data.msgSeq,
			operator_id: data.operatorUin,
			is_set: data.isSet
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group essence message change event:", error);
		return null;
	}
}
async function transformBotOfflineEvent(ctx, data) {
	try {
		return { reason: data.tipsDesc };
	} catch (error) {
		ctx.logger.error("Failed to transform bot offline event:", error);
		return null;
	}
}
async function transformGroupDisbandEvent(ctx, data) {
	try {
		return {
			group_id: data.groupCode,
			operator_id: data.operatorUin
		};
	} catch (error) {
		ctx.logger.error("Failed to transform group disband event:", error);
		return null;
	}
}
async function transformPrivateMessageEvent(ctx, message) {
	try {
		for (const element of message.elements) if (element.fileElement) return {
			eventType: "friend_file_upload",
			data: {
				user_id: +message.peerUin,
				file_id: element.fileElement.fileUuid,
				file_name: element.fileElement.fileName,
				file_size: +element.fileElement.fileSize,
				file_hash: element.fileElement.fileMd5 ?? "",
				is_self: message.senderUin === +selfInfo.uin
			}
		};
		return null;
	} catch (error) {
		ctx.logger.error("Failed to transform private message event:", error);
		return null;
	}
}
async function transformGroupMessageEvent(ctx, message) {
	try {
		for (const element of message.elements) if (element.fileElement) return {
			eventType: "group_file_upload",
			data: {
				group_id: +message.peerUid,
				user_id: +message.senderUin,
				file_id: element.fileElement.fileUuid,
				file_name: element.fileElement.fileName,
				file_size: +element.fileElement.fileSize
			}
		};
		return null;
	} catch (error) {
		ctx.logger.error("Failed to transform group message event:", error);
		return null;
	}
}
//#endregion
//#region src/milky/adapter.ts
var MilkyAdapter = class extends Service {
	config;
	static inject = [
		"ntUserApi",
		"ntFriendApi",
		"ntGroupApi",
		"ntMsgApi",
		"ntFileApi",
		"ntSystemApi",
		"ntWebApi",
		"app",
		"store"
	];
	apiCollection;
	httpHandler;
	webhookHandler;
	listenedEvent = false;
	constructor(ctx, config) {
		super(ctx, "milky");
		this.config = config;
		this.apiCollection = new MilkyApiCollection(ctx, [
			...SystemApi,
			...MessageApi,
			...FriendApi,
			...GroupApi,
			...FileApi
		]);
		this.httpHandler = new MilkyHttpHandler(this, ctx, config.http);
		this.webhookHandler = new MilkyWebhookHandler(this, ctx, config.webhook);
	}
	async [Service.init]() {
		this.start();
		return noop;
	}
	start() {
		this.ctx.on("llob/config-updated", (config) => {
			this.httpHandler.stop();
			this.webhookHandler.stop();
			this.httpHandler.updateConfig(config.milky.http);
			this.webhookHandler.updateConfig(config.milky.webhook);
			if (config.milky.enable) {
				this.httpHandler.start();
				this.webhookHandler.start();
				this.setupEventListeners();
			}
			this.config = config.milky;
		});
		if (!this.config.enable) return;
		this.httpHandler.start();
		this.webhookHandler.start();
		this.setupEventListeners();
	}
	async stop() {
		if (!this.config.enable) return;
		this.httpHandler.stop();
	}
	emitEvent(eventName, data) {
		const selfUin = selfInfo.uin;
		const eventString = JSON.stringify({
			time: Math.floor(Date.now() / 1e3),
			self_id: +selfUin,
			event_type: eventName,
			data
		});
		this.httpHandler.broadcast(eventString);
		this.webhookHandler.broadcast(eventString);
	}
	setupEventListeners() {
		if (this.listenedEvent) return;
		this.listenedEvent = true;
		this.ctx.on("nt/message-created", async (data) => {
			if (data.message.chatType === ChatType.C2C) {
				const eventData = await transformPrivateMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
				const result = await transformPrivateMessageEvent(this.ctx, data.message);
				if (result) this.emitEvent(result.eventType, result.data);
			} else if (data.message.chatType === ChatType.Group) {
				const eventData = await transformGroupMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
				const result = await transformGroupMessageEvent(this.ctx, data.message);
				if (result) this.emitEvent(result.eventType, result.data);
			} else if (data.message.chatType === ChatType.TempC2CFromGroup) {
				const eventData = await transformTempMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
				const result = await transformPrivateMessageEvent(this.ctx, data.message);
				if (result) this.emitEvent(result.eventType, result.data);
			}
		});
		this.ctx.on("nt/message-deleted", async (data) => {
			if (data.chatType === ChatType.C2C) {
				const eventData = await transformFriendMessageRecall(this.ctx, data);
				if (eventData) this.emitEvent("message_recall", eventData);
			} else if (data.chatType === ChatType.Group) {
				const eventData = await transformGroupMessageRecall(this.ctx, data);
				if (eventData) this.emitEvent("message_recall", eventData);
			} else if (data.chatType === ChatType.TempC2CFromGroup) {
				const eventData = await transformTempMessageRecall(this.ctx, data);
				if (eventData) this.emitEvent("message_recall", eventData);
			}
		});
		this.ctx.on("nt/message-sent", async (data) => {
			if (!this.config.reportSelfMessage) return;
			if (data.message.chatType === ChatType.C2C) {
				const eventData = await transformPrivateMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
			} else if (data.message.chatType === ChatType.Group) {
				const eventData = await transformGroupMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
			} else if (data.message.chatType === ChatType.TempC2CFromGroup) {
				const eventData = await transformTempMessageCreated(this.ctx, data.message);
				if (eventData) this.emitEvent("message_receive", eventData);
			}
		});
		this.ctx.on("nt/group-join-request", async (data) => {
			const eventData = await transformGroupJoinRequestEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_join_request", eventData);
		});
		this.ctx.on("nt/group-invited-join-request", async (data) => {
			const eventData = await transformGroupInvitedJoinRequestEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_invited_join_request", eventData);
		});
		this.ctx.on("nt/group-invitation", async (data) => {
			const eventData = await transformGroupInvitationEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_invitation", eventData);
		});
		this.ctx.on("nt/group-disband", async (data) => {
			const eventData = await transformGroupDisbandEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_disband", eventData);
		});
		this.ctx.on("nt/group-nudge", async (data) => {
			const eventData = await transformGroupNudgeEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_nudge", eventData);
		});
		this.ctx.on("nt/group-message-reaction", async (data) => {
			const eventData = await transformGroupMessageReactionEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_message_reaction", eventData);
		});
		this.ctx.on("nt/group-essence-message-changed", async (data) => {
			const eventData = await transformGroupEssenceMessageChangeEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_essence_message_change", eventData);
		});
		this.ctx.on("nt/group-whole-mute", async (data) => {
			const eventData = await transformGroupWholeMuteEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_whole_mute", eventData);
		});
		this.ctx.on("nt/group-mute", async (data) => {
			const eventData = await transformGroupMuteEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_mute", eventData);
		});
		this.ctx.on("nt/group-name-changed", async (data) => {
			const eventData = await transformGroupNameChangeEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_name_change", eventData);
		});
		this.ctx.on("nt/group-admin-changed", async (data) => {
			const eventData = await transformGroupAdminChangeEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_admin_change", eventData);
		});
		this.ctx.on("nt/group-member-added", async (data) => {
			const eventData = await transformGroupMemberIncreaseEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_member_increase", eventData);
		});
		this.ctx.on("nt/group-member-removed", async (data) => {
			const eventData = await transformGroupMemberDecreaseEvent(this.ctx, data);
			if (eventData) this.emitEvent("group_member_decrease", eventData);
		});
		this.ctx.on("nt/friend-request", async (data) => {
			const eventData = await transformFriendRequestEvent(this.ctx, data);
			if (eventData) this.emitEvent("friend_request", eventData);
		});
		this.ctx.on("nt/friend-nudge", async (data) => {
			const eventData = await transformFriendNudgeEvent(this.ctx, data);
			if (eventData) this.emitEvent("friend_nudge", eventData);
		});
		this.ctx.on("nt/pin-changed", async (data) => {
			const eventData = await transformPeerPinChangeEvent(this.ctx, data);
			if (eventData) this.emitEvent("peer_pin_change", eventData);
		});
		this.ctx.on("nt/kicked-offline", async (data) => {
			const eventData = await transformBotOfflineEvent(this.ctx, data);
			if (eventData) this.emitEvent("bot_offline", eventData);
		});
	}
};
//#endregion
//#region node_modules/@cordisjs/plugin-database/lib/index.js
var __create = Object.create;
var __defProp$3 = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
var __typeError = (msg) => {
	throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp$3(obj, key, {
	enumerable: true,
	configurable: true,
	writable: true,
	value
}) : obj[key] = value;
var __name$3 = (target, value) => __defProp$3(target, "name", {
	value,
	configurable: true
});
var __decoratorStart = (base) => [
	,
	,
	,
	__create(base?.[__knownSymbol("metadata")] ?? null)
];
var __decoratorStrings = [
	"class",
	"method",
	"getter",
	"setter",
	"accessor",
	"field",
	"value",
	"get",
	"set"
];
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
var __decoratorContext = (kind, name, done, metadata, fns) => ({
	kind: __decoratorStrings[kind],
	name,
	metadata,
	addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null))
});
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
var __runInitializers = (array, flags, self, value) => {
	for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
	return value;
};
var __decorateElement = (array, flags, name, decorators, target, extra) => {
	var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
	var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
	var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
	var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : {
		get [name]() {
			return __privateGet(this, extra);
		},
		set [name](x) {
			return __privateSet(this, extra, x);
		}
	}, name));
	k ? p && k < 4 && __name$3(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name$3(target, name);
	for (var i = decorators.length - 1; i >= 0; i--) {
		ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
		if (k) {
			ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
			if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
			if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
		}
		it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : {
			get: desc.get,
			set: desc.set
		} : target, ctx), done._ = 1;
		if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
		else if (typeof it !== "object" || it === null) __typeError("Object expected");
		else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
	}
	return k || __decoratorMetadata(array, target), desc && __defProp$3(target, name, desc), p ? k ^ 4 ? extra : desc : target;
};
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError("Cannot use the \"in\" operator on this value") : member.has(obj);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
var Type;
((Type2) => {
	Type2.kType = /* @__PURE__ */ Symbol.for("minato.type");
	Type2.Any = fromField("expr");
	Type2.Boolean = fromField("boolean");
	Type2.Number = fromField("double");
	Type2.String = fromField("string");
	Type2.Object = /* @__PURE__ */ __name$3((obj) => defineProperty({
		type: "json",
		inner: globalThis.Object.keys(obj ?? {}).length ? mapValues(obj, (value) => isType(value) ? value : fromField(value)) : void 0
	}, Type2.kType, true), "Object");
	Type2.Array = /* @__PURE__ */ __name$3((type) => defineProperty({
		type: "json",
		inner: type,
		array: true
	}, Type2.kType, true), "Array");
	function fromPrimitive(value) {
		if (isNullable(value)) return fromField("expr");
		else if (typeof value === "number") return Type2.Number;
		else if (typeof value === "string") return Type2.String;
		else if (typeof value === "boolean") return Type2.Boolean;
		else if (typeof value === "bigint") return fromField("bigint");
		else if (value instanceof Date) return fromField("timestamp");
		else if (Binary.is(value)) return fromField("binary");
		else if (globalThis.Array.isArray(value)) return (0, Type2.Array)(value.length ? fromPrimitive(value[0]) : void 0);
		else if (typeof value === "object") return fromField("json");
		throw new TypeError(`invalid primitive: ${value}`);
	}
	Type2.fromPrimitive = fromPrimitive;
	__name$3(fromPrimitive, "fromPrimitive");
	function fromField(field) {
		if (isType(field)) return field;
		else if (field === "array") return (0, Type2.Array)();
		else if (field === "object") return (0, Type2.Object)();
		else if (typeof field === "string") return defineProperty({ type: field }, Type2.kType, true);
		else if (field.type) return field.type;
		else if (field.expr?.[Type2.kType]) return field.expr[Type2.kType];
		throw new TypeError(`invalid field: ${field}`);
	}
	Type2.fromField = fromField;
	__name$3(fromField, "fromField");
	function fromTerm(value, initial) {
		if (isEvalExpr(value)) return value[Type2.kType] ?? initial ?? fromField("expr");
		else return fromPrimitive(value);
	}
	Type2.fromTerm = fromTerm;
	__name$3(fromTerm, "fromTerm");
	function fromTerms(values, initial) {
		return values.map((x) => fromTerm(x)).find((type) => type.type !== "expr") ?? initial ?? fromField("expr");
	}
	Type2.fromTerms = fromTerms;
	__name$3(fromTerms, "fromTerms");
	function isType(value) {
		return value?.[Type2.kType] === true;
	}
	Type2.isType = isType;
	__name$3(isType, "isType");
	function isArray(type) {
		return type?.type === "json" && type?.array;
	}
	Type2.isArray = isArray;
	__name$3(isArray, "isArray");
	function getInner(type, key) {
		if (!type?.inner) return;
		if (isArray(type)) return type.inner;
		if (isNullable(key)) return;
		if (type.inner[key]) return type.inner[key];
		if (key.includes(".")) return key.split(".").reduce((t, k) => getInner(t, k), type);
		const fields = globalThis.Object.entries(type.inner).filter(([k]) => k.startsWith(`${key}.`)).map(([k, v]) => [k.slice(key.length + 1), v]);
		return fields.length ? (0, Type2.Object)(globalThis.Object.fromEntries(fields)) : void 0;
	}
	Type2.getInner = getInner;
	__name$3(getInner, "getInner");
	function transform(value, type, callback) {
		if (!isNullable(value) && type?.inner) if (Type2.isArray(type)) {
			const innerType = Type2.getInner(type);
			return value.map((x) => callback(x, innerType)).filter((x) => !type.ignoreNull || !isEmpty(x));
		} else {
			if (type.ignoreNull && isEmpty(value)) return null;
			return mapValues(value, (x, k) => callback(x, Type2.getInner(type, k)));
		}
		return value;
	}
	Type2.transform = transform;
	__name$3(transform, "transform");
})(Type || (Type = {}));
var Relation;
((Relation4) => {
	Relation4.Type = [
		"oneToOne",
		"oneToMany",
		"manyToOne",
		"manyToMany"
	];
	function buildAssociationTable(...tables) {
		return "_" + tables.sort().join("_");
	}
	Relation4.buildAssociationTable = buildAssociationTable;
	__name$3(buildAssociationTable, "buildAssociationTable");
	function buildAssociationKey(key, table) {
		return `${table}.${key}`;
	}
	Relation4.buildAssociationKey = buildAssociationKey;
	__name$3(buildAssociationKey, "buildAssociationKey");
	function buildSharedKey(field, reference) {
		return [field, reference].sort().join("_");
	}
	Relation4.buildSharedKey = buildSharedKey;
	__name$3(buildSharedKey, "buildSharedKey");
	function parse(def, key, model, relModel, subprimary) {
		const shared = !def.shared ? {} : typeof def.shared === "string" ? { [def.shared]: def.shared } : Array.isArray(def.shared) ? Object.fromEntries(def.shared.map((x) => [x, x])) : def.shared;
		const fields = def.fields ?? (subprimary || def.type === "manyToOne" || def.type === "oneToOne" && (model.name === relModel.name || !makeArray(relModel.primary).every((key2) => !relModel.fields[key2]?.nullable)) ? makeArray(relModel.primary).map((x) => `${key}.${x}`) : model.primary);
		const relation = {
			type: def.type,
			table: def.table ?? relModel.name,
			fields: makeArray(fields),
			shared,
			references: makeArray(def.references ?? relModel.primary),
			required: def.type !== "manyToOne" && model.name !== relModel.name && makeArray(fields).every((key2) => !model.fields[key2]?.nullable || makeArray(model.primary).includes(key2))
		};
		Object.entries(shared).forEach(([k, v]) => {
			relation.fields = relation.fields.filter((x) => x !== k);
			relation.references = relation.references.filter((x) => x !== v);
		});
		const inverse = {
			type: relation.type === "oneToMany" ? "manyToOne" : relation.type === "manyToOne" ? "oneToMany" : relation.type,
			table: model.name,
			fields: relation.references,
			references: relation.fields,
			shared: Object.fromEntries(Object.entries(shared).map(([k, v]) => [v, k])),
			required: relation.type !== "oneToMany" && relation.references.every((key2) => !relModel.fields[key2]?.nullable || makeArray(relModel.primary).includes(key2))
		};
		if (inverse.required) relation.required = false;
		return [relation, inverse];
	}
	Relation4.parse = parse;
	__name$3(parse, "parse");
})(Relation || (Relation = {}));
var Field;
((Field2) => {
	Field2.number = [
		"integer",
		"unsigned",
		"float",
		"double",
		"decimal"
	];
	Field2.string = [
		"char",
		"string",
		"text"
	];
	Field2.boolean = ["boolean"];
	Field2.date = [
		"timestamp",
		"date",
		"time"
	];
	Field2.object = ["list", "json"];
	const regexp = /^(\w+)(?:\((.+)\))?$/;
	function parse(source) {
		if (typeof source === "function") throw new TypeError("view field is not supported");
		if (typeof source !== "string") return {
			initial: null,
			deftype: source.type,
			...source,
			type: Type.fromField(source.type)
		};
		const capture = regexp.exec(source);
		if (!capture) throw new TypeError("invalid field definition");
		const type = capture[1];
		const args = (capture[2] || "").split(",");
		const field = {
			deftype: type,
			type: Type.fromField(type)
		};
		if (field.initial === void 0) field.initial = getInitial(type);
		if (type === "decimal") {
			field.precision = +args[0];
			field.scale = +args[1];
		} else if (args[0]) field.length = +args[0];
		return field;
	}
	Field2.parse = parse;
	__name$3(parse, "parse");
	function getInitial(type, initial) {
		if (initial === void 0) {
			if (Field2.number.includes(type)) return 0;
			if (Field2.string.includes(type)) return "";
			if (type === "list") return [];
			if (type === "json") return {};
		}
		return initial;
	}
	Field2.getInitial = getInitial;
	__name$3(getInitial, "getInitial");
	function available(field) {
		return !!field && !field.deprecated && !field.relation && field.deftype !== "expr";
	}
	Field2.available = available;
	__name$3(available, "available");
})(Field || (Field = {}));
var Model = class {
	constructor(name) {
		this.name = name;
		this.autoInc = false;
		this.primary = "id";
		this.unique = [];
		this.indexes = [];
		this.foreign = {};
	}
	name;
	static {
		__name$3(this, "Model");
	}
	fields = {};
	migrations = /* @__PURE__ */ new Map();
	extend(fields = {}, config = {}) {
		const { primary, autoInc, unique = [], indexes = [], foreign, callback } = config;
		this.primary = primary || this.primary;
		this.autoInc = autoInc || this.autoInc;
		unique.forEach((key) => this.unique.includes(key) || this.unique.push(key));
		indexes.map((x) => this.parseIndex(x)).forEach((index) => this.indexes.some((ind) => deepEqual(ind, index)) || this.indexes.push(index));
		Object.assign(this.foreign, foreign);
		if (callback) this.migrations.set(callback, Object.keys(fields));
		for (const key in fields) {
			this.fields[key] = Field.parse(fields[key]);
			this.fields[key].deprecated = !!callback;
		}
		if (typeof this.primary === "string" && this.fields[this.primary]?.deftype === "primary") this.autoInc = true;
		this.checkIndex(this.primary);
		this.unique.forEach((index) => this.checkIndex(index));
		this.indexes.forEach((index) => this.checkIndex(index));
		defineProperty(this, "type", Type.Object(mapValues(this.fields, (field) => Type.fromField(field))));
	}
	parseIndex(index) {
		if (typeof index === "string" || Array.isArray(index)) return {
			name: `index:${this.name}:` + makeArray(index).join("+"),
			unique: false,
			keys: Object.fromEntries(makeArray(index).map((key) => [key, "asc"]))
		};
		else return {
			name: index.name ?? `index:${this.name}:` + Object.keys(index.keys).join("+"),
			unique: index.unique ?? false,
			keys: index.keys
		};
	}
	checkIndex(index) {
		for (const key of typeof index === "string" || Array.isArray(index) ? makeArray(index) : Object.keys(index.keys)) if (!this.fields[key]) throw new TypeError(`missing field definition for index key "${key}"`);
	}
	resolveValue(field, value) {
		if (isNullable(value)) return value;
		if (typeof field === "string") field = this.fields[field];
		if (field) field = Type.fromField(field);
		if (field?.type === "time") {
			const date = /* @__PURE__ */ new Date(0);
			date.setHours(value.getHours(), value.getMinutes(), value.getSeconds(), value.getMilliseconds());
			return date;
		} else if (field?.type === "date") {
			const date = new Date(value);
			date.setHours(0, 0, 0, 0);
			return date;
		}
		return value;
	}
	resolveModel(obj, model) {
		if (!model) model = this.getType();
		if (isNullable(obj) || !model.inner) return obj;
		if (Type.isArray(model) && Array.isArray(obj)) return obj.map((x) => this.resolveModel(x, Type.getInner(model)));
		const result = {};
		for (const key in obj) {
			const type = Type.getInner(model, key);
			if (!type || isNullable(obj[key])) result[key] = obj[key];
			else if (type.type !== "json") result[key] = this.resolveValue(type, obj[key]);
			else if (isEvalExpr(obj[key])) result[key] = obj[key];
			else if (type.inner && Type.isArray(type) && Array.isArray(obj[key])) result[key] = obj[key].map((x) => this.resolveModel(x, Type.getInner(type)));
			else if (type.inner) result[key] = this.resolveModel(obj[key], type);
			else result[key] = obj[key];
		}
		return result;
	}
	format(source, strict = true, prefix = "", result = {}) {
		const fields = Object.keys(this.fields).filter((key) => !this.fields[key].relation);
		Object.entries(source).map(([key, value]) => {
			key = prefix + key;
			if (value === void 0) return;
			if (fields.includes(key)) {
				result[key] = value;
				return;
			}
			if (fields.find((field2) => key.startsWith(field2 + "."))) result[key] = value;
			else if (isFlat(value)) {
				if (strict && (typeof value !== "object" || Object.keys(value).length)) throw new TypeError(`unknown field "${key}" in model ${this.name}`);
			} else this.format(value, strict, key + ".", result);
		});
		return strict && prefix === "" ? this.resolveModel(result) : result;
	}
	parse(source, strict = true, prefix = "", result = {}) {
		const fields = Object.keys(this.fields).filter((key) => !this.fields[key].relation);
		if (strict && prefix === "") Object.assign(result, unravel(Object.fromEntries(fields.filter((key) => key.includes(".")).map((key) => [key.slice(0, key.lastIndexOf(".")), {}]))));
		for (const key in source) {
			let node = result;
			const segments = key.split(".").reverse();
			for (let index = segments.length - 1; index > 0; index--) {
				const segment = segments[index];
				node = node[segment] ??= {};
			}
			if (key in source) {
				const fullKey = prefix + key, value = source[key];
				if (fields.find((field2) => fullKey === field2 || fullKey.startsWith(field2 + "."))) node[segments[0]] = value;
				else if (isFlat(value)) if (strict) throw new TypeError(`unknown field "${fullKey}" in model ${this.name}`);
				else node[segments[0]] = value;
				else this.parse(value, strict, fullKey + ".", node[segments[0]] ??= {});
			}
		}
		return strict && prefix === "" ? this.resolveModel(result) : result;
	}
	create(data) {
		const result = {};
		const keys = makeArray(this.primary);
		for (const key in this.fields) {
			if (!Field.available(this.fields[key])) continue;
			const { initial } = this.fields[key];
			if (!keys.includes(key) && !isNullable(initial)) result[key] = clone$1(initial);
		}
		return this.parse({
			...result,
			...data
		});
	}
	availableFields() {
		return filterKeys(this.fields, (_, field) => Field.available(field));
	}
	getType(key) {
		if (!this.type) defineProperty(this, "type", Type.Object(mapValues(this.fields, (field) => Type.fromField(field))));
		return key ? Type.getInner(this.type, key) : this.type;
	}
};
function isEvalExpr(value) {
	return value && Object.keys(value).some((key) => key.startsWith("$"));
}
__name$3(isEvalExpr, "isEvalExpr");
var isUpdateExpr = isEvalExpr;
function isAggrExpr(expr) {
	return expr["$"] || expr["$select"];
}
__name$3(isAggrExpr, "isAggrExpr");
function hasSubquery(value) {
	if (!isEvalExpr(value)) return false;
	return Object.entries(value).filter(([k]) => k.startsWith("$")).some(([k, v]) => {
		if (isNullable(v) || isComparable(v)) return false;
		if (k === "$exec") return true;
		if (isEvalExpr(v)) return hasSubquery(v);
		if (Array.isArray(v)) return v.some((x) => hasSubquery(x));
		if (typeof v === "object") return Object.values(v).some((x) => hasSubquery(x));
		return false;
	});
}
__name$3(hasSubquery, "hasSubquery");
var kExpr = /* @__PURE__ */ Symbol("expr");
var Eval3 = /* @__PURE__ */ __name$3(((key, value, type) => defineProperty(defineProperty({ ["$" + key]: value }, kExpr, true), Type.kType, type)), "Eval");
var operators = /* @__PURE__ */ Object.create(null);
operators["$"] = getRecursive;
function unary(key, callback, type) {
	operators[`$${key}`] = callback;
	return ((value) => Eval3(key, value, typeof type === "function" ? type(value) : type));
}
__name$3(unary, "unary");
function multary(key, callback, type) {
	operators[`$${key}`] = callback;
	return (...args) => Eval3(key, args, typeof type === "function" ? type(...args) : type);
}
__name$3(multary, "multary");
function comparator(key, callback) {
	operators[`$${key}`] = (args, data) => {
		const left = executeEval(data, args[0]);
		const right = executeEval(data, args[1]);
		if (isNullable(left) || isNullable(right)) return true;
		return callback(left.valueOf(), right.valueOf());
	};
	return (...args) => Eval3(key, args, Type.Boolean);
}
__name$3(comparator, "comparator");
Eval3.switch = (branches, vDefault) => Eval3("switch", {
	branches,
	default: vDefault
}, Type.fromTerm(branches[0]));
operators.$switch = (args, data) => {
	for (const branch of args.branches) if (executeEval(data, branch.case)) return executeEval(data, branch.then);
	return executeEval(data, args.default);
};
Eval3.ignoreNull = (expr) => (expr["$ignoreNull"] = true, expr[Type.kType].ignoreNull = true, expr);
Eval3.select = multary("select", (args, table) => args.map((arg) => executeEval(table, arg)), Type.Array());
Eval3.query = (row, query, expr = true) => ({
	$expr: expr,
	...query
});
Eval3.exec = unary("exec", (expr, data) => expr.driver.executeSelection(expr, data), (expr) => Type.fromTerm(expr.args[0]));
Eval3.if = multary("if", ([cond, vThen, vElse], data) => executeEval(data, cond) ? executeEval(data, vThen) : executeEval(data, vElse), (cond, vThen, vElse) => Type.fromTerm(vThen));
Eval3.ifNull = multary("ifNull", ([value, fallback], data) => executeEval(data, value) ?? executeEval(data, fallback), (value) => Type.fromTerm(value));
Eval3.add = multary("add", (args, data) => args.reduce((prev, curr) => prev + executeEval(data, curr), 0), Type.Number);
Eval3.mul = Eval3.multiply = multary("multiply", (args, data) => args.reduce((prev, curr) => prev * executeEval(data, curr), 1), Type.Number);
Eval3.sub = Eval3.subtract = multary("subtract", ([left, right], data) => executeEval(data, left) - executeEval(data, right), Type.Number);
Eval3.div = Eval3.divide = multary("divide", ([left, right], data) => executeEval(data, left) / executeEval(data, right), Type.Number);
Eval3.mod = Eval3.modulo = multary("modulo", ([left, right], data) => executeEval(data, left) % executeEval(data, right), Type.Number);
Eval3.abs = unary("abs", (arg, data) => Math.abs(executeEval(data, arg)), Type.Number);
Eval3.floor = unary("floor", (arg, data) => Math.floor(executeEval(data, arg)), Type.Number);
Eval3.ceil = unary("ceil", (arg, data) => Math.ceil(executeEval(data, arg)), Type.Number);
Eval3.round = unary("round", (arg, data) => Math.round(executeEval(data, arg)), Type.Number);
Eval3.exp = unary("exp", (arg, data) => Math.exp(executeEval(data, arg)), Type.Number);
Eval3.log = multary("log", ([left, right], data) => Math.log(executeEval(data, left)) / Math.log(executeEval(data, right ?? Math.E)), Type.Number);
Eval3.pow = Eval3.power = multary("power", ([left, right], data) => Math.pow(executeEval(data, left), executeEval(data, right)), Type.Number);
Eval3.random = () => Eval3("random", {}, Type.Number);
operators.$random = () => Math.random();
Eval3.eq = comparator("eq", (left, right) => left === right);
Eval3.ne = comparator("ne", (left, right) => left !== right);
Eval3.gt = comparator("gt", (left, right) => left > right);
Eval3.ge = Eval3.gte = comparator("gte", (left, right) => left >= right);
Eval3.lt = comparator("lt", (left, right) => left < right);
Eval3.le = Eval3.lte = comparator("lte", (left, right) => left <= right);
Eval3.in = (value, array) => Eval3("in", [Array.isArray(value) ? Eval3.select(...value) : value, array], Type.Boolean);
operators.$in = ([value, array], data) => {
	const val = executeEval(data, value), arr = executeEval(data, array);
	if (typeof val === "object") return arr.includes(val) || arr.map(JSON.stringify).includes(JSON.stringify(val));
	return arr.includes(val);
};
Eval3.nin = (value, array) => Eval3("nin", [Array.isArray(value) ? Eval3.select(...value) : value, array], Type.Boolean);
operators.$nin = ([value, array], data) => {
	const val = executeEval(data, value), arr = executeEval(data, array);
	if (typeof val === "object") return !arr.includes(val) && !arr.map(JSON.stringify).includes(JSON.stringify(val));
	return !arr.includes(val);
};
Eval3.concat = multary("concat", (args, data) => args.map((arg) => executeEval(data, arg)).join(""), Type.String);
Eval3.regex = multary("regex", ([value, regex, flags], data) => makeRegExp(executeEval(data, regex), flags).test(executeEval(data, value)), Type.Boolean);
Eval3.startsWith = comparator("startsWith", (str, prefix) => str.startsWith(prefix));
Eval3.and = multary("and", (args, data) => {
	const type = Type.fromTerms(args, Type.Boolean);
	if (Field.boolean.includes(type.type)) return args.every((arg) => executeEval(data, arg));
	else if (Field.number.includes(type.type)) return args.map((arg) => executeEval(data, arg)).reduce((prev, curr) => prev & curr);
	else if (type.type === "bigint") return args.map((arg) => BigInt(executeEval(data, arg) ?? 0)).reduce((prev, curr) => prev & curr);
}, (...args) => Type.fromTerms(args, Type.Boolean));
Eval3.or = multary("or", (args, data) => {
	const type = Type.fromTerms(args, Type.Boolean);
	if (Field.boolean.includes(type.type)) return args.some((arg) => executeEval(data, arg));
	else if (Field.number.includes(type.type)) return args.map((arg) => executeEval(data, arg)).reduce((prev, curr) => prev | curr);
	else if (type.type === "bigint") return args.map((arg) => BigInt(executeEval(data, arg) ?? 0)).reduce((prev, curr) => prev | curr);
}, (...args) => Type.fromTerms(args, Type.Boolean));
Eval3.not = unary("not", (value, data) => {
	const type = Type.fromTerms([value], Type.Boolean);
	if (Field.boolean.includes(type.type)) return !executeEval(data, value);
	else if (Field.number.includes(type.type)) return ~executeEval(data, value);
	else if (type.type === "bigint") return ~BigInt(executeEval(data, value) ?? 0);
}, (value) => Type.fromTerms([value], Type.Boolean));
Eval3.xor = multary("xor", (args, data) => {
	const type = Type.fromTerms(args, Type.Boolean);
	if (Field.boolean.includes(type.type)) return args.map((arg) => executeEval(data, arg)).reduce((prev, curr) => prev !== curr);
	else if (Field.number.includes(type.type)) return args.map((arg) => executeEval(data, arg)).reduce((prev, curr) => prev ^ curr);
	else if (type.type === "bigint") return args.map((arg) => BigInt(executeEval(data, arg) ?? 0)).reduce((prev, curr) => prev ^ curr);
}, (...args) => Type.fromTerms(args, Type.Boolean));
Eval3.literal = multary("literal", ([value, type]) => value, (value, type) => type ? Type.fromField(type) : Type.fromTerm(value));
Eval3.number = unary("number", (arg, data) => {
	const value = executeEval(data, arg);
	return value instanceof Date ? Math.floor(value.valueOf() / 1e3) : Number(value);
}, Type.Number);
var unwrapAggr = /* @__PURE__ */ __name$3((expr, def) => {
	let type = Type.fromTerm(expr);
	type = Type.getInner(type) ?? type;
	return def && type.type === "expr" ? def : type;
}, "unwrapAggr");
Eval3.first = unary("first", (expr, table) => Array.isArray(table) ? table.map((data) => executeAggr(expr, data))[0] : Array.from(executeEval(table, expr))[0], (expr) => unwrapAggr(expr));
Eval3.sum = unary("sum", (expr, table) => Array.isArray(table) ? table.reduce((prev, curr) => prev + executeAggr(expr, curr), 0) : Array.from(executeEval(table, expr)).reduce((prev, curr) => prev + curr, 0), Type.Number);
Eval3.avg = unary("avg", (expr, table) => {
	if (Array.isArray(table)) return table.reduce((prev, curr) => prev + executeAggr(expr, curr), 0) / table.length;
	else {
		const array = Array.from(executeEval(table, expr));
		return array.reduce((prev, curr) => prev + curr, 0) / array.length;
	}
}, Type.Number);
Eval3.max = unary("max", (expr, table) => Array.isArray(table) ? table.map((data) => executeAggr(expr, data)).reduce((x, y) => x > y ? x : y, -Infinity) : Array.from(executeEval(table, expr)).reduce((x, y) => x > y ? x : y, -Infinity), (expr) => unwrapAggr(expr, Type.Number));
Eval3.min = unary("min", (expr, table) => Array.isArray(table) ? table.map((data) => executeAggr(expr, data)).reduce((x, y) => x < y ? x : y, Infinity) : Array.from(executeEval(table, expr)).reduce((x, y) => x < y ? x : y, Infinity), (expr) => unwrapAggr(expr, Type.Number));
Eval3.count = unary("count", (expr, table) => new Set(table.map((data) => executeAggr(expr, data))).size, Type.Number);
defineProperty(Eval3, "length", unary("length", (expr, table) => Array.isArray(table) ? table.map((data) => executeAggr(expr, data)).length : Array.from(executeEval(table, expr)).length, Type.Number));
operators.$object = (field, table) => mapValues(field, (value) => executeAggr(value, table));
Eval3.object = (fields) => {
	if (fields.$model) {
		const modelFields = Object.entries(fields.$model.fields);
		const prefix = fields.$prefix;
		fields = Object.fromEntries(modelFields.filter(([, field]) => Field.available(field)).filter(([path]) => path.startsWith(prefix)).map(([k]) => [k.slice(prefix.length), fields[k.slice(prefix.length)]]));
		return Object.assign(Eval3("object", fields, Type.Object(mapValues(fields, (value) => Type.fromTerm(value)))), fields);
	}
	fields = filterKeys(fields, (key) => key !== "$object");
	return Object.assign(Eval3("object", fields, Type.Object(mapValues(fields, (value) => Type.fromTerm(value)))), fields);
};
Eval3.array = unary("array", (expr, table) => Array.isArray(table) ? table.map((data) => executeAggr(expr, data)).filter((x) => !expr[Type.kType]?.ignoreNull || !isEmpty(x)) : Array.from(executeEval(table, expr)).filter((x) => !expr[Type.kType]?.ignoreNull || !isEmpty(x)), (expr) => Type.Array(Type.fromTerm(expr)));
Eval3.get = multary("get", ([x, key], data) => executeEval(data, x)?.[executeEval(data, key)], (x, key) => Type.getInner(Type.fromTerm(x), key) ?? Type.Any);
function getRecursive(args, data) {
	if (typeof args === "string") return getRecursive(["_", args], data);
	const [ref, path] = args;
	let value = data[ref];
	if (!value) return value;
	if (path in value) return value[path];
	const prefix = Object.keys(value).find((s) => path.startsWith(s + ".")) || path.split(".", 1)[0];
	const rest = path.slice(prefix.length + 1).split(".").filter(Boolean);
	rest.unshift(prefix);
	for (const key of rest) {
		value = value[key];
		if (!value) return value;
	}
	return value;
}
__name$3(getRecursive, "getRecursive");
function executeEvalExpr(expr, data) {
	for (const key in expr) if (key in operators) return operators[key](expr[key], data);
	return expr;
}
__name$3(executeEvalExpr, "executeEvalExpr");
function executeAggr(expr, data) {
	if (typeof expr === "string") return getRecursive(expr, data);
	return executeEvalExpr(expr, data);
}
__name$3(executeAggr, "executeAggr");
function executeEval(data, expr) {
	if (isComparable(expr) || isNullable(expr)) return expr;
	if (Array.isArray(expr)) return expr.map((item) => executeEval(data, item));
	return executeEvalExpr(expr, data);
}
__name$3(executeEval, "executeEval");
function executeUpdate(data, update, ref) {
	for (const key in update) {
		let root = data;
		const path = key.split(".");
		const last = path.pop();
		for (const key2 of path) root = root[key2] ||= {};
		root[last] = executeEval({
			[ref]: data,
			_: data
		}, update[key]);
	}
	return data;
}
__name$3(executeUpdate, "executeUpdate");
function isComparable(value) {
	return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || value instanceof Date;
}
__name$3(isComparable, "isComparable");
function isFlat(value) {
	return !value || typeof value !== "object" || isEvalExpr(value) || Object.keys(value).length === 0 || Array.isArray(value) || value instanceof Date || value instanceof RegExp || Binary.isSource(value);
}
__name$3(isFlat, "isFlat");
var letters = "abcdefghijklmnopqrstuvwxyz";
function randomId() {
	return Array(8).fill(0).map(() => letters[Math.floor(Math.random() * letters.length)]).join("");
}
__name$3(randomId, "randomId");
function makeRegExp(source, flags) {
	return source instanceof RegExp && !flags ? source : new RegExp(source.source ?? source, flags ?? source.flags);
}
__name$3(makeRegExp, "makeRegExp");
function unravel(source, init) {
	const result = {};
	for (const key in source) {
		let node = result;
		const segments = key.split(".").reverse();
		for (let index = segments.length - 1; index > 0; index--) {
			const segment = segments[index];
			node = node[segment] ??= {};
			if (init) node = init(node);
		}
		node[segments[0]] = source[key];
	}
	return result;
}
__name$3(unravel, "unravel");
function flatten(source, prefix = "", ignore = isFlat) {
	const result = {};
	for (const key in source) {
		const value = source[key];
		if (ignore(value)) result[`${prefix}${key}`] = value;
		else Object.assign(result, flatten(value, `${prefix}${key}.`, ignore));
	}
	return result;
}
__name$3(flatten, "flatten");
function getCell(row, path) {
	if (path in row) return row[path];
	if (path.includes(".")) {
		const index = path.indexOf(".");
		return getCell(row[path.slice(0, index)] ?? {}, path.slice(index + 1));
	} else return row[path];
}
__name$3(getCell, "getCell");
function isEmpty(value) {
	if (isNullable(value)) return true;
	if (typeof value !== "object") return false;
	for (const key in value) if (!isEmpty(value[key])) return false;
	return true;
}
__name$3(isEmpty, "isEmpty");
var uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
function uuidToBuffer(value) {
	if (!uuidRegex.test(value)) throw new TypeError(`invalid uuid: ${value}`);
	const hex = value.replace(/-/g, "");
	const buffer = /* @__PURE__ */ new Uint8Array(16);
	for (let i = 0; i < 16; i++) buffer[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
	return buffer;
}
__name$3(uuidToBuffer, "uuidToBuffer");
function bufferToUuid(value) {
	let bytes;
	if (value instanceof Uint8Array) bytes = value;
	else if (value instanceof ArrayBuffer) bytes = new Uint8Array(value);
	else bytes = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
	if (bytes.byteLength !== 16) throw new TypeError(`invalid uuid buffer length: ${bytes.byteLength}`);
	const hex = [];
	for (let i = 0; i < 16; i++) hex.push(bytes[i].toString(16).padStart(2, "0"));
	return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10, 16).join("")}`;
}
__name$3(bufferToUuid, "bufferToUuid");
var createRow = /* @__PURE__ */ __name$3((ref, expr = {}, prefix = "", model, intermediate) => new Proxy(expr, { get(target, key) {
	if (key === "$prefix") return prefix;
	if (key === "$model") return model;
	if (typeof key === "symbol" || key in target || key.startsWith("$")) return Reflect.get(target, key);
	if (intermediate) if (Type.isArray(expr?.[Type.kType]) && Number.isInteger(+key)) return createRow(ref, Eval3.get(expr, +key), "", model, Eval3.get(expr, +key));
	else return createRow(ref, Eval3.get(intermediate, `${prefix}${key}`), `${prefix}${key}.`, model, intermediate);
	let type;
	const field = model?.fields[prefix + key];
	if (Type.isArray(expr?.[Type.kType]) && Number.isInteger(+key)) {
		type = Type.getInner(expr?.[Type.kType]) ?? Type.fromField("expr");
		return createRow(ref, Eval3.get(expr, +key), "", model, Eval3.get(expr, +key));
	} else if (Type.getInner(expr?.[Type.kType], key)) type = Type.getInner(expr?.[Type.kType], key);
	else if (field) type = Type.fromField(field);
	else if (Object.keys(model?.fields).some((k) => k.startsWith(`${prefix}${key}.`))) type = Type.Object(Object.fromEntries(Object.entries(model?.fields).filter(([k]) => k.startsWith(`${prefix}${key}`)).map(([k, field2]) => [k.slice(prefix.length + key.length + 1), Type.fromField(field2)])));
	else type = model?.getType(`${prefix}${key}`) ?? Type.fromField("expr");
	const row = createRow(ref, Eval3("", [ref, `${prefix}${key}`], type), `${prefix}${key}.`, model);
	if (!field && Object.keys(model?.fields).some((k) => k.startsWith(`${prefix}${key}.`))) return createRow(ref, Eval3.object(row), `${prefix}${key}.`, model);
	else return row;
} }), "createRow");
var Executable = class {
	static {
		__name$3(this, "Executable");
	}
	row;
	model;
	driver;
	constructor(driver, payload) {
		Object.assign(this, payload);
		defineProperty(this, "driver", driver);
		defineProperty(this, "model", driver.model(this.table));
		defineProperty(this, "row", createRow(this.ref, Eval3.object(createRow(this.ref, {}, "", this.model)), "", this.model));
	}
	isCallaback(query) {
		if (typeof query !== "function") return false;
		return isEvalExpr(omit$1(query(this.row), ["$object"]));
	}
	resolveQuery(query = {}) {
		if (typeof query === "function") {
			const expr = query(this.row);
			return expr["$expr"] ? expr : isEvalExpr(expr) ? { $expr: expr } : expr;
		}
		if (Array.isArray(query) || query instanceof RegExp || [
			"string",
			"number",
			"bigint"
		].includes(typeof query)) {
			const { primary } = this.model;
			if (Array.isArray(primary)) throw new TypeError("invalid shorthand for composite primary key");
			return { [primary]: query };
		}
		return query;
	}
	resolveField(field) {
		if (typeof field === "string") return this.row[field];
		else if (typeof field === "function") return field(this.row);
		else if (isEvalExpr(field)) return field;
		else throw new TypeError("invalid field definition");
	}
	resolveFields(fields) {
		if (typeof fields === "function") fields = fields(this.row);
		if (typeof fields === "string") fields = [fields];
		if (Array.isArray(fields)) {
			const modelFields = Object.keys(this.model.fields);
			const entries = fields.flatMap((key) => {
				if (this.model.fields[key]) return [[key, this.row[key]]];
				else if (modelFields.some((path) => path.startsWith(key + "."))) return modelFields.filter((path) => path.startsWith(key + ".")).map((path) => [path, this.row[path]]);
				return [[key, key.split(".").reduce((row, k) => row[k], this.row)]];
			});
			return Object.fromEntries(entries);
		} else {
			const entries = Object.entries(fields).flatMap(([key, field]) => {
				if (key.startsWith("$")) return [];
				const expr = this.resolveField(field);
				if (expr["$object"] && !Type.fromTerm(expr).ignoreNull) return Object.entries(expr["$object"]).map(([key2, expr2]) => [`${key}.${key2}`, expr2]);
				return [[key, expr]];
			});
			return Object.fromEntries(entries);
		}
	}
	async execute() {
		await this.driver.database.prepared();
		await this.driver._ensureSession();
		return this.driver[this.type](this, ...this.args);
	}
};
var Selection = class _Selection extends Executable {
	static {
		__name$3(this, "Selection");
	}
	tables = {};
	constructor(driver, table, query) {
		super(driver, {
			type: "get",
			ref: randomId(),
			table,
			query: null,
			args: [{
				sort: [],
				limit: Infinity,
				offset: 0,
				group: void 0,
				having: Eval3.and(),
				optional: {}
			}]
		});
		this.tables[this.ref] = this.model;
		this.query = this.resolveQuery(query);
		if (typeof table !== "string") Object.assign(this.tables, table.tables);
	}
	where(query) {
		this.query.$and ||= [];
		this.query.$and.push(this.resolveQuery(query));
		return this;
	}
	limit(...args) {
		if (args.length > 1) this.offset(args.shift());
		this.args[0].limit = args[0];
		return this;
	}
	offset(offset) {
		this.args[0].offset = offset;
		return this;
	}
	orderBy(field, direction = "asc") {
		this.args[0].sort.push([this.resolveField(field), direction]);
		return this;
	}
	groupBy(fields, ...args) {
		this.args[0].fields = this.resolveFields(fields);
		this.args[0].group = Object.keys(this.args[0].fields);
		const extra = this.isCallaback(args[0]) ? void 0 : args.shift();
		Object.assign(this.args[0].fields, this.resolveFields(extra || {}));
		if (args[0]) this.having(args[0]);
		return new _Selection(this.driver, this);
	}
	having(query) {
		this.args[0].having["$and"].push(this.resolveField(query));
		return this;
	}
	project(fields) {
		this.args[0].fields = this.resolveFields(fields);
		return new _Selection(this.driver, this);
	}
	join(name, selection, callback = () => Eval3.and(), optional = false) {
		const fields = Object.fromEntries(Object.entries(this.model.fields).filter(([key, field]) => Field.available(field) && !key.startsWith(name + ".")).map(([key]) => [key, (row) => getCell(row[this.ref], key)]));
		const joinFields = Object.fromEntries(Object.entries(selection.model.fields).filter(([key, field]) => Field.available(field) || Field.available(this.model.fields[`${name}.${key}`])).map(([key]) => [key, (row) => Field.available(this.model.fields[`${name}.${key}`]) ? getCell(row[this.ref], `${name}.${key}`) : getCell(row[name], key)]));
		if (optional) return this.driver.ctx.model.join({
			[this.ref]: this,
			[name]: selection
		}, (t) => callback(t[this.ref], t[name]), {
			[this.ref]: false,
			[name]: true
		}).project({
			...fields,
			[name]: (row) => Eval3.ignoreNull(Eval3.object(mapValues(joinFields, (x) => x(row))))
		});
		else return this.driver.ctx.model.join({
			[this.ref]: this,
			[name]: selection
		}, (t) => callback(t[this.ref], t[name])).project({
			...fields,
			[name]: (row) => Eval3.ignoreNull(Eval3.object(mapValues(joinFields, (x) => x(row))))
		});
	}
	_action(type, ...args) {
		return new Executable(this.driver, {
			...this,
			type,
			args
		});
	}
	evaluate(callback) {
		const selection = new _Selection(this.driver, this);
		if (!callback) callback = /* @__PURE__ */ __name$3((row) => Eval3.array(Eval3.object(row)), "callback");
		const expr = Array.isArray(callback) ? Eval3.select(...callback.map((x) => this.resolveField(x))) : this.resolveField(callback);
		if (isAggrExpr(expr)) defineProperty(expr, Type.kType, Type.Array(Type.fromTerm(expr)));
		return Eval3.exec(selection._action("eval", expr));
	}
	async execute(cursor) {
		if (typeof cursor === "function") return new _Selection(this.driver, this)._action("eval", this.resolveField(cursor)).execute();
		if (Array.isArray(cursor)) cursor = { fields: cursor };
		else if (!cursor) cursor = {};
		if (cursor.fields) this.project(cursor.fields);
		if (cursor.limit !== void 0) this.limit(cursor.limit);
		if (cursor.offset !== void 0) this.offset(cursor.offset);
		if (cursor.sort) for (const field in cursor.sort) this.orderBy(field, cursor.sort[field]);
		const rows = await super.execute();
		if (!cursor.fields) return rows;
		return rows.map((row) => {
			return filterKeys(row, (key) => {
				return cursor.fields.some((k) => k === key || k.startsWith(`${key}.`));
			});
		});
	}
};
((Selection2) => {
	function is(sel) {
		return sel && !!sel.tables;
	}
	Selection2.is = is;
	__name$3(is, "is");
})(Selection || (Selection = {}));
function executeSort(data, modifier, name) {
	const { limit, offset, sort } = modifier;
	data.sort((a, b) => {
		for (const [field, direction] of sort) {
			const sign = direction === "asc" ? 1 : -1;
			const x = executeEval({
				[name]: a,
				_: a
			}, field);
			const y = executeEval({
				[name]: b,
				_: b
			}, field);
			if (x < y) return -sign;
			if (x > y) return sign;
		}
		return 0;
	});
	return data.slice(offset, offset + limit);
}
__name$3(executeSort, "executeSort");
function mergeQuery(base, query) {
	if (typeof query === "function") return (row) => {
		const q = query(row);
		return {
			$expr: true,
			...base,
			...q.$expr ? q : { $expr: q }
		};
	};
	else return (_) => ({
		$expr: true,
		...base,
		...query
	});
}
__name$3(mergeQuery, "mergeQuery");
var Database = class _Database extends Service {
	static {
		__name$3(this, "Database");
	}
	static transact = /* @__PURE__ */ Symbol.for("minato.transact");
	static migrate = /* @__PURE__ */ Symbol.for("minato.migrate");
	tables = /* @__PURE__ */ Object.create(null);
	drivers = [];
	types = /* @__PURE__ */ Object.create(null);
	_driver;
	stashed = /* @__PURE__ */ new Set();
	prepareTasks = /* @__PURE__ */ Object.create(null);
	migrateTasks = /* @__PURE__ */ Object.create(null);
	constructor(ctx) {
		super(ctx, "model");
	}
	refresh() {
		for (const name in this.tables) this.prepareTasks[name] = this.prepare(name);
	}
	async prepared() {
		if (this[_Database.migrate]) return;
		await Promise.all(Object.values(this.prepareTasks));
	}
	getDriver(table) {
		if (Selection.is(table)) return table.driver;
		const model = this.tables[table];
		if (!model) throw new Error(`cannot resolve table "${table}"`);
		return model.ctx?.get("database")?._driver;
	}
	async prepare(name) {
		this.stashed.add(name);
		await this.prepareTasks[name];
		await Promise.resolve();
		if (!this.stashed.delete(name)) return;
		const driver = this.getDriver(name);
		if (!driver) return;
		driver.tables.add(name);
		const { fields } = driver.model(name);
		Object.values(fields).forEach((field) => field?.transformers?.forEach((x) => driver.define(x)));
		await driver.prepare(name);
		await driver.prepareIndexes(name);
	}
	extend(name, fields, config = {}) {
		let model = this.tables[name];
		if (!model) model = this.tables[name] = new Model(name);
		Object.entries(fields).forEach(([key, field]) => {
			const transformer = [];
			this.parseField(field, transformer, void 0, (value) => field = fields[key] = value);
			if (typeof field === "object") field.transformers = transformer;
		});
		model.extend(fields, config);
		if (makeArray(model.primary).every((key) => key in fields)) defineProperty(model, "ctx", this.ctx);
		Object.entries(fields).forEach(([key, def]) => {
			if (!Relation.Type.includes(def.type)) return;
			const subprimary = !def.fields && makeArray(model.primary).includes(key);
			const [relation, inverse] = Relation.parse(def, key, model, this.tables[def.table ?? key], subprimary);
			const relModel = this.tables[relation.table];
			if (!relModel) throw new Error(`relation table ${relation.table} does not exist`);
			(model.fields[key] = Field.parse("expr")).relation = relation;
			if (def.target) (relModel.fields[def.target] ??= Field.parse("expr")).relation = inverse;
			if (relation.type === "oneToOne" || relation.type === "manyToOne") relation.fields.forEach((x, i) => {
				model.fields[x] ??= { ...relModel.fields[relation.references[i]] };
				if (!relation.required) {
					model.fields[x].nullable = true;
					model.fields[x].initial = null;
				}
			});
			else if (relation.type === "manyToMany") {
				const assocTable = Relation.buildAssociationTable(relation.table, name);
				if (this.tables[assocTable]) return;
				const shared = Object.entries(relation.shared).map(([x, y]) => [Relation.buildSharedKey(x, y), model.fields[x].deftype]);
				const fields2 = relation.fields.map((x) => [Relation.buildAssociationKey(x, name), model.fields[x].deftype]);
				const references = relation.references.map((x) => [Relation.buildAssociationKey(x, relation.table), relModel.fields[x]?.deftype]);
				this.extend(assocTable, {
					...Object.fromEntries([
						...shared,
						...fields2,
						...references
					]),
					[name]: {
						type: "manyToOne",
						table: name,
						fields: [...shared, ...fields2].map((x) => x[0]),
						references: [...Object.keys(relation.shared), ...relation.fields]
					},
					[relation.table]: {
						type: "manyToOne",
						table: relation.table,
						fields: [...shared, ...references].map((x) => x[0]),
						references: [...Object.values(relation.shared), ...relation.references]
					}
				}, { primary: [
					...shared,
					...fields2,
					...references
				].map((x) => x[0]) });
			}
		});
		if (Array.isArray(model.primary) || model.fields[model.primary].relation) model.primary = deduplicate(makeArray(model.primary).map((key) => model.fields[key].relation?.fields || key).flat());
		model.unique = model.unique.map((keys) => typeof keys === "string" ? model.fields[keys].relation?.fields || keys : keys.map((key) => model.fields[key].relation?.fields || key).flat());
		defineProperty(model, "type", Type.Object(mapValues(model.fields, (field) => Type.fromField(field))));
		this.prepareTasks[name] = this.prepare(name);
		this.ctx.emit("database/model", name);
	}
	_parseField(field, transformers = [], setInitial, setField) {
		if (field === "object") {
			setInitial?.({});
			setField?.({
				initial: {},
				deftype: "json",
				type: Type.Object()
			});
			return Type.Object();
		} else if (field === "array") {
			setInitial?.([]);
			setField?.({
				initial: [],
				deftype: "json",
				type: Type.Array()
			});
			return Type.Array();
		} else if (typeof field === "string" && this.types[field]) {
			transformers.push({
				types: [field],
				load: this.types[field].load,
				dump: this.types[field].dump
			}, ...this.types[field].transformers ?? []);
			setInitial?.(this.types[field].initial);
			setField?.({
				...this.types[field],
				type: field
			});
			return Type.fromField(field);
		} else if (typeof field === "string") {
			setInitial?.(Field.getInitial(field.split("(")[0]));
			setField?.(field);
			return Type.fromField(field.split("(")[0]);
		} else if (typeof field === "object" && field.type === "object") {
			const inner = field.inner ? unravel(field.inner, (value) => (value.type = "object", value.inner ??= {})) : /* @__PURE__ */ Object.create(null);
			const initial = /* @__PURE__ */ Object.create(null);
			const res = Type.Object(mapValues(inner, (x, k) => this.parseField(x, transformers, (value) => initial[k] = value)));
			setInitial?.(Field.getInitial("json", initial));
			setField?.({
				initial: Field.getInitial("json", initial),
				...field,
				deftype: "json",
				type: res
			});
			return res;
		} else if (typeof field === "object" && field.type === "array") {
			const res = field.inner ? Type.Array(this.parseField(field.inner, transformers)) : Type.Array();
			setInitial?.([]);
			setField?.({
				initial: [],
				...field,
				deftype: "json",
				type: res
			});
			return res;
		} else if (typeof field === "object" && this.types[field.type]) {
			transformers.push({
				types: [field.type],
				load: this.types[field.type].load,
				dump: this.types[field.type].dump
			}, ...this.types[field.type].transformers ?? []);
			setInitial?.(field.initial === void 0 ? this.types[field.type].initial : field.initial);
			setField?.({
				initial: this.types[field.type].initial,
				...field
			});
			return Type.fromField(field.type);
		} else {
			setInitial?.(Field.getInitial(field.type, field.initial));
			setField?.(field);
			return Type.fromField(field.type);
		}
	}
	parseField(field, transformers = [], setInitial, setField) {
		let midfield;
		let type = this._parseField(field, transformers, setInitial, (value) => (midfield = value, setField?.(value)));
		if (typeof field === "object" && field.load && field.dump) {
			if (type.inner) type = Type.fromField(this.define({
				...omit$1(midfield, ["load", "dump"]),
				type
			}));
			const name = this.define({
				...field,
				deftype: midfield.deftype,
				type: type.type
			});
			transformers.push({
				types: [name],
				load: field.load,
				dump: field.dump
			});
			setInitial?.(field.initial);
			setField?.({
				...field,
				deftype: midfield.deftype ?? this.types[type.type]?.deftype ?? type.type,
				initial: midfield.initial,
				type: name
			});
			return Type.fromField(name);
		}
		if (typeof midfield === "object") setField?.({
			...midfield,
			deftype: midfield.deftype ?? this.types[type.type]?.deftype ?? type?.type
		});
		return type;
	}
	define(name, field) {
		if (typeof name === "object") {
			field = name;
			name = void 0;
		}
		if (name && this.types[name]) throw new Error(`type "${name}" already defined`);
		if (!name) while (this.types[name = "_define_" + randomId()]);
		const transformers = [];
		const type = this._parseField(field, transformers, void 0, (value) => field = value);
		field.transformers = transformers;
		this.ctx.effect(() => {
			this.types[name] = { ...field };
			this.types[name].deftype ??= this.types[field.type]?.deftype ?? type.type;
			return () => delete this.types[name];
		});
		return name;
	}
	migrate(name, fields, callback) {
		this.extend(name, fields, { callback });
	}
	select(table, query, include) {
		let sel = new Selection(this.getDriver(table), table, query);
		if (typeof table !== "string") return sel;
		const whereOnly = include === null, isAssoc = !!include?.$assoc;
		const rawQuery = typeof query === "function" ? query : () => query;
		const modelFields = this.tables[table].fields;
		if (include) include = filterKeys(include, (key) => !!modelFields[key]?.relation);
		for (const key in {
			...sel.query,
			...sel.query.$not
		}) if (modelFields[key]?.relation) {
			if (sel.query[key] === null && !modelFields[key].relation.required) sel.query[key] = Object.fromEntries(modelFields[key].relation.references.map((k) => [k, null]));
			if (sel.query[key] && typeof sel.query[key] !== "function" && typeof sel.query[key] === "object" && Object.keys(sel.query[key]).every((x) => modelFields[key].relation.fields.includes(`${key}.${x}`))) {
				Object.entries(sel.query[key]).forEach(([k, v]) => sel.query[`${key}.${k}`] = v);
				delete sel.query[key];
			}
			if (sel.query.$not?.[key] === null && !modelFields[key].relation.required) sel.query.$not[key] = Object.fromEntries(modelFields[key].relation.references.map((k) => [k, null]));
			if (sel.query.$not?.[key] && typeof sel.query.$not[key] !== "function" && typeof sel.query.$not[key] === "object" && Object.keys(sel.query.$not[key]).every((x) => modelFields[key].relation.fields.includes(`${key}.${x}`))) {
				Object.entries(sel.query.$not[key]).forEach(([k, v]) => sel.query.$not[`${key}.${k}`] = v);
				delete sel.query.$not[key];
			}
			if (!include || !Object.getOwnPropertyNames(include).includes(key)) (include ??= {})[key] = true;
		}
		sel.query = omit$1(sel.query, Object.keys(include ?? {}));
		if (Object.keys(sel.query.$not ?? {}).length) {
			sel.query.$not = omit$1(sel.query.$not, Object.keys(include ?? {}));
			if (Object.keys(sel.query.$not).length === 0) Reflect.deleteProperty(sel.query, "$not");
		}
		if (include && typeof include === "object") {
			if (typeof table !== "string") throw new Error("cannot include relations on derived selection");
			const extraFields = [];
			const applyQuery = /* @__PURE__ */ __name$3((sel2, key) => {
				const query2 = rawQuery(sel2.row);
				const relQuery = query2[key] !== void 0 ? query2[key] : query2.$not?.[key] !== void 0 ? { $not: query2.$not?.[key] } : void 0;
				return relQuery === void 0 ? sel2 : sel2.where(this.transformRelationQuery(table, sel2.row, key, relQuery));
			}, "applyQuery");
			for (const key in include) {
				if (!include[key] || !modelFields[key]?.relation) continue;
				const relation = modelFields[key].relation;
				const relModel = this.tables[relation.table];
				if (relation.type === "oneToOne" || relation.type === "manyToOne") {
					sel = whereOnly ? sel : sel.join(key, this.select(relation.table, typeof include[key] === "object" ? filterKeys(include[key], (k) => !relModel.fields[k]?.relation) : {}, typeof include[key] === "object" ? filterKeys(include[key], (k) => !!relModel.fields[k]?.relation) : include[key]), (self, other) => Eval3.and(...relation.fields.map((k, i) => Eval3.eq(self[k], other[relation.references[i]]))), !isAssoc);
					sel = applyQuery(sel, key);
				} else if (relation.type === "oneToMany") {
					sel = whereOnly ? sel : sel.join(key, this.select(relation.table, typeof include[key] === "object" ? filterKeys(include[key], (k) => !relModel.fields[k]?.relation) : {}, typeof include[key] === "object" ? filterKeys(include[key], (k) => !!relModel.fields[k]?.relation) : include[key]), (self, other) => Eval3.and(...relation.fields.map((k, i) => Eval3.eq(self[k], other[relation.references[i]]))), true);
					sel = applyQuery(sel, key);
					sel = whereOnly ? sel : sel.groupBy([...Object.entries(modelFields).filter(([k, field]) => !extraFields.some((x) => k.startsWith(`${x}.`)) && Field.available(field)).map(([k]) => k), ...extraFields], { [key]: (row) => Eval3.ignoreNull(Eval3.array(row[key])) });
				} else if (relation.type === "manyToMany") {
					const assocTable = Relation.buildAssociationTable(relation.table, table);
					const references = relation.fields.map((x) => Relation.buildAssociationKey(x, table));
					const shared = Object.entries(relation.shared).map(([x, y]) => [Relation.buildSharedKey(x, y), {
						field: x,
						reference: y
					}]);
					sel = whereOnly ? sel : sel.join(key, this.select(assocTable, {}, {
						$assoc: true,
						[relation.table]: include[key]
					}), (self, other) => Eval3.and(...shared.map(([k, v]) => Eval3.eq(self[v.field], other[k])), ...relation.fields.map((k, i) => Eval3.eq(self[k], other[references[i]]))), true);
					sel = applyQuery(sel, key);
					sel = whereOnly ? sel : sel.groupBy([...Object.entries(modelFields).filter(([k, field]) => !extraFields.some((x) => k.startsWith(`${x}.`)) && Field.available(field)).map(([k]) => k), ...extraFields], { [key]: (row) => Eval3.ignoreNull(Eval3.array(row[key][relation.table])) });
				}
				extraFields.push(key);
			}
		}
		return sel;
	}
	join(tables, query = (...args) => Eval3.and(), optional) {
		const oldTables = tables;
		if (Array.isArray(oldTables)) tables = Object.fromEntries(oldTables.map((name) => [name, this.select(name)]));
		let sels = mapValues(tables, (t) => {
			return typeof t === "string" ? this.select(t) : t;
		});
		if (Object.keys(sels).length === 0) throw new Error("no tables to join");
		const drivers = new Set(Object.values(sels).map((sel2) => sel2.driver[_Database.transact] ?? sel2.driver));
		if (drivers.size !== 1) throw new Error("cannot join tables from different drivers");
		if (Object.keys(sels).length === 2 && (optional?.[0] || optional?.[Object.keys(sels)[0]])) {
			if (optional[1] || optional[Object.keys(sels)[1]]) throw new Error("full join is not supported");
			sels = Object.fromEntries(Object.entries(sels).reverse());
		}
		const sel = new Selection([...drivers][0], sels);
		if (Array.isArray(oldTables)) {
			sel.args[0].having = Eval3.and(query(...oldTables.map((name) => sel.row[name])));
			sel.args[0].optional = Object.fromEntries(oldTables.map((name, index) => [name, optional?.[index]]));
		} else {
			sel.args[0].having = Eval3.and(query(sel.row));
			sel.args[0].optional = optional;
		}
		return this.select(sel);
	}
	async get(table, query, cursor) {
		let fields = Array.isArray(cursor) ? cursor : cursor?.fields;
		fields = fields ? Object.fromEntries(fields.map((x) => [x, true])) : cursor?.include;
		return this.select(table, query, fields).execute(cursor);
	}
	async eval(table, expr, query) {
		return this.select(table, query).execute(typeof expr === "function" ? expr : () => expr);
	}
	async set(table, query, update) {
		const rawUpdate = typeof update === "function" ? update : () => update;
		let sel = this.select(table, query, null);
		if (typeof update === "function") update = update(sel.row);
		if (makeArray(sel.model.primary).some((key) => key in update)) throw new TypeError(`cannot modify primary key`);
		const relations = Object.entries(sel.model.fields).filter(([key, field]) => key in update && field.relation).map(([key, field]) => [key, field.relation]);
		if (relations.length) return await this.ensureTransaction(async (database) => {
			const rows = await database.get(table, query);
			sel = database.select(table, query, null);
			let baseUpdate = omit$1(rawUpdate(sel.row), relations.map(([key]) => key));
			baseUpdate = sel.model.format(baseUpdate);
			for (const [key] of relations) await Promise.all(rows.map((row) => database.processRelationUpdate(table, row, key, rawUpdate(row)[key])));
			return Object.keys(baseUpdate).length === 0 ? {} : await sel._action("set", baseUpdate).execute();
		});
		update = sel.model.format(update);
		if (Object.keys(update).length === 0) return {};
		return sel._action("set", update).execute();
	}
	async setOne(table, query, update) {
		const sel = this.select(table, query, null);
		if (typeof update === "function") update = update(sel.row);
		if (makeArray(sel.model.primary).some((key) => key in update)) throw new TypeError(`cannot modify primary key`);
		update = sel.model.format(update);
		if (Object.keys(update).length === 0) return (await this.get(table, query))[0];
		return sel._action("setOne", update).execute();
	}
	async remove(table, query) {
		return this.select(table, query, null)._action("remove").execute();
	}
	async create(table, data) {
		const sel = this.select(table);
		if (!this.hasRelation(table, data)) {
			const { primary, autoInc } = sel.model;
			if (!autoInc) {
				if (makeArray(primary).some((key) => getCell(data, key) === void 0)) throw new Error("missing primary key");
			}
			return sel._action("create", sel.model.create(data)).execute();
		} else return this.ensureTransaction((database) => database.createOrUpdate(table, data, false));
	}
	async upsert(table, upsert, keys) {
		const sel = this.select(table);
		if (typeof upsert === "function") upsert = upsert(sel.row);
		upsert = upsert.map((item) => sel.model.format(item));
		keys = makeArray(keys || sel.model.primary);
		return sel._action("upsert", upsert, keys).execute();
	}
	makeProxy(marker, getDriver) {
		const drivers = /* @__PURE__ */ new Map();
		const database = new Proxy(this, { get: /* @__PURE__ */ __name$3((target, p, receiver) => {
			if (p === /* @__PURE__ */ Symbol.for("cordis.tracker")) return void 0;
			if (p === marker) return true;
			if (p !== "getDriver") return Reflect.get(target, p, receiver);
			return (name) => {
				const original = this.getDriver(name);
				let driver = drivers.get(original);
				if (!driver) {
					driver = getDriver?.(original, database) ?? new Proxy(original, { get: /* @__PURE__ */ __name$3((target2, p2, receiver2) => {
						if (p2 === "database") return database;
						return Reflect.get(target2, p2, receiver2);
					}, "get") });
					drivers.set(original, driver);
				}
				return driver;
			};
		}, "get") });
		return database;
	}
	withTransaction(callback) {
		return this.transact(callback);
	}
	async transact(callback) {
		if (this[_Database.transact]) throw new Error("nested transactions are not supported");
		const finalTasks = [];
		const database = this.makeProxy(_Database.transact, (driver) => {
			let initialized = false, session;
			let _resolve, _reject;
			const sessionTask = new Promise((resolve, reject) => {
				_resolve = resolve;
				_reject = reject;
			});
			sessionTask.catch(() => {});
			driver = new Proxy(driver, { get: /* @__PURE__ */ __name$3((target, p, receiver) => {
				if (p === _Database.transact) return target;
				if (p === "database") return database;
				if (p === "session") return session;
				if (p === "_ensureSession") return () => sessionTask;
				return Reflect.get(target, p, receiver);
			}, "get") });
			const task = Promise.resolve().then(() => driver.withTransaction(async (_session) => {
				initialized = true;
				session = _session;
				_resolve();
				await initialTask;
			}));
			task.catch((error) => !initialized && _reject(error));
			finalTasks.push(task);
			return driver;
		});
		const initialTask = Promise.resolve().then(() => callback(database));
		return initialTask.finally(() => Promise.all(finalTasks));
	}
	async stopAll() {
		await Promise.all(this.drivers.splice(0).map((driver) => driver.stop()));
	}
	async drop(table) {
		if (this[_Database.transact]) throw new Error("cannot drop table in transaction");
		await this.getDriver(table).drop(table);
	}
	async dropAll() {
		if (this[_Database.transact]) throw new Error("cannot drop table in transaction");
		await Promise.all(Object.values(this.drivers).map((driver) => driver.dropAll()));
	}
	async stats() {
		await this.prepared();
		const stats = {
			size: 0,
			tables: {}
		};
		await Promise.all(Object.values(this.drivers).map(async (driver) => {
			const { size = 0, tables } = await driver.stats();
			stats.size += size;
			Object.assign(stats.tables, tables);
		}));
		return stats;
	}
	ensureTransaction(callback) {
		if (this[_Database.transact]) return callback(this);
		else return this.transact(callback);
	}
	transformRelationQuery(table, row, key, query) {
		const relation = this.tables[table].fields[key].relation;
		const results = [];
		if (relation.type === "oneToOne" || relation.type === "manyToOne") if (query === null) results.push(Eval3.nin(relation.fields.map((x) => row[x]), this.select(relation.table).evaluate(relation.references)));
		else results.push(Eval3.in(relation.fields.map((x) => row[x]), this.select(relation.table, query).evaluate(relation.references)));
		else if (relation.type === "oneToMany") {
			if (query.$or) results.push(Eval3.or(...query.$or.map((q) => this.transformRelationQuery(table, row, key, q).$expr)));
			if (query.$and) results.push(...query.$and.map((q) => this.transformRelationQuery(table, row, key, q).$expr));
			if (query.$not) results.push(Eval3.not(this.transformRelationQuery(table, row, key, query.$not).$expr));
			if (query.$some) results.push(Eval3.in(relation.fields.map((x) => row[x]), this.select(relation.table, query.$some).evaluate(relation.references)));
			if (query.$none) results.push(Eval3.nin(relation.fields.map((x) => row[x]), this.select(relation.table, query.$none).evaluate(relation.references)));
			if (query.$every) results.push(Eval3.nin(relation.fields.map((x) => row[x]), this.select(relation.table, Eval3.not(query.$every)).evaluate(relation.references)));
		} else if (relation.type === "manyToMany") {
			const assocTable = Relation.buildAssociationTable(table, relation.table);
			const fields = relation.fields.map((x) => Relation.buildAssociationKey(x, table));
			const references = relation.references.map((x) => Relation.buildAssociationKey(x, relation.table));
			if (query.$or) results.push(Eval3.or(...query.$or.map((q) => this.transformRelationQuery(table, row, key, q).$expr)));
			if (query.$and) results.push(...query.$and.map((q) => this.transformRelationQuery(table, row, key, q).$expr));
			if (query.$not) results.push(Eval3.not(this.transformRelationQuery(table, row, key, query.$not).$expr));
			if (query.$some) {
				const innerTable = this.select(relation.table, query.$some).evaluate(relation.references);
				const relTable = this.select(assocTable, (r) => Eval3.in(references.map((x) => r[x]), innerTable)).evaluate(fields);
				results.push(Eval3.in(relation.fields.map((x) => row[x]), relTable));
			}
			if (query.$none) {
				const innerTable = this.select(relation.table, query.$none).evaluate(relation.references);
				const relTable = this.select(assocTable, (r) => Eval3.in(references.map((x) => r[x]), innerTable)).evaluate(fields);
				results.push(Eval3.nin(relation.fields.map((x) => row[x]), relTable));
			}
			if (query.$every) {
				const innerTable = this.select(relation.table, Eval3.not(query.$every)).evaluate(relation.references);
				const relTable = this.select(assocTable, (r) => Eval3.in(references.map((x) => r[x]), innerTable)).evaluate(fields);
				results.push(Eval3.nin(relation.fields.map((x) => row[x]), relTable));
			}
		}
		return { $expr: Eval3.and(...results) };
	}
	async createOrUpdate(table, data, upsert = true) {
		const sel = this.select(table);
		data = { ...data };
		const tasks = [""];
		for (const key in data) if (data[key] !== void 0 && this.tables[table].fields[key]?.relation) {
			const relation = this.tables[table].fields[key].relation;
			if (relation.type === "oneToOne" && relation.required) tasks.push(key);
			else if (relation.type === "oneToOne") tasks.unshift(key);
			else if (relation.type === "oneToMany") tasks.push(key);
			else if (relation.type === "manyToOne") tasks.unshift(key);
			else if (relation.type === "manyToMany") tasks.push(key);
		}
		for (const key of [...tasks]) {
			if (!key) {
				const { primary, autoInc } = sel.model;
				const keys = makeArray(primary);
				if (keys.some((key2) => isNullable(getCell(data, key2)))) if (!autoInc) throw new Error("missing primary key");
				else {
					delete data[primary];
					upsert = false;
				}
				if (upsert) await sel._action("upsert", [sel.model.format(omit$1(data, tasks))], keys).execute();
				else Object.assign(data, await sel._action("create", sel.model.create(omit$1(data, tasks))).execute());
				continue;
			}
			const value = data[key];
			const relation = this.tables[table].fields[key].relation;
			if (relation.type === "oneToOne") {
				if (value.$literal) {
					data[key] = value.$literal;
					remove(tasks, key);
				} else if (value.$create || !isUpdateExpr(value)) {
					const result = await this.createOrUpdate(relation.table, {
						...Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])),
						...value.$create ?? value
					});
					if (!relation.required) relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(result, k));
				} else if (value.$upsert) {
					await this.upsert(relation.table, [{
						...Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])),
						...value.$upsert
					}]);
					if (!relation.required) relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(value.$upsert, k));
				} else if (value.$connect) if (relation.required) await this.set(relation.table, value.$connect, Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])));
				else {
					const result = relation.references.every((k) => value.$connect[k] !== void 0) ? [value.$connect] : await this.get(relation.table, value.$connect);
					if (result.length !== 1) throw new Error("related row not found or not unique");
					relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(result[0], k));
				}
			} else if (relation.type === "manyToOne") {
				if (value.$literal) {
					data[key] = value.$literal;
					remove(tasks, key);
				} else if (value.$create || !isUpdateExpr(value)) {
					const result = await this.createOrUpdate(relation.table, value.$create ?? value);
					relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(result, k));
				} else if (value.$upsert) {
					await this.upsert(relation.table, [value.$upsert]);
					relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(value.$upsert, k));
				} else if (value.$connect) {
					const result = relation.references.every((k) => value.$connect[k] !== void 0) ? [value.$connect] : await this.get(relation.table, value.$connect);
					if (result.length !== 1) throw new Error("related row not found or not unique");
					relation.references.forEach((k, i) => data[relation.fields[i]] = getCell(result[0], k));
				}
			} else if (relation.type === "oneToMany") {
				if (value.$create || Array.isArray(value)) for (const item of makeArray(value.$create ?? value)) await this.createOrUpdate(relation.table, {
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])),
					...item
				});
				if (value.$upsert) await this.upsert(relation.table, makeArray(value.$upsert).map((r) => ({
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])),
					...r
				})));
				if (value.$connect) await this.set(relation.table, value.$connect, Object.fromEntries(relation.references.map((k, i) => [k, getCell(data, relation.fields[i])])));
			} else if (relation.type === "manyToMany") {
				const assocTable = Relation.buildAssociationTable(relation.table, table);
				const fields = relation.fields.map((x) => Relation.buildAssociationKey(x, table));
				const references = relation.references.map((x) => Relation.buildAssociationKey(x, relation.table));
				const shared = Object.entries(relation.shared).map(([x, y]) => [Relation.buildSharedKey(x, y), {
					field: x,
					reference: y
				}]);
				const result = [];
				if (value.$create || Array.isArray(value)) for (const item of makeArray(value.$create ?? value)) result.push(await this.createOrUpdate(relation.table, {
					...Object.fromEntries(shared.map(([, v]) => [v.reference, getCell(item, v.reference) ?? getCell(data, v.field)])),
					...item
				}));
				if (value.$upsert) {
					const upsert2 = makeArray(value.$upsert).map((r) => ({
						...Object.fromEntries(shared.map(([, v]) => [v.reference, getCell(r, v.reference) ?? getCell(data, v.field)])),
						...r
					}));
					await this.upsert(relation.table, upsert2);
					result.push(...upsert2);
				}
				if (value.$connect) for (const item of makeArray(value.$connect)) if (references.every((k) => item[k] !== void 0)) result.push(item);
				else result.push(...await this.get(relation.table, item));
				await this.upsert(assocTable, result.map((r) => ({
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(r, v.reference) ?? getCell(data, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, getCell(data, relation.fields[i])])),
					...Object.fromEntries(references.map((k, i) => [k, getCell(r, relation.references[i])]))
				})));
			}
		}
		return data;
	}
	async processRelationUpdate(table, row, key, value) {
		const model = this.tables[table], update = /* @__PURE__ */ Object.create(null);
		const relation = this.tables[table].fields[key].relation;
		if (relation.type === "oneToOne") {
			if (value === null) value = relation.required ? { $remove: {} } : { $disconnect: {} };
			if (typeof value === "object" && !isUpdateExpr(value)) value = { $create: value };
			if (value.$remove) await this.remove(relation.table, Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])));
			if (value.$disconnect) if (relation.required) await this.set(relation.table, mergeQuery(Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])), value.$disconnect), Object.fromEntries(relation.references.map((k, i) => [k, null])));
			else Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, null])));
			if (value.$set || typeof value === "function") await this.set(relation.table, Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])), value.$set ?? value);
			if (value.$create) {
				const result = await this.createOrUpdate(relation.table, {
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...value.$create
				});
				if (!relation.required) Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(result, relation.references[i])])));
			}
			if (value.$upsert) {
				await this.upsert(relation.table, makeArray(value.$upsert).map((r) => ({
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...r
				})));
				if (!relation.required) Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(value.$upsert, relation.references[i])])));
			}
			if (value.$connect) if (relation.required) await this.set(relation.table, value.$connect, Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])));
			else {
				const result = await this.get(relation.table, value.$connect);
				if (result.length !== 1) throw new Error("related row not found or not unique");
				Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(result[0], relation.references[i])])));
			}
		} else if (relation.type === "manyToOne") {
			if (value === null) value = { $disconnect: {} };
			if (typeof value === "object" && !isUpdateExpr(value)) value = { $create: value };
			if (value.$remove) await this.remove(relation.table, Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])));
			if (value.$disconnect) Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, null])));
			if (value.$set || typeof value === "function") await this.set(relation.table, Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])), value.$set ?? value);
			if (value.$create) {
				const result = await this.createOrUpdate(relation.table, {
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...value.$create
				});
				Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(result, relation.references[i])])));
			}
			if (value.$upsert) {
				await this.upsert(relation.table, makeArray(value.$upsert).map((r) => ({
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...r
				})));
				Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(value.$upsert, relation.references[i])])));
			}
			if (value.$connect) {
				const result = await this.get(relation.table, value.$connect);
				if (result.length !== 1) throw new Error("related row not found or not unique");
				Object.assign(update, Object.fromEntries(relation.fields.map((k, i) => [k, getCell(result[0], relation.references[i])])));
			}
		} else if (relation.type === "oneToMany") {
			if (Array.isArray(value)) {
				const $create = [], $upsert = [];
				value.forEach((item) => this.hasRelation(relation.table, item) ? $create.push(item) : $upsert.push(item));
				value = {
					$remove: {},
					$create,
					$upsert
				};
			}
			if (value.$remove) await this.remove(relation.table, mergeQuery(Object.fromEntries(relation.references.map((k, i) => [k, row[relation.fields[i]]])), value.$remove));
			if (value.$disconnect) await this.set(relation.table, mergeQuery(Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])), value.$disconnect), Object.fromEntries(relation.references.map((k, i) => [k, null])));
			if (value.$set || typeof value === "function") for (const setExpr of makeArray(value.$set ?? value)) {
				const [query, update2] = setExpr.update ? [setExpr.where, setExpr.update] : [{}, setExpr];
				await this.set(relation.table, mergeQuery(Object.fromEntries(relation.references.map((k, i) => [k, row[relation.fields[i]]])), query), update2);
			}
			if (value.$create) for (const item of makeArray(value.$create)) await this.createOrUpdate(relation.table, {
				...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
				...item
			});
			if (value.$upsert) await this.upsert(relation.table, makeArray(value.$upsert).map((r) => ({
				...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
				...r
			})));
			if (value.$connect) await this.set(relation.table, value.$connect, Object.fromEntries(relation.references.map((k, i) => [k, row[relation.fields[i]]])));
		} else if (relation.type === "manyToMany") {
			const assocTable = Relation.buildAssociationTable(table, relation.table);
			const fields = relation.fields.map((x) => Relation.buildAssociationKey(x, table));
			const references = relation.references.map((x) => Relation.buildAssociationKey(x, relation.table));
			const shared = Object.entries(relation.shared).map(([x, y]) => [Relation.buildSharedKey(x, y), {
				field: x,
				reference: y
			}]);
			if (Array.isArray(value)) {
				const $create = [], $upsert = [];
				value.forEach((item) => this.hasRelation(relation.table, item) ? $create.push(item) : $upsert.push(item));
				value = {
					$disconnect: {},
					$create,
					$upsert
				};
			}
			if (value.$remove) {
				const rows = await this.select(assocTable, {
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, getCell(row, relation.fields[i])])),
					[relation.table]: value.$remove
				}, null).execute();
				await this.remove(assocTable, (r) => Eval3.in([
					...shared.map(([k, v]) => r[k]),
					...fields.map((x) => r[x]),
					...references.map((x) => r[x])
				], rows.map((r2) => [
					...shared.map(([k, v]) => getCell(r2, k)),
					...fields.map((x) => getCell(r2, x)),
					...references.map((x) => getCell(r2, x))
				])));
				await this.remove(relation.table, (r) => Eval3.in([...shared.map(([k, v]) => r[v.reference]), ...relation.references.map((x) => r[x])], rows.map((r2) => [...shared.map(([k, v]) => getCell(r2, k)), ...references.map((x) => getCell(r2, x))])));
			}
			if (value.$disconnect) {
				const rows = await this.select(assocTable, {
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, getCell(row, relation.fields[i])])),
					[relation.table]: value.$disconnect
				}, null).execute();
				await this.remove(assocTable, (r) => Eval3.in([
					...shared.map(([k, v]) => r[k]),
					...fields.map((x) => r[x]),
					...references.map((x) => r[x])
				], rows.map((r2) => [
					...shared.map(([k, v]) => getCell(r2, k)),
					...fields.map((x) => getCell(r2, x)),
					...references.map((x) => getCell(r2, x))
				])));
			}
			if (value.$set) for (const setExpr of makeArray(value.$set)) {
				const [query, update2] = setExpr.update ? [setExpr.where, setExpr.update] : [{}, setExpr];
				const rows = await this.select(assocTable, (r) => ({
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, getCell(row, relation.fields[i])])),
					[relation.table]: query
				}), null).execute();
				await this.set(relation.table, (r) => Eval3.in([...shared.map(([k, v]) => r[v.reference]), ...relation.references.map((x) => r[x])], rows.map((r2) => [...shared.map(([k, v]) => getCell(r2, k)), ...references.map((x) => getCell(r2, x))])), update2);
			}
			if (value.$create) {
				const result = [];
				for (const item of makeArray(value.$create)) result.push(await this.createOrUpdate(relation.table, {
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...item
				}));
				await this.upsert(assocTable, result.map((r) => ({
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, row[relation.fields[i]]])),
					...Object.fromEntries(references.map((k, i) => [k, r[relation.references[i]]]))
				})));
			}
			if (value.$upsert) {
				await this.upsert(relation.table, makeArray(value.$upsert).map((r) => ({
					...Object.fromEntries(relation.references.map((k, i) => [k, getCell(row, relation.fields[i])])),
					...r
				})));
				await this.upsert(assocTable, makeArray(value.$upsert).map((r) => ({
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, row[relation.fields[i]]])),
					...Object.fromEntries(references.map((k, i) => [k, r[relation.references[i]]]))
				})));
			}
			if (value.$connect) {
				const rows = await this.get(relation.table, mergeQuery(Object.fromEntries(shared.map(([k, v]) => [v.reference, getCell(row, v.field)])), value.$connect));
				await this.upsert(assocTable, rows.map((r) => ({
					...Object.fromEntries(shared.map(([k, v]) => [k, getCell(row, v.field)])),
					...Object.fromEntries(fields.map((k, i) => [k, row[relation.fields[i]]])),
					...Object.fromEntries(references.map((k, i) => [k, r[relation.references[i]]]))
				})));
			}
		}
		if (Object.keys(update).length) await this.set(table, pick$1(model.format(row), makeArray(model.primary)), update);
	}
	hasRelation(table, data) {
		for (const key in data) if (data[key] !== void 0 && this.tables[table].fields[key]?.relation) return true;
		return false;
	}
};
var _Driver_decorators = [Inject("model")];
var _init;
var Driver = class {
	constructor(ctx, config) {
		this.ctx = ctx;
		this.config = config;
	}
	ctx;
	config;
	static {
		__name$3(this, "Driver");
	}
	database;
	tables = /* @__PURE__ */ new Set();
	types = /* @__PURE__ */ Object.create(null);
	async *[Service.init]() {
		await this.start();
		yield () => this.stop();
		this.ctx.model.drivers.push(this);
		yield () => remove(this.ctx.model.drivers, this);
		this.ctx.model.refresh();
		const database = this.database = Object.create(this.ctx.model);
		defineProperty(database, "ctx", this.ctx);
		defineProperty(database, Service.tracker, {
			associate: "database",
			property: "ctx"
		});
		defineProperty(database, "_driver", this);
		yield this.ctx.provide("database", database);
	}
	model(table) {
		if (typeof table === "string") {
			const model2 = this.ctx.model.tables[table];
			if (model2) return model2;
			throw new TypeError(`unknown table name "${table}"`);
		}
		if (Selection.is(table)) {
			if (!table.args[0].fields && (typeof table.table === "string" || Selection.is(table.table))) return table.model;
			const model2 = new Model("temp");
			if (table.args[0].fields) model2.fields = mapValues(table.args[0].fields, (expr) => ({ type: Type.fromTerm(expr) }));
			else model2.fields = mapValues(table.model.fields, (field) => ({ type: Type.fromField(field) }));
			return model2;
		}
		const model = new Model("temp");
		for (const key in table) {
			const subModel = this.model(table[key]);
			for (const field in subModel.fields) {
				if (!Field.available(subModel.fields[field])) continue;
				model.fields[`${key}.${field}`] = {
					expr: Eval3("", [table[key].ref, field], Type.fromField(subModel.fields[field])),
					type: Type.fromField(subModel.fields[field])
				};
			}
		}
		return model;
	}
	async migrate(name, hooks) {
		const database = this.ctx.model.makeProxy(Database.migrate);
		const model = this.model(name);
		await (database.migrateTasks[name] = Promise.resolve(database.migrateTasks[name]).then(() => {
			return Promise.all([...model.migrations].map(async ([migrate, keys]) => {
				try {
					if (!hooks.before(keys)) return;
					await migrate(database);
					hooks.after(keys);
				} catch (reason) {
					hooks.error(reason);
				}
			}));
		}).then(hooks.finalize).catch(hooks.error));
	}
	define(converter) {
		converter.types.forEach((type) => this.types[type] = converter);
	}
	async _ensureSession() {}
	async prepareIndexes(table) {
		const oldIndexes = await this.getIndexes(table);
		const { indexes } = this.model(table);
		for (const index of indexes) {
			const oldIndex = oldIndexes.find((info) => info.name === index.name);
			if (!oldIndex) await this.createIndex(table, index);
			else if (!deepEqual(oldIndex, index)) {
				await this.dropIndex(table, index.name);
				await this.createIndex(table, index);
			}
		}
	}
};
_init = __decoratorStart(null);
Driver = __decorateElement(_init, 0, "Driver", _Driver_decorators, Driver);
__runInitializers(_init, 1, Driver);
(class _RuntimeError extends Error {
	constructor(code, message) {
		super(message || code.replace("-", " "));
		this.code = code;
	}
	code;
	static {
		__name$3(this, "RuntimeError");
	}
	name = "RuntimeError";
	static check(error, code) {
		if (!(error instanceof _RuntimeError)) return false;
		return !code || error.message === code;
	}
});
var queryOperators = {
	$or: /* @__PURE__ */ __name$3((query, data) => query.reduce((prev, query2) => prev || executeFieldQuery(query2, data), false), "$or"),
	$and: /* @__PURE__ */ __name$3((query, data) => query.reduce((prev, query2) => prev && executeFieldQuery(query2, data), true), "$and"),
	$not: /* @__PURE__ */ __name$3((query, data) => !executeFieldQuery(query, data), "$not"),
	$exists: /* @__PURE__ */ __name$3((query, data) => query !== isNullable(data), "$exists"),
	$eq: /* @__PURE__ */ __name$3((query, data) => data.valueOf() === query.valueOf(), "$eq"),
	$ne: /* @__PURE__ */ __name$3((query, data) => data.valueOf() !== query.valueOf(), "$ne"),
	$gt: /* @__PURE__ */ __name$3((query, data) => data.valueOf() > query.valueOf(), "$gt"),
	$gte: /* @__PURE__ */ __name$3((query, data) => data.valueOf() >= query.valueOf(), "$gte"),
	$lt: /* @__PURE__ */ __name$3((query, data) => data.valueOf() < query.valueOf(), "$lt"),
	$lte: /* @__PURE__ */ __name$3((query, data) => data.valueOf() <= query.valueOf(), "$lte"),
	$in: /* @__PURE__ */ __name$3((query, data) => query.includes(data), "$in"),
	$nin: /* @__PURE__ */ __name$3((query, data) => !query.includes(data), "$nin"),
	$regex: /* @__PURE__ */ __name$3((query, data) => makeRegExp(query).test(data), "$regex"),
	$regexFor: /* @__PURE__ */ __name$3((query, data) => typeof query === "string" ? makeRegExp(data).test(query) : makeRegExp(data, query.flags).test(query.input), "$regexFor"),
	$startsWith: /* @__PURE__ */ __name$3((query, data) => data.startsWith(query), "$startsWith"),
	$bitsAllSet: /* @__PURE__ */ __name$3((query, data) => (query & data) === query, "$bitsAllSet"),
	$bitsAllClear: /* @__PURE__ */ __name$3((query, data) => (query & data) === 0, "$bitsAllClear"),
	$bitsAnySet: /* @__PURE__ */ __name$3((query, data) => (query & data) !== 0, "$bitsAnySet"),
	$bitsAnyClear: /* @__PURE__ */ __name$3((query, data) => (query & data) !== query, "$bitsAnyClear"),
	$el: /* @__PURE__ */ __name$3((query, data) => data.some((item) => executeFieldQuery(query, item)), "$el"),
	$size: /* @__PURE__ */ __name$3((query, data) => data.length === query, "$size")
};
function executeFieldQuery(query, data) {
	if (Array.isArray(query)) return query.includes(data);
	else if (query instanceof RegExp) return query.test(data);
	else if (isComparable(query)) return data.valueOf() === query.valueOf();
	else if (isNullable(query)) return isNullable(data);
	for (const key in query) if (key in queryOperators) {
		if (!queryOperators[key](query[key], data)) return false;
	}
	return true;
}
__name$3(executeFieldQuery, "executeFieldQuery");
function executeQuery(data, query, ref, env = {}) {
	return Object.entries(query).every(([key, value]) => {
		if (key === "$and") return value.reduce((prev, query2) => prev && executeQuery(data, query2, ref, env), true);
		else if (key === "$or") return value.reduce((prev, query2) => prev || executeQuery(data, query2, ref, env), false);
		else if (key === "$not") return !executeQuery(data, value, ref, env);
		else if (key === "$expr") return executeEval({
			...env,
			[ref]: data,
			_: data
		}, value);
		try {
			const flattenQuery = isFlat(query[key]) ? { [key]: query[key] } : flatten(query[key], `${key}.`);
			return Object.entries(flattenQuery).every(([key2, value2]) => executeFieldQuery(value2, getCell(data, key2)));
		} catch {
			return false;
		}
	});
}
__name$3(executeQuery, "executeQuery");
var index_default$2 = Database;
//#endregion
//#region node_modules/@cordisjs/sql-utils/lib/index.js
var __defProp$2 = Object.defineProperty;
var __name$2 = (target, value) => __defProp$2(target, "name", {
	value,
	configurable: true
});
function escapeId(value) {
	return "`" + value + "`";
}
__name$2(escapeId, "escapeId");
function isBracketed(value) {
	return value.startsWith("(") && value.endsWith(")");
}
__name$2(isBracketed, "isBracketed");
function isSqlJson(type) {
	return type ? type.type === "json" || !!type.inner : false;
}
__name$2(isSqlJson, "isSqlJson");
var Builder = class {
	constructor(driver, tables) {
		this.driver = driver;
		this.state.tables = tables;
		this.queryOperators = {
			$or: /* @__PURE__ */ __name$2((key, value) => this.logicalOr(value.map((value2) => this.parseFieldQuery(key, value2))), "$or"),
			$and: /* @__PURE__ */ __name$2((key, value) => this.logicalAnd(value.map((value2) => this.parseFieldQuery(key, value2))), "$and"),
			$not: /* @__PURE__ */ __name$2((key, value) => this.logicalNot(this.parseFieldQuery(key, value)), "$not"),
			$exists: /* @__PURE__ */ __name$2((key, value) => this.createNullQuery(key, value), "$exists"),
			$eq: this.createEqualQuery,
			$ne: this.comparator("!="),
			$gt: this.comparator(">"),
			$gte: this.comparator(">="),
			$lt: this.comparator("<"),
			$lte: this.comparator("<="),
			$in: /* @__PURE__ */ __name$2((key, value) => this.createMemberQuery(key, value, ""), "$in"),
			$nin: /* @__PURE__ */ __name$2((key, value) => this.createMemberQuery(key, value, " NOT"), "$nin"),
			$regex: /* @__PURE__ */ __name$2((key, value) => this.createRegExpQuery(key, value), "$regex"),
			$bitsAllSet: /* @__PURE__ */ __name$2((key, value) => `${key} & ${this.escape(value)} = ${this.escape(value)}`, "$bitsAllSet"),
			$bitsAllClear: /* @__PURE__ */ __name$2((key, value) => `${key} & ${this.escape(value)} = 0`, "$bitsAllClear"),
			$bitsAnySet: /* @__PURE__ */ __name$2((key, value) => `${key} & ${this.escape(value)} != 0`, "$bitsAnySet"),
			$bitsAnyClear: /* @__PURE__ */ __name$2((key, value) => `${key} & ${this.escape(value)} != ${this.escape(value)}`, "$bitsAnyClear"),
			$el: /* @__PURE__ */ __name$2((key, value) => {
				if (Array.isArray(value)) return this.logicalOr(value.map((value2) => this.createElementQuery(key, value2)));
				else if (typeof value !== "number" && typeof value !== "string") throw new TypeError("query expr under $el is not supported");
				else return this.createElementQuery(key, value);
			}, "$el"),
			$size: /* @__PURE__ */ __name$2((key, value) => {
				if (this.isJsonQuery(key)) return `${this.jsonLength(key)} = ${this.escape(value)}`;
				else {
					if (!value) return this.logicalNot(key);
					return `${key} AND LENGTH(${key}) - LENGTH(REPLACE(${key}, ${this.escape(",")}, ${this.escape("")})) = ${this.escape(value)} - 1`;
				}
			}, "$size")
		};
		this.evalOperators = {
			$: /* @__PURE__ */ __name$2((key) => this.getRecursive(key), "$"),
			$select: /* @__PURE__ */ __name$2((args) => `${args.map((arg) => this.parseEval(arg)).join(", ")}`, "$select"),
			$if: /* @__PURE__ */ __name$2((args) => `if(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$if"),
			$ifNull: /* @__PURE__ */ __name$2((args) => `ifnull(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$ifNull"),
			$add: /* @__PURE__ */ __name$2((args) => `(${args.map((arg) => this.parseEval(arg)).join(" + ")})`, "$add"),
			$multiply: /* @__PURE__ */ __name$2((args) => `(${args.map((arg) => this.parseEval(arg)).join(" * ")})`, "$multiply"),
			$subtract: this.binary("-"),
			$divide: this.binary("/"),
			$modulo: this.binary("%"),
			$abs: /* @__PURE__ */ __name$2((arg) => `abs(${this.parseEval(arg)})`, "$abs"),
			$floor: /* @__PURE__ */ __name$2((arg) => `floor(${this.parseEval(arg)})`, "$floor"),
			$ceil: /* @__PURE__ */ __name$2((arg) => `ceil(${this.parseEval(arg)})`, "$ceil"),
			$round: /* @__PURE__ */ __name$2((arg) => `round(${this.parseEval(arg)})`, "$round"),
			$exp: /* @__PURE__ */ __name$2((arg) => `exp(${this.parseEval(arg)})`, "$exp"),
			$log: /* @__PURE__ */ __name$2((args) => `log(${args.filter((x) => !isNullable(x)).map((arg) => this.parseEval(arg)).reverse().join(", ")})`, "$log"),
			$power: /* @__PURE__ */ __name$2((args) => `power(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$power"),
			$random: /* @__PURE__ */ __name$2(() => `rand()`, "$random"),
			$concat: /* @__PURE__ */ __name$2((args) => `concat(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$concat"),
			$or: /* @__PURE__ */ __name$2((args) => {
				const type = Type.fromTerm(this.state.expr, Type.Boolean);
				if (Field.boolean.includes(type.type)) return this.logicalOr(args.map((arg) => this.parseEval(arg)));
				else return `(${args.map((arg) => this.parseEval(arg)).join(" | ")})`;
			}, "$or"),
			$and: /* @__PURE__ */ __name$2((args) => {
				const type = Type.fromTerm(this.state.expr, Type.Boolean);
				if (Field.boolean.includes(type.type)) return this.logicalAnd(args.map((arg) => this.parseEval(arg)));
				else return `(${args.map((arg) => this.parseEval(arg)).join(" & ")})`;
			}, "$and"),
			$not: /* @__PURE__ */ __name$2((arg) => {
				const type = Type.fromTerm(this.state.expr, Type.Boolean);
				if (Field.boolean.includes(type.type)) return this.logicalNot(this.parseEval(arg));
				else return `(~(${this.parseEval(arg)}))`;
			}, "$not"),
			$eq: this.binary("="),
			$ne: this.binary("!="),
			$gt: this.binary(">"),
			$gte: this.binary(">="),
			$lt: this.binary("<"),
			$lte: this.binary("<="),
			$in: /* @__PURE__ */ __name$2(([key, value]) => this.asEncoded(this.createMemberQuery(this.parseEval(key, false), value, "", key), false), "$in"),
			$nin: /* @__PURE__ */ __name$2(([key, value]) => this.asEncoded(this.createMemberQuery(this.parseEval(key, false), value, " NOT", key), false), "$nin"),
			$literal: /* @__PURE__ */ __name$2(([value, type]) => this.escape(value, type), "$literal"),
			$first: /* @__PURE__ */ __name$2((expr) => this.parseEval(expr, false), "$first"),
			$sum: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `ifnull(sum(${value}), 0)`), "$sum"),
			$avg: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `avg(${value})`), "$avg"),
			$min: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `min(${value})`), "$min"),
			$max: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `max(${value})`), "$max"),
			$count: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `count(distinct ${value})`), "$count"),
			$length: /* @__PURE__ */ __name$2((expr) => this.createAggr(expr, (value) => `count(${value})`, (value) => this.isEncoded() ? this.jsonLength(value) : this.asEncoded(`if(${value}, LENGTH(${value}) - LENGTH(REPLACE(${value}, ${this.escape(",")}, ${this.escape("")})) + 1, 0)`, false)), "$length"),
			$object: /* @__PURE__ */ __name$2((fields) => this.groupObject(fields), "$object"),
			$array: /* @__PURE__ */ __name$2((expr) => this.groupArray(this.transform(this.parseEval(expr, false), expr, "encode")), "$array"),
			$get: /* @__PURE__ */ __name$2(([x, key]) => typeof key === "string" ? this.asEncoded(`json_extract(${this.parseEval(x, false)}, '$.${key}')`, true) : this.asEncoded(`json_extract(${this.parseEval(x, false)}, concat('$[', ${this.parseEval(key)}, ']'))`, true), "$get"),
			$exec: /* @__PURE__ */ __name$2((sel) => this.parseSelection(sel), "$exec")
		};
	}
	driver;
	static {
		__name$2(this, "Builder");
	}
	escapeMap = {};
	escapeRegExp;
	createEqualQuery = this.comparator("=");
	queryOperators;
	evalOperators;
	state = {};
	$true = "1";
	$false = "0";
	modifiedTable;
	transformers = /* @__PURE__ */ Object.create(null);
	createNullQuery(key, value) {
		return `${key} is ${value ? "not " : ""}null`;
	}
	createMemberQuery(key, value, notStr = "", rawKey) {
		if (Array.isArray(value)) {
			if (!value.length) return notStr ? this.$true : this.$false;
			if (Array.isArray(value[0])) return `(${key})${notStr} in (${value.map((val) => `(${val.map((x) => this.escape(x, this.state.fieldType)).join(", ")})`).join(", ")})`;
			return `${key}${notStr} in (${value.map((val) => isEvalExpr(val) ? this.parseEval(val, false) : this.escape(val, this.state.fieldType)).join(", ")})`;
		} else if (value.$exec) return `(${key})${notStr} in ${this.parseSelection(value.$exec, true)}`;
		else if (Type.fromTerm(value)?.type === "list") {
			const res = this.listContains(this.parseEval(value), key);
			return notStr ? this.logicalNot(res) : res;
		} else {
			const res = this.jsonContains(this.parseEval(value, false), !rawKey || isEvalExpr(rawKey) ? this.encode(key, true, true) : this.escape(rawKey, "json"));
			return notStr ? this.logicalNot(res) : res;
		}
	}
	listContains(list, value) {
		return `find_in_set(${value}, ${list})`;
	}
	createElementQuery(key, value) {
		if (this.isJsonQuery(key)) return this.jsonContains(key, this.encode(this.escape(value), true, true));
		else return `find_in_set(${this.escape(value)}, ${key})`;
	}
	isJsonQuery(key) {
		return Type.fromTerm(this.state.expr)?.type === "json" || this.isEncoded(key);
	}
	comparator(operator) {
		return (key, value) => {
			return `${key} ${operator} ${this.escape(value, this.state.fieldType)}`;
		};
	}
	binary(operator) {
		return ([left, right]) => {
			return `(${this.parseEval(left)} ${operator} ${this.parseEval(right)})`;
		};
	}
	logicalAnd(conditions) {
		if (!conditions.length) return this.$true;
		if (conditions.includes(this.$false)) return this.$false;
		return conditions.join(" AND ");
	}
	logicalOr(conditions) {
		if (!conditions.length) return this.$false;
		if (conditions.includes(this.$true)) return this.$true;
		return `(${conditions.join(" OR ")})`;
	}
	logicalNot(condition) {
		return `NOT(${condition})`;
	}
	parseSelection(sel, inline = false) {
		const { args: [expr], ref, table, tables } = sel;
		const restore = this.saveState({ tables });
		const inner = this.get(table, true, true);
		const output = this.parseEval(expr, false);
		const fields = expr["$select"]?.map((x) => this.getRecursive(x["$"]));
		const where = fields && this.logicalAnd(fields.map((x) => `(${x} is not null)`));
		restore();
		if (inline || !isAggrExpr(expr)) return `(SELECT ${output} FROM ${inner} ${isBracketed(inner) ? ref : ""}${where ? ` WHERE ${where}` : ""})`;
		else return [`(ifnull((SELECT ${this.groupArray(this.transform(output, Type.getInner(Type.fromTerm(expr)), "encode"))}`, `FROM ${inner} ${isBracketed(inner) ? ref : ""}), json_array()))`].join(" ");
	}
	jsonLength(value) {
		return this.asEncoded(`json_length(${value})`, false);
	}
	jsonContains(obj, value) {
		return this.asEncoded(`json_contains(${obj}, ${value})`, false);
	}
	asEncoded(value, encoded) {
		if (encoded !== void 0) this.state.encoded = encoded;
		return value;
	}
	encode(value, encoded, pure = false, type) {
		return this.asEncoded(encoded === this.isEncoded() && !pure ? value : encoded ? `cast(${this.transform(value, type, "encode")} as json)` : this.transform(`json_unquote(${value})`, type, "decode"), pure ? void 0 : encoded);
	}
	isEncoded(key) {
		return key ? this.state.encodedMap?.[key] : this.state.encoded;
	}
	createAggr(expr, aggr, nonaggr) {
		if (this.state.group) {
			this.state.group = false;
			const value = aggr(this.parseEval(expr, false));
			this.state.group = true;
			return value;
		} else {
			const value = this.parseEval(expr, false);
			return nonaggr ? nonaggr(value) : `(select ${aggr(`json_unquote(${this.escapeId("value")})`)} from json_table(${value}, '$[*]' columns (value json path '$')) ${randomId()})`;
		}
	}
	/**
	* Convert value from SQL field to JSON field
	*/
	transform(value, type, method, miss) {
		type = Type.isType(type) ? type : Type.fromTerm(type);
		const transformer = this.transformers[type.type] ?? this.transformers[this.driver.database.types[type.type]?.type];
		return transformer?.[method] ? transformer[method](value) : miss ?? value;
	}
	groupObject(_fields) {
		const _groupObject = /* @__PURE__ */ __name$2((fields, type, prefix = "") => {
			const parse = /* @__PURE__ */ __name$2((expr, key) => {
				const value = !_fields[`${prefix}${key}`] && type && Type.getInner(type, key)?.inner ? _groupObject(expr, Type.getInner(type, key), `${prefix}${key}.`) : this.parseEval(expr, false);
				return this.isEncoded() ? `json_extract(${value}, '$')` : this.transform(value, expr, "encode");
			}, "parse");
			return `json_object(` + Object.entries(fields).map(([key, expr]) => `'${key}', ${parse(expr, key)}`).join(",") + `)`;
		}, "_groupObject");
		return this.asEncoded(_groupObject(unravel(_fields), Type.fromTerm(this.state.expr), ""), true);
	}
	groupArray(value) {
		return this.asEncoded(`ifnull(json_arrayagg(${value}), json_array())`, true);
	}
	parseFieldQuery(key, query) {
		const conditions = [];
		if (Array.isArray(query)) conditions.push(this.createMemberQuery(key, query));
		else if (query instanceof RegExp) conditions.push(this.createRegExpQuery(key, query));
		else if (isComparable(query)) conditions.push(this.createEqualQuery(key, query));
		else if (isNullable(query)) conditions.push(this.createNullQuery(key, false));
		else for (const prop in query) if (prop in this.queryOperators) conditions.push(this.queryOperators[prop](key, query[prop]));
		return this.logicalAnd(conditions);
	}
	parseQuery(query) {
		const conditions = [];
		for (const key in query) if (key === "$not") conditions.push(this.logicalNot(this.parseQuery(query.$not)));
		else if (key === "$and") conditions.push(this.logicalAnd(query.$and.map(this.parseQuery.bind(this))));
		else if (key === "$or") conditions.push(this.logicalOr(query.$or.map(this.parseQuery.bind(this))));
		else if (key === "$expr") conditions.push(this.parseEval(query.$expr));
		else {
			const flattenQuery = isFlat(query[key]) ? { [key]: query[key] } : flatten(query[key], `${key}.`);
			for (const key2 in flattenQuery) {
				const model = this.state.tables[this.state.table] ?? Object.values(this.state.tables)[0];
				const expr = Eval3("", [this.state.table ?? Object.keys(this.state.tables)[0], key2], model.getType(key2));
				const prevType = this.state.fieldType;
				this.state.fieldType = model.getType(key2);
				conditions.push(this.parseFieldQuery(this.parseEval(expr), flattenQuery[key2]));
				this.state.fieldType = prevType;
			}
		}
		return this.logicalAnd(conditions);
	}
	parseEvalExpr(expr) {
		this.state.encoded = false;
		for (const key in expr) if (key in this.evalOperators) {
			this.state.expr = expr;
			return this.evalOperators[key](expr[key]);
		}
		return this.escape(expr);
	}
	transformJsonField(obj, path) {
		return this.asEncoded(`json_extract(${obj}, '$${path}')`, true);
	}
	transformKey(key, fields, prefix) {
		if (key in fields || !key.includes(".")) return this.asEncoded(prefix + this.escapeId(key), this.isEncoded(key) ?? isSqlJson(fields[key]?.type));
		const field = Object.keys(fields).find((k) => key.startsWith(k + ".")) || key.split(".")[0];
		const rest = key.slice(field.length + 1).split(".");
		return this.transformJsonField(`${prefix}${this.escapeId(field)}`, rest.map((key2) => `.${this.escapeKey(key2)}`).join(""));
	}
	getRecursive(args) {
		if (typeof args === "string") return this.getRecursive(["_", args]);
		const [table, key] = args;
		const fields = this.state.tables?.[table]?.fields || {};
		const fkey = Object.keys(fields).find((field) => key === field || key.startsWith(field + "."));
		if (fkey && fields[fkey]?.expr) if (key === fkey) return this.parseEvalExpr(fields[fkey]?.expr);
		else {
			const field = this.parseEvalExpr(fields[fkey]?.expr);
			const rest = key.slice(fkey.length + 1).split(".");
			return this.transformJsonField(`${field}`, rest.map((key2) => `.${this.escapeKey(key2)}`).join(""));
		}
		const prefix = this.modifiedTable ? `${this.escapeId(this.state.tables?.[table]?.name ?? this.modifiedTable)}.` : !this.state.tables || table === "_" || key in fields || table in this.state.tables ? "" : `${this.escapeId(table)}.`;
		if (!(table in (this.state.tables || {})) && table in (this.state.innerTables || {})) {
			const fields2 = this.state.innerTables?.[table]?.fields || {};
			return fields2[key]?.expr ? this.parseEvalExpr(fields2[key]?.expr) : this.transformKey(key, fields2, `${this.escapeId(table)}.`);
		}
		if (!(table in (this.state.tables || {})) && table in (this.state.refTables || {})) {
			const fields2 = this.state.refTables?.[table]?.fields || {};
			const res = fields2[key]?.expr ? this.parseEvalExpr(fields2[key]?.expr) : this.transformKey(key, fields2, `${this.escapeId(table)}.`);
			if (this.state.wrappedSubquery) {
				if (res in (this.state.refFields ?? {})) return this.state.refFields[res];
				const key2 = `minato_tvar_${randomId()}`;
				(this.state.refFields ??= {})[res] = key2;
				return this.asEncoded(this.escapeId(key2), true);
			} else return res;
		}
		return this.transformKey(key, fields, prefix);
	}
	parseEval(expr, unquote = true) {
		this.state.encoded = false;
		if (typeof expr === "string" || typeof expr === "number" || typeof expr === "boolean" || expr instanceof Date || expr instanceof RegExp) return this.escape(expr);
		return unquote ? this.encode(this.parseEvalExpr(expr), false, false, Type.fromTerm(expr)) : this.parseEvalExpr(expr);
	}
	saveState(extra = {}) {
		const thisState = this.state;
		this.state = {
			refTables: {
				...this.state.refTables || {},
				...this.state.tables || {}
			},
			...extra
		};
		return () => {
			thisState.encoded = this.state.encoded;
			this.state = thisState;
		};
	}
	suffix(modifier) {
		const { limit, offset, sort, group, having } = modifier;
		let sql = "";
		if (group?.length) {
			sql += ` GROUP BY ${group.map(this.escapeId).join(", ")}`;
			const filter = this.parseEval(having);
			if (filter !== this.$true) sql += ` HAVING ${filter}`;
		}
		if (sort.length) sql += " ORDER BY " + sort.map(([expr, dir]) => {
			return `${this.parseEval(expr)} ${dir.toUpperCase()}`;
		}).join(", ");
		if (limit < Infinity) sql += " LIMIT " + limit;
		if (offset > 0) sql += " OFFSET " + offset;
		return sql;
	}
	get(sel, inline = false, group = false, addref = true) {
		const { args, table, query, ref, model } = sel;
		this.state.table = ref;
		let prefix;
		if (typeof table === "string") prefix = this.escapeId(table);
		else if (Selection.is(table)) {
			prefix = this.get(table, true);
			if (!prefix) return;
		} else {
			this.state.innerTables = Object.fromEntries(Object.values(table).map((t) => [t.ref, t.model]));
			const joins = Object.entries(table).map(([key, table2]) => {
				const restore = this.saveState({ tables: { ...table2.tables } });
				const t = `${this.get(table2, true, false, false)} AS ${this.escapeId(table2.ref)}`;
				restore();
				return [key, t];
			});
			prefix = [
				" ",
				joins[0][1],
				...joins.slice(1, -1).map(([key, join]) => `${args[0].optional?.[key] ? "LEFT" : ""} JOIN ${join} ON ${this.$true}`),
				`${args[0].optional?.[joins.at(-1)[0]] ? "LEFT " : ""}JOIN`,
				joins.at(-1)[1]
			].join(" ");
			const filter2 = this.parseEval(args[0].having);
			prefix += ` ON ${filter2}`;
		}
		const filter = this.parseQuery(query);
		if (filter === this.$false) return;
		this.state.group = group || !!args[0].group;
		const encodedMap = {};
		const fields = args[0].fields ?? Object.fromEntries(Object.entries(model.fields).filter(([, field]) => Field.available(field)).map(([key, field]) => [key, field.expr ? field.expr : Eval3("", [ref, key], Type.fromField(field))]));
		const keys = Object.entries(fields).map(([key, value]) => {
			value = this.parseEval(value, false);
			encodedMap[key] = this.state.encoded;
			return this.escapeId(key) === value ? this.escapeId(key) : `${value} AS ${this.escapeId(key)}`;
		}).join(", ");
		let suffix = this.suffix(args[0]);
		this.state.encodedMap = encodedMap;
		if (filter !== this.$true) suffix = ` WHERE ${filter}` + suffix;
		if (inline && !args[0].fields && !suffix && (typeof table === "string" || Selection.is(table))) return addref && isBracketed(prefix) ? `${prefix} ${ref}` : prefix;
		if (!prefix.includes(" ") || isBracketed(prefix)) suffix = ` ${ref}` + suffix;
		const result = `SELECT ${keys} FROM ${prefix}${suffix}`;
		return inline ? `(${result})` : result;
	}
	/**
	* Convert value from Type to Field.Type.
	* @param root indicate whether the context is inside json
	*/
	dump(value, type, root = true) {
		if (!type) return value;
		if (Type.isType(type) || isEvalExpr(type)) {
			type = Type.isType(type) ? type : Type.fromTerm(type);
			const converter = type.inner || type.type === "json" ? root ? this.driver.types["json"] : void 0 : this.driver.types[type.type];
			if (type.inner || type.type === "json") root = false;
			let res = value;
			res = Type.transform(res, type, (value2, type2) => this.dump(value2, type2, root));
			res = converter?.dump ? converter.dump(res) : res;
			const ancestor = this.driver.database.types[type.type]?.type;
			if (!root && !ancestor) res = this.transform(res, type, "dump");
			res = this.dump(res, ancestor ? Type.fromField(ancestor) : void 0, root);
			return res;
		}
		value = type.format(value);
		const result = {};
		for (const key in value) {
			const { type: ftype } = type.fields[key];
			result[key] = this.dump(value[key], ftype);
		}
		return result;
	}
	load(value, type, root = true) {
		if (!type) return value;
		const load = this.compileLoad(type, root);
		if (root && Array.isArray(value) && type instanceof Model) return value.map(load);
		return load(value);
	}
	compileTransform(type, method) {
		if (!type) return (value) => value;
		const resolvedType = Type.isType(type) ? type : Type.fromTerm(type);
		const ancestorType = this.driver.database.types[resolvedType.type]?.type;
		const transformer = this.transformers[resolvedType.type] ?? this.transformers[ancestorType];
		return transformer?.[method] ? (value) => transformer[method](value) : (value) => value;
	}
	compileLoad(type, root = true) {
		if (!type) return (value) => value;
		if (Type.isType(type) || isEvalExpr(type)) {
			const resolvedType = Type.isType(type) ? type : Type.fromTerm(type);
			const converter = this.driver.types[root && resolvedType.type === "json" ? "json" : resolvedType.type];
			const ancestor = this.driver.database.types[resolvedType.type]?.type;
			const ancestorLoad = ancestor ? this.compileLoad(Type.fromField(ancestor), root) : null;
			const transformLoad = this.compileTransform(resolvedType, "load");
			const innerLoads = /* @__PURE__ */ new WeakMap();
			const getInnerLoad = /* @__PURE__ */ __name$2((type2) => {
				if (!type2) return (value) => value;
				let load = innerLoads.get(type2);
				if (!load) {
					load = this.compileLoad(type2, false);
					innerLoads.set(type2, load);
				}
				return load;
			}, "getInnerLoad");
			return (value) => {
				let res = ancestorLoad ? ancestorLoad(value) : value;
				res = transformLoad(res);
				if (converter?.load) res = converter.load(res);
				if (resolvedType.inner) res = Type.transform(res, resolvedType, (x, type2) => getInnerLoad(type2 ?? Type.getInner(resolvedType))(x));
				return !isNullable(res) && resolvedType.inner && !Type.isArray(resolvedType) ? unravel(res) : res;
			};
		}
		const fields = type.fields;
		const fieldKeys = Object.keys(fields);
		const jsonLoad = this.driver.types["json"].load;
		const loads = fieldKeys.map((key) => this.compileLoad(fields[key].type, true));
		return (value) => {
			const result = {};
			for (let i = 0; i < fieldKeys.length; i++) {
				const key = fieldKeys[i];
				if (!(key in value)) continue;
				let val = value[key];
				if (val && this.isEncoded(key)) val = jsonLoad(val);
				result[key] = loads[i](val);
			}
			return type.parse(result);
		};
	}
	/**
	* Convert value from Type to SQL.
	*/
	escape(value, type) {
		type &&= Type.fromField(type);
		return this.escapePrimitive(type ? this.dump(value, type) : value, type);
	}
	/**
	* Convert value from Field.Type to SQL.
	*/
	escapePrimitive(value, type) {
		if (isNullable(value)) return "NULL";
		switch (typeof value) {
			case "boolean":
			case "number":
			case "bigint": return value + "";
			case "object": return this.quote(JSON.stringify(value));
			default: return this.quote(value);
		}
	}
	escapeId(value) {
		return escapeId(value);
	}
	escapeKey(value) {
		return `"${value}"`;
	}
	quote(value) {
		this.escapeRegExp ??= new RegExp(`[${Object.values(this.escapeMap).join("")}]`, "g");
		let chunkIndex = this.escapeRegExp.lastIndex = 0;
		let escapedVal = "";
		let match;
		while (match = this.escapeRegExp.exec(value)) {
			escapedVal += value.slice(chunkIndex, match.index) + this.escapeMap[match[0]];
			chunkIndex = this.escapeRegExp.lastIndex;
		}
		if (chunkIndex === 0) return "'" + value + "'";
		if (chunkIndex < value.length) return "'" + escapedVal + value.slice(chunkIndex) + "'";
		return "'" + escapedVal + "'";
	}
};
//#endregion
//#region \0vite/preload-helper.js
var scriptRel = "modulepreload";
var assetsURL = function(dep) {
	return "/" + dep;
};
var seen = {};
var __vitePreload = function preload(baseModule, deps, importerUrl) {
	let promise = Promise.resolve();
	if (deps && deps.length > 0) {
		const links = document.getElementsByTagName("link");
		const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
		const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
		function allSettled(promises) {
			return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
				status: "fulfilled",
				value
			}), (reason) => ({
				status: "rejected",
				reason
			}))));
		}
		function importMetaResolve(specifier) {
			if (import.meta.resolve) return import.meta.resolve(specifier);
			return new URL(
				specifier,
				/** #__KEEP__ */
				import.meta.url
			).href;
		}
		promise = allSettled(deps.map((dep) => {
			dep = assetsURL(dep, importerUrl);
			dep = importMetaResolve(dep);
			if (dep in seen) return;
			seen[dep] = true;
			const isCss = dep.endsWith(".css");
			for (let i = links.length - 1; i >= 0; i--) {
				const link = links[i];
				if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
			}
			const link = document.createElement("link");
			link.rel = isCss ? "stylesheet" : scriptRel;
			if (!isCss) link.as = "script";
			link.crossOrigin = "";
			link.href = dep;
			if (cspNonce) link.setAttribute("nonce", cspNonce);
			document.head.appendChild(link);
			if (isCss) return new Promise((res, rej) => {
				link.addEventListener("load", res);
				link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
			});
		}));
	}
	function handlePreloadError(err) {
		const e = new Event("vite:preloadError", { cancelable: true });
		e.payload = err;
		window.dispatchEvent(e);
		if (!e.defaultPrevented) throw err;
	}
	return promise.then((res) => {
		for (const item of res || []) {
			if (item.status !== "rejected") continue;
			handlePreloadError(item.reason);
		}
		return baseModule().catch(handlePreloadError);
	});
};
//#endregion
//#region node_modules/@cordisjs/plugin-database-sqlite/lib/index.js
var __defProp$1 = Object.defineProperty;
var __name$1 = (target, value) => __defProp$1(target, "name", {
	value,
	configurable: true
});
var en_US_default = { path: "Database path." };
var zh_CN_default = { path: "数据库路径。" };
var SQLiteBuilder = class extends Builder {
	constructor(driver, tables) {
		super(driver, tables);
		this.driver = driver;
		this.queryOperators.$regexFor = (key, value) => typeof value === "string" ? `${this.escape(value)} regexp ${key}` : value.flags?.includes("i") ? `regexp2(${key}, ${this.escape(value.input)}, 'i')` : `${this.escape(value.input)} regexp ${key}`;
		this.queryOperators.$startsWith = (key, value) => {
			const escaped = String(value).replace(/[*?[]/g, "[$&]");
			return `${key} GLOB ${this.escape(escaped + "*")}`;
		};
		this.evalOperators.$if = (args) => `iif(${args.map((arg) => this.parseEval(arg)).join(", ")})`;
		this.evalOperators.$regex = ([key, value, flags]) => flags?.includes("i") || value instanceof RegExp && value.flags?.includes("i") ? `regexp2(${this.parseEval(value)}, ${this.parseEval(key)}, ${this.escape(flags ?? value.flags)})` : `regexp(${this.parseEval(value)}, ${this.parseEval(key)})`;
		this.evalOperators.$concat = (args) => `(${args.map((arg) => this.parseEval(arg)).join("||")})`;
		this.evalOperators.$startsWith = ([key, prefix]) => {
			const k = this.parseEval(key);
			if (typeof prefix === "string") {
				const escaped = String(prefix).replace(/[*?[]/g, "[$&]");
				return `${k} GLOB ${this.escape(escaped + "*")}`;
			}
			return `${k} GLOB replace(replace(replace(${this.parseEval(prefix)}, '[', '[[]'), '*', '[*]'), '?', '[?]') || '*'`;
		};
		this.evalOperators.$modulo = ([left, right]) => `modulo(${this.parseEval(left)}, ${this.parseEval(right)})`;
		this.evalOperators.$log = ([left, right]) => isNullable(right) ? `ln(${this.parseEval(left)})` : `ln(${this.parseEval(left)}) / ln(${this.parseEval(right)})`;
		this.evalOperators.$length = (expr) => this.createAggr(expr, (value) => `count(${value})`, (value) => this.isEncoded() ? this.jsonLength(value) : this.asEncoded(`iif(${value}, LENGTH(${value}) - LENGTH(REPLACE(${value}, ${this.escape(",")}, ${this.escape("")})) + 1, 0)`, false));
		this.evalOperators.$number = (arg) => {
			const type = Type.fromTerm(arg);
			const value = this.parseEval(arg);
			const res = Field.date.includes(type.type) ? `cast(${value} / 1000 as integer)` : `cast(${this.parseEval(arg)} as double)`;
			return this.asEncoded(`ifnull(${res}, 0)`, false);
		};
		const binaryXor = /* @__PURE__ */ __name$1((left, right) => `((${left} & ~${right}) | (~${left} & ${right}))`, "binaryXor");
		this.evalOperators.$xor = (args) => {
			const type = Type.fromTerm(this.state.expr, Type.Boolean);
			if (Field.boolean.includes(type.type)) return args.map((arg) => this.parseEval(arg)).reduce((prev, curr) => `(${prev} != ${curr})`);
			else return args.map((arg) => this.parseEval(arg)).reduce((prev, curr) => binaryXor(prev, curr));
		};
		this.evalOperators.$get = ([x, key]) => typeof key === "string" ? this.asEncoded(`(${this.parseEval(x, false)} -> '$.${key}')`, true) : this.asEncoded(`(${this.parseEval(x, false)} -> ('$[' || ${this.parseEval(key)} || ']'))`, true);
		this.transformers["bigint"] = {
			encode: /* @__PURE__ */ __name$1((value) => `cast(${value} as text)`, "encode"),
			decode: /* @__PURE__ */ __name$1((value) => `cast(${value} as integer)`, "decode"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : BigInt(value), "load"),
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : `${value}`, "dump")
		};
		this.transformers["binary"] = {
			encode: /* @__PURE__ */ __name$1((value) => `hex(${value})`, "encode"),
			decode: /* @__PURE__ */ __name$1((value) => `unhex(${value})`, "decode"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) || typeof value === "object" ? value : Binary.fromHex(value), "load"),
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) || typeof value === "string" ? value : Binary.toHex(value), "dump")
		};
		this.transformers["uuid"] = {
			encode: /* @__PURE__ */ __name$1((value) => `hex(${value})`, "encode"),
			decode: /* @__PURE__ */ __name$1((value) => `unhex(${value})`, "decode"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) || typeof value === "object" ? value : !value ? null : Binary.fromHex(value), "load"),
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) || typeof value === "string" ? value : Binary.toHex(value), "dump")
		};
	}
	driver;
	static {
		__name$1(this, "SQLiteBuilder");
	}
	escapeMap = { "'": "''" };
	escapePrimitive(value, type) {
		if (value instanceof Date) value = +value;
		else if (value instanceof RegExp) value = value.source;
		else if (Binary.is(value)) return `X'${Binary.toHex(value)}'`;
		else if (Binary.isSource(value)) return `X'${Binary.toHex(Binary.fromSource(value))}'`;
		return super.escapePrimitive(value, type);
	}
	createMemberEval(rawKey, value, notStr = "") {
		const key = this.parseEval(rawKey, false);
		if (Array.isArray(value)) {
			if (!value.length) return notStr ? this.$true : this.$false;
			if (Array.isArray(value[0])) return `(${key})${notStr} in (${value.map((val) => `(${val.map((x) => this.escape(x)).join(", ")})`).join(", ")})`;
			return `${key}${notStr} in (${value.map((val) => this.escape(val)).join(", ")})`;
		} else if (value.$exec) return `(${key})${notStr} in ${this.parseSelection(value.$exec, true)}`;
		else if (Type.fromTerm(value)?.type === "list") {
			const res = this.listContains(this.parseEval(value), key);
			return notStr ? this.logicalNot(res) : res;
		} else {
			const res = this.jsonContains(this.parseEval(value, false), isEvalExpr(rawKey) ? this.encode(key, true, true) : this.escape(rawKey, "json"));
			return notStr ? this.logicalNot(res) : res;
		}
	}
	createElementQuery(key, value) {
		if (this.isJsonQuery(key)) return this.jsonContains(key, this.escape(value, "json"));
		else return `(',' || ${key} || ',') LIKE ${this.escape("%," + value + ",%")}`;
	}
	createRegExpQuery(key, value) {
		if (typeof value !== "string" && value.flags?.includes("i")) return `regexp2(${this.escape(typeof value === "string" ? value : value.source)}, ${key}, ${this.escape(value.flags)})`;
		else return `regexp(${this.escape(typeof value === "string" ? value : value.source)}, ${key})`;
	}
	listContains(list, value) {
		return `(',' || ${list} || ',') LIKE '%,' || ${value} || ',%'`;
	}
	jsonLength(value) {
		return this.asEncoded(`json_array_length(${value})`, false);
	}
	jsonContains(obj, value) {
		return this.asEncoded(`json_array_contains(${obj}, ${value})`, false);
	}
	encode(value, encoded, pure = false, type) {
		return encoded ? super.encode(value, encoded, pure, type) : encoded === this.isEncoded() && !pure ? value : this.asEncoded(this.transform(`(${value} ->> '$')`, type, "decode"), pure ? void 0 : false);
	}
	createAggr(expr, aggr, nonaggr) {
		if (!this.state.group && !nonaggr) {
			const value = this.parseEval(expr, false);
			return `(select ${aggr(escapeId("value"))} from json_each(${value}) ${randomId()})`;
		} else return super.createAggr(expr, aggr, nonaggr);
	}
	groupArray(value) {
		const res = this.isEncoded() ? `('[' || group_concat(${value}) || ']')` : `('[' || group_concat(json_quote(${value})) || ']')`;
		return this.asEncoded(`ifnull(${res}, json_array())`, true);
	}
	transformJsonField(obj, path) {
		return this.asEncoded(`(${obj} -> '$${path}')`, true);
	}
};
function getTypeDef({ deftype: type }) {
	switch (type) {
		case "primary":
		case "boolean":
		case "integer":
		case "unsigned":
		case "bigint":
		case "date":
		case "time":
		case "timestamp": return `INTEGER`;
		case "float":
		case "double":
		case "decimal": return `REAL`;
		case "char":
		case "string":
		case "text":
		case "list":
		case "json": return `TEXT`;
		case "binary": return `BLOB`;
		case "uuid": return `BLOB`;
		default: throw new Error(`unsupported type: ${type}`);
	}
}
__name$1(getTypeDef, "getTypeDef");
var SQLiteDriver = class extends Driver {
	static name = "sqlite";
	path;
	db;
	sql = new SQLiteBuilder(this);
	beforeUnload;
	_transactionTask;
	/** synchronize table schema */
	async prepare(table, dropKeys) {
		const columns = this._all(`PRAGMA table_info(${escapeId(table)})`);
		const model = this.model(table);
		const columnDefs = [];
		const indexDefs = [];
		const alter = [];
		const mapping = {};
		let shouldMigrate = false;
		for (const key in model.fields) {
			if (!Field.available(model.fields[key])) {
				if (dropKeys?.includes(key)) shouldMigrate = true;
				continue;
			}
			const legacy = [key, ...model.fields[key].legacy || []];
			const column = columns.find(({ name }) => legacy.includes(name));
			const { initial, nullable = true } = model.fields[key];
			const typedef = getTypeDef(model.fields[key]);
			let def = `${escapeId(key)} ${typedef}`;
			if (key === model.primary && model.autoInc) def += " NOT NULL PRIMARY KEY AUTOINCREMENT";
			else {
				def += (nullable ? " " : " NOT ") + "NULL";
				if (!isNullable(initial)) def += " DEFAULT " + this.sql.escape(this.sql.dump({ [key]: initial }, model)[key]);
			}
			columnDefs.push(def);
			if (!column) alter.push("ADD " + def);
			else {
				mapping[column.name] = key;
				shouldMigrate ||= column.name !== key || column.type !== typedef;
			}
		}
		if (model.primary && !model.autoInc) indexDefs.push(`PRIMARY KEY (${this._joinKeys(makeArray(model.primary))})`);
		if (model.unique) indexDefs.push(...model.unique.map((keys) => `UNIQUE (${this._joinKeys(makeArray(keys))})`));
		if (model.foreign) indexDefs.push(...Object.entries(model.foreign).map(([key, value]) => {
			const [table2, key2] = value;
			return `FOREIGN KEY (\`${key}\`) REFERENCES ${escapeId(table2)} (\`${key2}\`)`;
		}));
		if (!columns.length) {
			this.ctx.logger?.info("auto creating table %C", table);
			this._run(`CREATE TABLE ${escapeId(table)} (${[...columnDefs, ...indexDefs].join(", ")})`);
		} else if (shouldMigrate) {
			for (const { name, type, notnull, pk, dflt_value: value } of columns) {
				if (mapping[name] || dropKeys?.includes(name)) continue;
				let def = `${escapeId(name)} ${type}`;
				def += (notnull ? " NOT " : " ") + "NULL";
				if (pk) def += " PRIMARY KEY";
				if (value !== null) def += " DEFAULT " + this.sql.escape(value);
				columnDefs.push(def);
				mapping[name] = name;
			}
			const temp = table + "_temp";
			const fields = Object.keys(mapping).map(escapeId).join(", ");
			this.ctx.logger?.info("auto migrating table %C", table);
			this._run(`CREATE TABLE ${escapeId(temp)} (${[...columnDefs, ...indexDefs].join(", ")})`);
			try {
				this._run(`INSERT INTO ${escapeId(temp)} SELECT ${fields} FROM ${escapeId(table)}`);
				this._run(`DROP TABLE ${escapeId(table)}`);
			} catch (error) {
				this._run(`DROP TABLE ${escapeId(temp)}`);
				throw error;
			}
			this._run(`ALTER TABLE ${escapeId(temp)} RENAME TO ${escapeId(table)}`);
		} else if (alter.length) {
			this.ctx.logger?.info("auto updating table %C", table);
			for (const def of alter) this._run(`ALTER TABLE ${escapeId(table)} ${def}`);
		}
		if (dropKeys) return;
		dropKeys = [];
		await this.migrate(table, {
			error: this.ctx.logger?.warn,
			before: /* @__PURE__ */ __name$1((keys) => keys.every((key) => columns.some(({ name }) => name === key)), "before"),
			after: /* @__PURE__ */ __name$1((keys) => dropKeys.push(...keys), "after"),
			finalize: /* @__PURE__ */ __name$1(() => {
				if (!dropKeys.length) return;
				this.prepare(table, dropKeys);
			}, "finalize")
		});
	}
	async start() {
		this.path = this.config.path;
		if (this.path !== ":memory:") {
			this.path = fileURLToPath(new URL(this.path, this.ctx.baseUrl));
			mkdirSync(dirname(this.path), { recursive: true });
		}
		const { DatabaseSync } = await __vitePreload(async () => {
			const { DatabaseSync } = await import("node:sqlite");
			return { DatabaseSync };
		}, []);
		this.db = new DatabaseSync(this.path);
		this.db.function("regexp", (pattern, str) => +new RegExp(pattern).test(str));
		this.db.function("regexp2", (pattern, str, flags) => +new RegExp(pattern, flags).test(str));
		this.db.function("json_array_contains", (array, value) => +JSON.parse(array).includes(JSON.parse(value)));
		this.db.function("modulo", (left, right) => left % right);
		this.db.function("rand", () => Math.random());
		this.define({
			types: ["boolean"],
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : +value, "dump"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : !!value, "load")
		});
		this.define({
			types: ["json"],
			dump: /* @__PURE__ */ __name$1((value) => JSON.stringify(value), "dump"),
			load: /* @__PURE__ */ __name$1((value) => typeof value === "string" ? JSON.parse(value) : value, "load")
		});
		this.define({
			types: ["list"],
			dump: /* @__PURE__ */ __name$1((value) => Array.isArray(value) ? value.join(",") : value, "dump"),
			load: /* @__PURE__ */ __name$1((value) => value ? value.split(",") : [], "load")
		});
		this.define({
			types: [
				"date",
				"time",
				"timestamp"
			],
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : +new Date(value), "dump"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : new Date(Number(value)), "load")
		});
		this.define({
			types: ["binary"],
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : new Uint8Array(value), "dump"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : Binary.fromSource(value), "load")
		});
		this.define({
			types: ["uuid"],
			dump: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : uuidToBuffer(value), "dump"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) || typeof value === "string" ? value : bufferToUuid(value), "load")
		});
		this.define({
			types: ["primary", ...Field.number],
			dump: /* @__PURE__ */ __name$1((value) => value, "dump"),
			load: /* @__PURE__ */ __name$1((value) => isNullable(value) ? value : Number(value), "load")
		});
	}
	_joinKeys(keys) {
		return keys?.length ? keys.map((key) => `\`${key}\``).join(", ") : "*";
	}
	async stop() {
		await new Promise((resolve) => setTimeout(resolve, 0));
		this.db?.close();
	}
	_exec(sql, params, callback) {
		try {
			const result = callback(this.db.prepare(sql));
			this.ctx.logger?.debug("> %s", sql, params);
			return result;
		} catch (e) {
			this.ctx.logger?.warn("> %s", sql, params);
			throw e;
		}
	}
	_all(sql, params = [], config) {
		return this._exec(sql, params, (stmt) => {
			stmt.setReadBigInts(config?.useBigInt || false);
			return stmt.all(...params);
		});
	}
	_get(sql, params = [], config) {
		return this._exec(sql, params, (stmt) => {
			stmt.setReadBigInts(config?.useBigInt || false);
			return stmt.get(...params);
		});
	}
	_run(sql, params = [], callback) {
		this._exec(sql, params, (stmt) => stmt.run(...params));
		return callback?.();
	}
	async drop(table) {
		this._run(`DROP TABLE ${escapeId(table)}`);
	}
	async dropAll() {
		const tables = [...this.tables];
		for (const table of tables) this._run(`DROP TABLE ${escapeId(table)}`);
	}
	async stats() {
		const tables = [...this.tables];
		const pageCount = this._get(`PRAGMA page_count`);
		const pageSize = this._get(`PRAGMA page_size`);
		const stats = {
			size: Number(pageCount?.page_count ?? 0) * Number(pageSize?.page_size ?? 0),
			tables: {}
		};
		const dbstats = this._all("SELECT name, pgsize as size FROM \"dbstat\" WHERE aggregate=TRUE;");
		tables.forEach((name) => {
			stats.tables[name] = this._get(`SELECT COUNT(*) as count FROM ${escapeId(name)};`);
			stats.tables[name].size = dbstats.find((o) => o.name === name)?.size ?? 0;
		});
		return stats;
	}
	async remove(sel) {
		const { query, table, tables } = sel;
		const filter = new SQLiteBuilder(this, tables).parseQuery(query);
		if (filter === "0") return {};
		const result = this._run(`DELETE FROM ${escapeId(table)} WHERE ${filter}`, [], () => this._get(`SELECT changes() AS count`));
		return {
			matched: result.count,
			removed: result.count
		};
	}
	async get(sel) {
		const { model, tables } = sel;
		const builder = new SQLiteBuilder(this, tables);
		const sql = builder.get(sel);
		if (!sql) return [];
		const rows = this._all(sql, [], { useBigInt: true });
		return builder.load(rows, model);
	}
	async eval(sel, expr) {
		const builder = new SQLiteBuilder(this, sel.tables);
		const inner = builder.get(sel.table, true, true);
		const output = builder.parseEval(expr, false);
		const { value } = this._get(`SELECT ${output} AS value FROM ${inner}`, [], { useBigInt: true });
		return builder.load(value, expr);
	}
	_update(sel, indexFields, updateFields, update, data) {
		const { ref, table, tables, model } = sel;
		const builder = new SQLiteBuilder(this, tables);
		executeUpdate(data, update, ref);
		const row = builder.dump(data, model);
		const assignment = updateFields.map((key) => `${escapeId(key)} = ?`).join(",");
		const query = Object.fromEntries(indexFields.map((key) => [key, row[key]]));
		const filter = builder.parseQuery(query);
		this._run(`UPDATE ${escapeId(table)} SET ${assignment} WHERE ${filter}`, updateFields.map((key) => row[key] ?? null));
	}
	async set(sel, update) {
		const { model, table, query } = sel;
		const { primary } = model, fields = model.availableFields();
		const updateFields = [...new Set(Object.keys(update).map((key) => {
			return Object.keys(fields).find((field) => field === key || key.startsWith(field + "."));
		}))];
		const primaryFields = makeArray(primary);
		if (query.$expr || hasSubquery(sel.query) || Object.values(update).some((x) => hasSubquery(x))) {
			const sel2 = this.database.select(table, query);
			sel2.tables[sel.ref] = sel2.tables[sel2.ref];
			delete sel2.tables[sel2.ref];
			sel2.ref = sel.ref;
			const project = mapValues(update, (value, key) => () => isEvalExpr(value) ? value : Eval3.literal(value, model.getType(key)));
			const upsert = (await sel2.project({
				...project,
				...Object.fromEntries(primaryFields.map((x) => [x, () => Eval3("", [sel.ref, x], sel2.model.getType(x))]))
			}).execute()).map((row) => ({
				...mapValues(update, (_, key) => getCell(row, key)),
				...Object.fromEntries(primaryFields.map((x) => [x, getCell(row, x)]))
			}));
			return this.database.upsert(table, upsert);
		} else {
			const data = await this.database.get(table, query);
			for (const row of data) this._update(sel, primaryFields, updateFields, update, row);
			return { matched: data.length };
		}
	}
	async setOne(sel, data) {
		const { model, table, query } = sel;
		const { primary } = model, fields = model.availableFields();
		const updateFields = [...new Set(Object.keys(data).map((key) => {
			return Object.keys(fields).find((field) => field === key || key.startsWith(field + "."));
		}))];
		const primaryFields = makeArray(primary);
		if (query.$expr || hasSubquery(sel.query) || Object.values(data).some((x) => hasSubquery(x))) {
			const sel2 = this.database.select(table, query);
			sel2.tables[sel.ref] = sel2.tables[sel2.ref];
			delete sel2.tables[sel2.ref];
			sel2.ref = sel.ref;
			const project = mapValues(data, (value, key) => () => isEvalExpr(value) ? value : Eval3.literal(value, model.getType(key)));
			const rawUpsert = await sel2.project({
				...project,
				...Object.fromEntries(primaryFields.map((x) => [x, () => Eval3("", [sel.ref, x], sel2.model.getType(x))]))
			}).limit(1).execute();
			if (!rawUpsert.length) return;
			const row = rawUpsert[0];
			const upsert = [{
				...mapValues(data, (_, key) => getCell(row, key)),
				...Object.fromEntries(primaryFields.map((x) => [x, getCell(row, x)]))
			}];
			await this.database.upsert(table, upsert);
			return (await this.database.get(table, pick$1(upsert[0], primaryFields)))[0];
		} else {
			const row = (await this.database.get(table, query))[0];
			if (!row) return;
			this._update(sel, primaryFields, updateFields, data, row);
			return (await this.database.get(table, pick$1(row, primaryFields)))[0];
		}
	}
	_create(table, data) {
		const model = this.model(table);
		data = this.sql.dump(data, model);
		const keys = Object.keys(data);
		const sql = `INSERT INTO ${escapeId(table)} (${this._joinKeys(keys)}) VALUES (${Array(keys.length).fill("?").join(", ")})`;
		return this._run(sql, keys.map((key) => data[key] ?? null), () => this._get(`SELECT last_insert_rowid() AS id`));
	}
	async create(sel, data) {
		const { model, table } = sel;
		const { id } = this._create(table, data);
		const { autoInc, primary } = model;
		if (!autoInc || Array.isArray(primary)) return data;
		return {
			...data,
			[primary]: id
		};
	}
	async upsert(sel, data, keys) {
		if (!data.length) return {};
		const { model, table, ref } = sel;
		const fields = model.availableFields();
		const result = {
			inserted: 0,
			matched: 0,
			modified: 0
		};
		const dataFields = [...new Set(Object.keys(Object.assign({}, ...data)).map((key) => {
			return Object.keys(fields).find((field) => field === key || key.startsWith(field + "."));
		}))];
		let updateFields = difference(dataFields, keys);
		if (!updateFields.length) updateFields = [dataFields[0]];
		const step = Math.floor(960 / keys.length);
		for (let i = 0; i < data.length; i += step) {
			const chunk = data.slice(i, i + step);
			const results = await this.database.get(table, { $or: chunk.map((item) => Object.fromEntries(keys.map((key) => [key, item[key]]))) });
			for (const item of chunk) {
				const row = results.find((row2) => {
					row2 = model.format(row2);
					return keys.every((key) => deepEqual(row2[key], item[key], true));
				});
				if (row) {
					this._update(sel, keys, updateFields, item, row);
					result.matched++;
				} else {
					this._create(table, executeUpdate(model.create(), item, ref));
					result.inserted++;
				}
			}
		}
		return result;
	}
	async withTransaction(callback) {
		if (this._transactionTask) await this._transactionTask.catch(() => {});
		return this._transactionTask = (async () => {
			this._run("BEGIN TRANSACTION");
			try {
				await callback();
				this._run("COMMIT");
			} catch (error) {
				try {
					this._run("ROLLBACK");
				} catch {}
				throw error;
			}
		})();
	}
	async getIndexes(table) {
		const indexes = this._all(`SELECT type,name,tbl_name,sql FROM sqlite_master WHERE type = 'index' AND tbl_name = ?`, [table]);
		const result = [];
		for (const { name, sql } of indexes) result.push({
			name,
			unique: !sql || sql.toUpperCase().startsWith("CREATE UNIQUE"),
			keys: this._parseIndexDef(sql)
		});
		return result;
	}
	async createIndex(table, index) {
		const name = index.name ?? Object.entries(index.keys).map(([key, direction]) => `${key}_${direction ?? "asc"}`).join("+");
		const keyFields = Object.entries(index.keys).map(([key, direction]) => `${escapeId(key)} ${direction ?? "asc"}`).join(", ");
		await this._run(`create ${index.unique ? "UNIQUE" : ""} index ${escapeId(name)} ON ${escapeId(table)} (${keyFields})`);
	}
	async dropIndex(table, name) {
		await this._run(`DROP INDEX ${escapeId(name)}`);
	}
	_parseIndexDef(def) {
		if (!def) return {};
		try {
			const keys = {};
			def.match(/\((.*)\)/)[1].split(",").forEach((key) => {
				const [name, direction] = key.trim().split(" ");
				keys[name.startsWith("`") ? name.slice(1, -1) : name] = direction?.toLowerCase() === "desc" ? "desc" : "asc";
			});
			return keys;
		} catch {
			return {};
		}
	}
};
((SQLiteDriver2) => {
	SQLiteDriver2.Config = lib_default$1.object({ path: lib_default$1.string().role("path").required() }).i18n({
		"en-US": en_US_default,
		"zh-CN": zh_CN_default
	});
})(SQLiteDriver || (SQLiteDriver = {}));
var index_default$1 = SQLiteDriver;
//#endregion
//#region src/main/store.ts
var Store = class extends Service {
	ctx;
	config;
	static inject = [
		"database",
		"model",
		"timer"
	];
	ids;
	messages;
	msgTimestamps;
	sweepTimer;
	constructor(ctx, config) {
		super(ctx, "store");
		this.ctx = ctx;
		this.config = config;
		this.ids = /* @__PURE__ */ new Map();
		this.messages = /* @__PURE__ */ new Map();
		this.msgTimestamps = /* @__PURE__ */ new Map();
	}
	async [Service.init]() {
		this.start();
		return noop;
	}
	start() {
		this.initDatabase().catch((e) => this.ctx.logger.error(e));
		this.ctx.on("llob/config-updated", async (input) => {
			this.config = { msgCacheExpire: input.msgCacheExpire };
		});
	}
	async initDatabase() {
		this.ctx.model.extend("message", {
			shortId: "integer(10)",
			chatType: "unsigned",
			msgId: "string(24)",
			peerUid: "string(24)",
			msgSeq: "unsigned(10)"
		}, { primary: "shortId" });
		this.ctx.model.extend("file", {
			fileName: "string",
			fileSize: "string",
			fileUuid: "string(128)",
			msgTime: "unsigned(10)",
			peerUid: "string(24)",
			chatType: "unsigned",
			elementType: "unsigned",
			md5HexStr: "string(32)",
			originImageUrl: "string"
		}, {
			primary: "fileUuid",
			indexes: ["fileName"]
		});
		this.ctx.model.extend("group_member", {
			groupCode: "unsigned(10)",
			uin: "unsigned(10)",
			cardName: "string(60)"
		}, { primary: ["groupCode", "uin"] });
		this.ctx.model.extend("uix", {
			uid: "string(24)",
			uin: "unsigned(10)"
		}, {
			primary: "uid",
			indexes: ["uin"]
		});
		this.ctx.model.extend("temp_chat_info", {
			peerUid: "string(24)",
			groupCode: "unsigned(10)"
		}, { primary: "peerUid" });
	}
	/**
	* shortId hash 输入。要保证同一条消息在不同时机/不同视角算出来一致。
	*
	* 群消息：peerUid (= groupCode) 和 msgSeq 是 server 全局分配，所有人视角一致；msgRandom
	*   server 在两端原样广播也一致。msgId（contentHead.msgUid）在 OlPush 推回 vs SsoGetGroupMsg
	*   拉历史时**不一样**，不能放进 hash 输入。
	* C2C：peerUid 是各自视角对方的 uid（双端不同），不能进 hash。RawMessage.msgSeq 在私聊里
	*   语义是 c2cMsgSeq（server 给这条消息的全局 c2c msgSeq，双端理论上一致），但本端 send
	*   时还没拿到它（PbSendMsgResp 同步返回有，但收到 self-echo 之前 store 里这条消息字段
	*   不一定齐），所以稳妥起见 hash 输入只用两端都立刻能拿到的 (selfUid, otherUid) 排序对
	*   + msgRandom（client 自造，server 在两端原样广播，永远一致）。
	*/
	buildShortIdKey(meta) {
		if (meta.chatType === ChatType.C2C || meta.chatType === ChatType.TempC2CFromGroup) {
			const me = selfInfo.uid;
			const other = meta.senderUid === me ? meta.peerUid : meta.senderUid;
			const pair = me < other ? `${me}|${other}` : `${other}|${me}`;
			return `${meta.chatType}-${pair}-${meta.msgRandom}`;
		}
		return `${meta.chatType}-${meta.peerUid}-${meta.msgSeq}-${meta.msgRandom}`;
	}
	createMsgShortId(meta) {
		const cacheKey = this.buildShortIdKey(meta);
		const existingShortId = this.ids.get(cacheKey);
		if (existingShortId) return existingShortId;
		const shortId = createHash("md5").update(cacheKey).digest().readInt32BE();
		this.ids.set(cacheKey, shortId);
		if (this.ids.size > 1e3) {
			const firstKey = this.ids.keys().next().value;
			this.ids.delete(firstKey);
		}
		this.ctx.database.upsert("message", [{
			msgId: meta.msgId,
			shortId,
			chatType: meta.chatType,
			peerUid: meta.peerUid,
			msgSeq: meta.msgSeq
		}], ["shortId"]).catch((e) => this.ctx.logger.warn(e));
		return shortId;
	}
	async getMsgInfoByShortId(shortId) {
		const items = await this.ctx.database.get("message", { shortId });
		if (items.length) {
			const { msgId, chatType, peerUid, msgSeq } = items[0];
			return {
				msgId,
				msgSeq,
				peer: {
					chatType,
					peerUid
				}
			};
		}
	}
	getMsgBySeq(peerUid, msgSeq) {
		return this.messages.values().find((e) => e.peerUid === peerUid && e.msgSeq === msgSeq);
	}
	/** 按 (peerUid, msgRandom) 反查 cache —— C2C 撤回 push 里 sequence/msgSeq 不可靠，random 是
	*  server 在两端原样广播的 32-bit 值，是双端唯一对得上的 key。 */
	getMsgByRandom(peerUid, msgRandom) {
		return this.messages.values().find((e) => e.peerUid === peerUid && e.msgRandom === msgRandom);
	}
	getMsgByMsgId(msgId) {
		return this.messages.get(msgId);
	}
	async addFileCache(data) {
		if ((await this.ctx.database.get("file", { fileUuid: data.fileUuid })).length) return;
		this.ctx.database.upsert("file", [data], "fileUuid").catch((e) => this.ctx.logger.warn(e));
	}
	getFileCacheByName(fileName) {
		return this.ctx.database.get("file", { fileName }, { sort: { msgTime: "desc" } });
	}
	getFileCacheById(fileUuid) {
		return this.ctx.database.get("file", { fileUuid });
	}
	async addMsgCache(msg) {
		const expire = this.config.msgCacheExpire;
		if (expire === 0) return;
		const id = msg.msgId;
		this.messages.set(id, msg);
		this.msgTimestamps.set(id, Date.now());
		if (this.messages.size > 1e4) {
			const firstKey = this.messages.keys().next().value;
			this.messages.delete(firstKey);
			this.msgTimestamps.delete(firstKey);
		}
		if (!this.sweepTimer) {
			const sweepMs = Math.max(5e3, expire * 200);
			this.sweepTimer = this.ctx.interval(() => this.sweepExpired(), sweepMs);
		}
	}
	sweepExpired() {
		const now = Date.now();
		const expireMs = this.config.msgCacheExpire * 1e3;
		for (const [id, ts] of this.msgTimestamps) if (now - ts >= expireMs) {
			this.messages.delete(id);
			this.msgTimestamps.delete(id);
		} else break;
		if (this.messages.size === 0 && this.sweepTimer) {
			this.sweepTimer();
			this.sweepTimer = void 0;
		}
	}
	async getGroupMemberCardName(groupCode, uin) {
		return (await this.ctx.database.get("group_member", {
			groupCode,
			uin
		}))[0]?.cardName;
	}
	async setGroupMemberCardName(groupCode, uin, cardName) {
		return await this.ctx.database.upsert("group_member", [{
			groupCode,
			uin,
			cardName
		}]);
	}
	async addUix(uix) {
		return await this.ctx.database.upsert("uix", uix);
	}
	async getUinByUid(uid) {
		return (await this.ctx.database.get("uix", { uid }))[0]?.uin;
	}
	async getUidByUin(uin) {
		return (await this.ctx.database.get("uix", { uin }))[0]?.uid;
	}
	async addTempChatInfo(info) {
		return await this.ctx.database.upsert("temp_chat_info", [info]);
	}
	async getTempChatInfo(peerUid) {
		return (await this.ctx.database.get("temp_chat_info", { peerUid }))[0];
	}
};
//#endregion
//#region src/ntqqapi/helper/rkey.ts
var RkeyManager = class {
	ctx;
	serverUrl = "";
	rkeyData = {
		group_rkey: "",
		private_rkey: "",
		expired_time: 0
	};
	pull;
	constructor(ctx, serverUrl) {
		this.ctx = ctx;
		this.serverUrl = serverUrl;
	}
	async getRkey(refresh = false) {
		if (this.isExpired() || refresh) try {
			await this.refreshRkey();
		} catch (e) {
			this.ctx.logger.error("获取rkey失败", e);
		}
		return this.rkeyData;
	}
	isExpired() {
		return (/* @__PURE__ */ new Date()).getTime() / 1e3 > this.rkeyData.expired_time;
	}
	async refreshRkey() {
		if (this.pull) return this.pull;
		const { promise, resolve, reject } = Promise.withResolvers();
		this.pull = promise;
		try {
			const { privateRKey, groupRKey, expiredTime } = await this.ctx.ntFileApi.getRKey();
			this.rkeyData = {
				private_rkey: privateRKey,
				group_rkey: groupRKey,
				expired_time: expiredTime
			};
			resolve();
			this.pull = void 0;
			this.ctx.logger.info(`发包获取rkey成功, private:${privateRKey}, group:${groupRKey}`);
		} catch (e) {
			this.ctx.logger.warn(`发包获取rkey失败 ${e}，开始获取远程rkey`);
			try {
				this.rkeyData = await this.fetchServerRkey();
				resolve();
				this.pull = void 0;
			} catch (e) {
				promise.catch(noop);
				reject(e);
				this.pull = void 0;
				throw e;
			}
		}
	}
	async fetchServerRkey() {
		const response = await fetch(this.serverUrl);
		if (!response.ok) throw new Error(response.statusText);
		return response.json();
	}
};
//#endregion
//#region src/main/qqProtocol/direct-lib/machineGuid.ts
var logger$6 = getLogger("machine-guid");
var DEFAULT_FILE = path$4.resolve("data/machine_guid.bin");
var cache = /* @__PURE__ */ new Map();
/** 同步版 loadMachineGuid; 跟 async 版共用 cache. */
function loadMachineGuidSync(filePath = DEFAULT_FILE) {
	const resolved = path$4.resolve(filePath);
	const cached = cache.get(resolved);
	if (cached) return cached;
	if (existsSync(resolved)) {
		const buf = readFileSync(resolved);
		if (buf.length === 16) {
			cache.set(resolved, buf);
			return buf;
		}
		const backup = `${resolved}.bad-${Date.now()}`;
		try {
			renameSync(resolved, backup);
		} catch {}
		logger$6.warn(`[MachineGuid] ${resolved} length=${buf.length} (expect 16), backed up to ${backup}, regenerating`);
	}
	const guid = randomBytes(16);
	try {
		mkdirSync(path$4.dirname(resolved), { recursive: true });
	} catch {}
	writeFileSync(resolved, guid);
	logger$6.info(`[MachineGuid] generated new 16B GUID -> ${resolved}`);
	cache.set(resolved, guid);
	return guid;
}
/** 覆盖 machine_guid.bin -- session 恢复时把 persisted.guid 同步过来. */
function overwriteMachineGuid(guid, filePath = DEFAULT_FILE) {
	if (guid.length !== 16) throw new Error(`overwriteMachineGuid expected 16B, got ${guid.length}`);
	const resolved = path$4.resolve(filePath);
	try {
		mkdirSync(path$4.dirname(resolved), { recursive: true });
	} catch {}
	writeFileSync(resolved, guid);
	cache.set(resolved, guid);
}
/**
* 删除 machine_guid.bin -- 异地登录顶号(密码可能泄露)后清掉设备指纹, 下次重新随机生成一个,
* 换新设备身份重新扫码登录. 同步清 cache, 否则同进程内仍复用旧 guid.
*/
function deleteMachineGuid(filePath = DEFAULT_FILE) {
	const resolved = path$4.resolve(filePath);
	try {
		unlinkSync(resolved);
	} catch {}
	cache.delete(resolved);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/appInfo.ts
var AppInfo = {
	os: "Linux",
	kernel: "Linux",
	vendorOs: "linux",
	currentVersion: "3.2.28-48517",
	buildVer: "3.2.28-48517",
	miscBitmap: 32764,
	ptVersion: "2.0.0",
	ssoVersion: 19,
	packageName: "com.tencent.qq",
	wtLoginSdk: "nt.wtlogin.0.0.1",
	appId: 1600001615,
	subAppId: 537352510,
	appIdQrCode: 8589934611,
	mainSigMap: 169742560,
	subSigMap: 66560,
	ntLoginType: 1,
	appClientVersion: 48517,
	qua: "V1_LNX_NQ_3.2.28_48517_GW_B"
};
var DeviceInfo = {
	devType: "Linux",
	get devName() {
		return `LuckyLillia-${createHash("sha256").update(loadMachineGuidSync()).digest("hex").slice(0, 6)}`;
	},
	osVer: "Ubuntu 22.04 LTS",
	vendorName: "",
	vendorOsName: "linux",
	systemKernel: "5.15.0"
};
//#endregion
//#region src/ntqqapi/helper/highway.ts
var logger$5 = getLogger("highway");
var AbstractHighwaySession = class {
	trans;
	concurrency = 3;
	/** 单调递增的 block seq */
	nextSeq = 1;
	retryTimes = 0;
	availableServer = 0;
	constructor(trans) {
		this.trans = trans;
	}
	buildPicUpHead(offset, bodyLength, bodyMd5, retryTimes = 0) {
		logger$5.debug("buildPicUpHead:", {
			offset,
			bodyLength,
			ticketLen: this.trans.ticket?.length || 0,
			cmd: this.trans.cmd,
			appId: AppInfo.appId
		});
		return Media.ReqDataHighwayHead.encode({
			msgBaseHead: {
				version: 1,
				uin: this.trans.uin,
				command: "PicUp.DataUp",
				seq: this.nextSeq++,
				retryTimes,
				appId: AppInfo.appId,
				dataFlag: 16,
				commandId: this.trans.cmd
			},
			msgSegHead: {
				serviceId: 0,
				filesize: this.trans.size,
				dataOffset: offset,
				dataLength: bodyLength,
				serviceTicket: this.trans.ticket,
				md5: bodyMd5,
				fileMd5: this.trans.sum,
				cacheAddr: 0,
				cachePort: 0
			},
			bytesReqExtendInfo: this.trans.ext,
			timestamp: 0,
			msgLoginSigHead: {
				uint32LoginSigType: 8,
				bytesLoginSig: Buffer.alloc(0),
				appId: AppInfo.appId
			}
		});
	}
	packFrame(head, body) {
		const totalLength = 9 + head.length + body.length + 1;
		const buffer = Buffer.allocUnsafe(totalLength);
		buffer[0] = 40;
		buffer.writeUInt32BE(head.length, 1);
		buffer.writeUInt32BE(body.length, 5);
		head.copy(buffer, 9);
		body.copy(buffer, 9 + head.length);
		buffer[totalLength - 1] = 41;
		return buffer;
	}
	unpackFrame(frame) {
		const headLen = frame.readUInt32BE(1);
		const bodyLen = frame.readUInt32BE(5);
		return [frame.subarray(9, 9 + headLen), frame.subarray(9 + headLen, 9 + headLen + bodyLen)];
	}
};
/**
* 挖 bytesRspExtendInfo 里的错误字符串。highway 服务器在权限不足等场景下，
* outer errorCode/segRetCode 都是 0，但会把真正的拒绝原因（如 "No Perm"）
* 塞在 bytesRspExtendInfo 嵌套 protobuf 的 field 4 里。
*/
function extractRspExtErrorMsg(buf) {
	let p = 0;
	while (p < buf.length) {
		const tag = buf[p++];
		const wire = tag & 7;
		const fn = tag >> 3;
		if (wire === 0) while (p < buf.length && buf[p++] & 128);
		else if (wire === 2) {
			let len = 0, sh = 0;
			while (p < buf.length) {
				const b = buf[p++];
				len |= (b & 127) << sh;
				if (!(b & 128)) break;
				sh += 7;
			}
			const value = buf.subarray(p, p + len);
			p += len;
			if (fn === 4) {
				const s = value.toString("utf-8");
				if (s && /^[\x20-\x7e一-鿿]+$/.test(s)) return s;
			}
		} else return null;
	}
	return null;
}
/**
* 校验 buffer 是否是结构合法的 protobuf 编码（wire-level 校验）。
*
* 校验规则（protobuf wire format）：
*   - tag varint 低 3 位 = wire type，必须 ∈ {0,1,2,5}（3/4=group 已废弃，6/7 非法）
*   - wire 0 (varint)          ：value varint 完整不越界（≤10 字节，protobuf 上限）
*   - wire 1 (fixed64)         ：剩余 ≥ 8 字节
*   - wire 2 (length-delimited)：length varint 合法且 offset+length ≤ buf.length
*   - wire 5 (fixed32)         ：剩余 ≥ 4 字节
*   - 整个 buffer 被完整消费，结束时 offset 恰好 = buf.length
* 返回 true 表示可安全交给 decode。
*/
function isValidProtoBuffer(buf) {
	if (!buf || buf.length === 0) return false;
	const len = buf.length;
	let p = 0;
	const readTag = () => {
		let val = 0;
		let shift = 0;
		for (;;) {
			if (p >= len) return -1;
			const b = buf[p++];
			val |= (b & 127) << shift;
			if (!(b & 128)) return val;
			shift += 7;
			if (shift > 35) return -1;
		}
	};
	const skipVarint = () => {
		let shift = 0;
		for (;;) {
			if (p >= len) return false;
			if (!(buf[p++] & 128)) return true;
			shift += 7;
			if (shift > 63) return false;
		}
	};
	const readLength = () => {
		let val = 0;
		let shift = 0;
		for (;;) {
			if (p >= len) return -1;
			const b = buf[p++];
			val |= (b & 127) << shift;
			if (!(b & 128)) break;
			shift += 7;
			if (shift > 21) return -1;
		}
		return val;
	};
	while (p < len) {
		const tag = readTag();
		if (tag < 0) return false;
		const wireType = tag & 7;
		if (wireType === 0) {
			if (!skipVarint()) return false;
		} else if (wireType === 1) {
			if (p + 8 > len) return false;
			p += 8;
		} else if (wireType === 2) {
			const fieldLen = readLength();
			if (fieldLen < 0 || p + fieldLen > len) return false;
			p += fieldLen;
		} else if (wireType === 5) {
			if (p + 4 > len) return false;
			p += 4;
		} else return false;
	}
	return p === len;
}
var HighwayHttpSession = class extends AbstractHighwaySession {
	async upload() {
		const concurrency = this.concurrency && this.concurrency > 1 ? this.concurrency : 1;
		if (concurrency === 1) {
			await this.uploadSerial();
			return;
		}
		const queue = [];
		let pendingLast;
		let offset = 0;
		let done = false;
		const uploadError = [];
		const queueReady = [];
		const slotFreed = [];
		const notifyQueueReady = () => {
			while (queueReady.length > 0) queueReady.shift()();
		};
		const notifySlotFreed = () => {
			while (slotFreed.length > 0) slotFreed.shift()();
		};
		const waitQueueReady = () => new Promise((r) => queueReady.push(r));
		const waitSlotFreed = () => new Promise((r) => slotFreed.push(r));
		const reader = (async () => {
			try {
				for await (const chunk of this.trans.readable) {
					const block = chunk;
					if (pendingLast) {
						if (queue.length >= concurrency) await waitSlotFreed();
						if (uploadError.length) return;
						queue.push(pendingLast);
						notifyQueueReady();
					}
					pendingLast = {
						block,
						offset
					};
					offset += block.length;
				}
			} finally {
				done = true;
				notifyQueueReady();
			}
		})();
		const worker = async () => {
			while (true) {
				if (uploadError.length) return;
				let item;
				while (!item && (queue.length > 0 || !done)) if (queue.length > 0) {
					item = queue.shift();
					notifySlotFreed();
				} else await waitQueueReady();
				if (!item) return;
				try {
					await this.uploadBlockWithRetry(item.block, item.offset, false);
				} catch (err) {
					uploadError.push(err);
					notifyQueueReady();
					notifySlotFreed();
					return;
				}
			}
		};
		const workers = Array.from({ length: concurrency }, () => worker());
		await Promise.all([reader, ...workers]);
		if (uploadError.length) throw uploadError[0];
		if (pendingLast) await this.uploadBlockWithRetry(pendingLast.block, pendingLast.offset, true);
	}
	/** 串行实现：原 upload() 内容原样保留。 */
	async uploadSerial() {
		let offset = 0;
		for await (const chunk of this.trans.readable) {
			const block = chunk;
			const isEnd = offset + block.length >= this.trans.size;
			const upload = async () => {
				try {
					await this.uploadBlock(block, offset, void 0, void 0, isEnd);
					this.availableServer = this.retryTimes;
					this.retryTimes = 0;
				} catch (err) {
					const { message } = err;
					if ((message.includes("request timeout") || message.includes("read ECONNRESET") || message.includes("not a valid proto")) && this.retryTimes < this.trans.server.length - 1) {
						this.retryTimes++;
						await upload();
					} else throw new Error(`[Highway] httpUpload Error uploading block at offset ${offset}: ${message}`);
				}
			};
			await upload();
			offset += block.length;
		}
	}
	/**
	* 并发路径里单个块的重试逻辑。每个块独立维护自己的 retryTimes + availableServer
	* (不能复用实例字段，否则并发块互串)。
	*/
	async uploadBlockWithRetry(block, offset, isEnd) {
		let retryTimes = 0;
		let availableServer = 0;
		const upload = async () => {
			try {
				await this.uploadBlock(block, offset, retryTimes, availableServer, isEnd);
				availableServer = retryTimes;
				retryTimes = 0;
			} catch (err) {
				const { message } = err;
				if ((message.includes("request timeout") || message.includes("read ECONNRESET") || message.includes("not a valid proto")) && retryTimes < this.trans.server.length - 1) {
					retryTimes++;
					await upload();
				} else throw new Error(`[Highway] httpUpload Error uploading block at offset ${offset}: ${message}`);
			}
		};
		await upload();
	}
	async uploadBlock(block, offset, retryTimes = this.retryTimes, availableServer = this.availableServer, isEnd) {
		const chunkMd5 = getMd5BufferFromBuffer(block);
		const payload = this.buildPicUpHead(offset, block.length, chunkMd5, retryTimes);
		const frame = this.packFrame(payload, block);
		logger$5.debug("HTTP block req:", {
			offset,
			cmd: this.trans.cmd,
			bodyLen: block.length,
			ticketLen: this.trans.ticket?.length || 0,
			extLen: this.trans.ext?.length || 0,
			headHex: payload.toString("hex"),
			extHex: this.trans.ext?.toString("hex") || ""
		});
		const server = availableServer ? this.trans.server[availableServer] : this.trans.server[retryTimes];
		const resp = await this.httpPostHighwayContent(frame, `http://${server}/cgi-bin/httpconn?htcmd=0x6FF0087&uin=${this.trans.uin}`, isEnd);
		const [head, body] = this.unpackFrame(resp);
		if (!isValidProtoBuffer(head)) {
			logger$5.debug("HTTP block resp head invalid proto, raw hex:", {
				offset,
				isEnd,
				headHex: head.toString("hex")
			});
			throw new Error(`HTTP Upload response head is not a valid proto`);
		}
		const headData = Media.RespDataHighwayHead.decode(head);
		logger$5.debug("HTTP block resp:", {
			offset,
			isEnd,
			cmd: this.trans.cmd,
			errorCode: headData.errorCode,
			seg: headData.msgSegHead ? {
				retCode: headData.msgSegHead.retCode,
				dataOffset: headData.msgSegHead.dataOffset,
				dataLength: headData.msgSegHead.dataLength
			} : null,
			bodyHex: body.toString("hex").slice(0, 200)
		});
		if (headData.errorCode !== 0) throw new Error(`HTTP Upload failed with code ${headData.errorCode}`);
		const segRet = headData.msgSegHead?.retCode;
		if (segRet !== void 0 && segRet !== 0) throw new Error(`HTTP Upload seg retCode=${segRet}`);
		const ext = headData.bytesRspExtendInfo;
		if (ext && ext.length > 0) {
			const reason = extractRspExtErrorMsg(Buffer.from(ext));
			if (reason) throw new Error(`HTTP Upload rejected: ${reason}`);
		}
	}
	async httpPostHighwayContent(frame, serverURL, isEnd) {
		return new Promise((resolve, reject) => {
			const req = request(serverURL, {
				method: "POST",
				timeout: 11e3,
				headers: {
					"Connection": isEnd ? "close" : "keep-alive",
					"Accept-Encoding": "identity",
					"User-Agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2)",
					"Content-Length": frame.length.toString()
				}
			}, (res) => {
				const data = [];
				res.on("data", (chunk) => {
					data.push(chunk);
				});
				res.on("end", () => {
					resolve(Buffer.concat(data));
				});
			});
			req.on("error", (error) => {
				reject(error);
			});
			req.on("timeout", () => {
				req.destroy(/* @__PURE__ */ new Error(`Highway request timeout (11s) on ${serverURL}`));
			});
			req.write(frame);
			req.end();
		});
	}
};
//#endregion
//#region src/ntqqapi/api/file.ts
var FLASH_TRANSFER_UPLOAD_URL = "https://multimedia.qfile.qq.com/sliceupload";
var FLASH_TRANSFER_CHUNK_SIZE = 1048576;
var FLASH_TRANSFER_APP_ID = 14901;
/**
* 闪传非秒传命中分支：分片上传到 multimedia.qfile.qq.com/sliceupload。
* 每片要带累计 sha1 列表（chunkSha1[0..i]）。
*/
async function flashTransferUpload(uKey, filePath, fileSize) {
	const fileBytes = readFileSync(filePath);
	const chunkCount = Math.ceil(fileSize / FLASH_TRANSFER_CHUNK_SIZE);
	const sha1State = [];
	for (let i = 0; i < chunkCount; i++) {
		const accLen = i === chunkCount - 1 ? fileSize : (i + 1) * FLASH_TRANSFER_CHUNK_SIZE;
		sha1State.push(createHash("sha1").update(fileBytes.subarray(0, accLen)).digest());
	}
	for (let i = 0; i < chunkCount; i++) {
		const start = i * FLASH_TRANSFER_CHUNK_SIZE;
		const end = Math.min(fileSize, start + FLASH_TRANSFER_CHUNK_SIZE);
		const chunk = fileBytes.subarray(start, end);
		const payload = Media.FlashTransferUploadReq.encode({
			fieId1: 0,
			appId: FLASH_TRANSFER_APP_ID,
			fileId3: 2,
			body: {
				fieId1: Buffer.alloc(0),
				uKey,
				start,
				end: end - 1,
				sha1: createHash("sha1").update(chunk).digest(),
				sha1StateV: { state: sha1State },
				body: chunk
			}
		});
		const resp = await fetch(FLASH_TRANSFER_UPLOAD_URL, {
			method: "POST",
			headers: {
				"Accept": "*/*",
				"Connection": "Keep-Alive"
			},
			body: Buffer.from(payload)
		});
		const respBytes = Buffer.from(await resp.arrayBuffer());
		const decoded = Media.FlashTransferUploadResp.decode(respBytes);
		if (decoded.status !== "success") throw new Error(`flashTransfer upload chunk ${i} failed: ${decoded.status}`);
	}
}
var NTFileApi = class extends Service {
	ctx;
	static inject = ["qqProtocol", "ntUserApi"];
	rkeyManager;
	constructor(ctx) {
		super(ctx, "ntFileApi");
		this.ctx = ctx;
		this.rkeyManager = new RkeyManager(ctx, "https://llob.linyuchen.net/rkey");
	}
	async getVideoUrl(fileUuid, isGroup) {
		if (isGroup) {
			const { download } = await this.ctx.qqProtocol.getGroupVideoUrl(fileUuid);
			if (!download) return "";
			return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
		} else {
			const { download } = await this.ctx.qqProtocol.getPrivateVideoUrl(fileUuid);
			if (!download) return "";
			return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
		}
	}
	async getPttUrl(fileUuid, isGroup) {
		if (isGroup) {
			const { download } = await this.ctx.qqProtocol.getGroupPttUrl(fileUuid);
			return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
		} else {
			const { download } = await this.ctx.qqProtocol.getPrivatePttUrl(fileUuid);
			return `https://${download.info.domain}${download.info.urlPath}${download.rKeyParam}`;
		}
	}
	async getFileUrl(fileUuid, isGroup, groupCode) {
		if (isGroup) {
			const { download } = await this.ctx.qqProtocol.getGroupFileUrl(groupCode, fileUuid);
			return {
				retCode: Number(download.retCode),
				retMsg: download.clientWording,
				url: `https://${download.downloadDns}/ftn_handler/${download.downloadUrl.toString("hex")}/?fname=`
			};
		} else {
			const { body } = await this.ctx.qqProtocol.getPrivateFileUrl(fileUuid);
			const { download } = body.result.extra;
			const { fileName } = body.metadata;
			return {
				retCode: Number(body.retCode),
				retMsg: body.state,
				url: `https://${download.downloadDns}/ftn_handler/${download.downloadUrl.toString("hex")}/?fname=${encodeURIComponent(fileName)}`
			};
		}
	}
	async getImageUrl(originImageUrl, md5HexStr) {
		const url = originImageUrl;
		if (url) {
			const parsedUrl = new URL(IMAGE_HTTP_HOST + url);
			const imageAppid = parsedUrl.searchParams.get("appid");
			if (imageAppid && ["1406", "1407"].includes(imageAppid)) {
				let rkey = parsedUrl.searchParams.get("rkey");
				if (rkey) return IMAGE_HTTP_HOST_NT + url;
				const rkeyData = await this.rkeyManager.getRkey();
				rkey = imageAppid === "1406" ? rkeyData.private_rkey : rkeyData.group_rkey;
				return IMAGE_HTTP_HOST_NT + url + rkey;
			} else if (url.startsWith("/offpic_new/")) return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${md5HexStr.toUpperCase()}/0`;
			else return IMAGE_HTTP_HOST + url;
		} else return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${md5HexStr.toUpperCase()}/0`;
	}
	async ocrImage(imageUrl) {
		return await this.ctx.qqProtocol.imageOcr(imageUrl);
	}
	async uploadFlashFile(title, filePaths) {
		if (filePaths.length === 0) throw new Error("uploadFlashFile: filePaths empty");
		const files = [];
		let totalSize = 0;
		for (const p of filePaths) {
			const st = await stat$1(p);
			const sha1 = await getSha1HexFromFile(p);
			const md5 = await getMd5HexFromFile(p);
			files.push({
				path: p,
				name: path.basename(p),
				size: st.size,
				sha1,
				md5,
				fileUuid: randomUUID()
			});
			totalSize += st.size;
		}
		if (!selfInfo.nick) await this.ctx.ntUserApi.getSelfNick(true).catch(() => {});
		const uploaderNick = selfInfo.nick || "QQ用户";
		const fset = await this.ctx.qqProtocol.createFlashFileSet({
			title,
			totalFileCount: files.length,
			totalFileSize: totalSize,
			uploaderUin: selfInfo.uin,
			uploaderNick,
			uploaderUid: selfInfo.uid
		});
		const fileSetId = fset.fileSetId;
		for (const f of files) await this.ctx.qqProtocol.registerFlashFile(fileSetId, {
			fileUuid: f.fileUuid,
			name: f.name,
			fileSize: f.size,
			sha1Hex: f.sha1,
			md5Hex: f.md5
		});
		await this.ctx.qqProtocol.prepFlashFileSet(fileSetId);
		let reqId = 0;
		const downloads = [];
		for (const f of files) {
			const pre = await this.ctx.qqProtocol.flashFileUploadPreflight({
				fileSize: f.size,
				sha1Hex: f.sha1,
				name: f.name,
				requestId: ++reqId,
				field103: 22
			});
			if (pre.uKey) await flashTransferUpload(pre.uKey, f.path, f.size);
			if (!pre.token) throw new Error(`uploadFlashFile: preflight 没有返回 token (file ${f.name})`);
			await this.ctx.qqProtocol.flashFileUploadCommit({
				fileSize: f.size,
				sha1Hex: f.sha1,
				name: f.name,
				token: pre.token,
				time: pre.time,
				ttl: pre.ttl,
				requestId: ++reqId,
				field103: 22,
				fileSetId,
				fileUuid: f.fileUuid
			});
			const dl = await this.ctx.qqProtocol.flashFileDownloadUrl({
				fileSetId,
				fileUuid: f.fileUuid,
				fileName: f.name,
				fileSize: f.size,
				fileId: pre.token,
				requestId: ++reqId
			});
			downloads.push({
				name: f.name,
				size: f.size,
				url: dl.fullUrl,
				expire: dl.ttl
			});
		}
		await this.ctx.qqProtocol.downloadFlashFile(fileSetId, 6).catch(() => {});
		return {
			result: 0,
			errMsg: "",
			seq: 0,
			createFlashTransferResult: {
				fileSetId,
				shareLink: fset.shareLink,
				expireTime: String(fset.expireTime),
				expireLeftTime: String(fset.expireLeftTime)
			},
			downloads
		};
	}
	async downloadFlashFile(fileSetId, sceneType = 6) {
		await this.ctx.qqProtocol.downloadFlashFile(fileSetId, sceneType);
		return {
			result: 0,
			errMsg: ""
		};
	}
	flashFileListCache = /* @__PURE__ */ new Map();
	async getFlashFileList(fileSetId, _force = true) {
		return [{
			fileList: (await this.ctx.qqProtocol.getFlashFileList(fileSetId)).map((f) => ({
				fileSetId: f.fileSetId,
				cliFileId: f.fileUuid,
				fileType: f.field5 ?? 0,
				name: f.name ?? "",
				fileSize: String(f.fileSize ?? 0),
				status: 2,
				uploadStatus: 3,
				downloadStatus: 0,
				filePhysicalSize: String(f.fileSize ?? 0),
				physical: {
					id: f.fileUuid,
					status: 2,
					localPath: ""
				},
				sha1Hex: f.sha1Hex ?? "",
				md5Hex: f.md5Hex ?? "",
				fileId: f.historyToken?.token ?? ""
			})),
			isEnd: true,
			isCache: false
		}];
	}
	async getFlashFileSetIdByCode(code) {
		return {
			result: 0,
			errMsg: "",
			fileSetId: await this.ctx.qqProtocol.getFlashFileSetIdByCode(code)
		};
	}
	/** 闪传：拿单个文件的 HTTPS 下载 URL（NTV2 0x12a9_200）。
	* 用法：`getFlashFileSetIdByCode(code)` → fileSetId → `getFlashFileList(fileSetId)` 拿到
	* file 列表 → 选中文件后从 `file.fileUuid` / `file.name` / `file.fileSize` 喂进来。
	* 返回带签名的 multimedia.qfile.qq.com URL，1 小时过期。
	*
	* server 用 (fileSetId, fileUuid) 真正定位文件，不依赖 download.info.fileId 那个 token —
	* 那个 token 是 Windows 客户端从老 commit cache 里翻出来的，传不传都行。
	*
	* 不需要：0x93d1_1 (registerDownload) / 0x93e1_0 (progress polling) /
	* 0x93d9_1 (download complete) — 那些是 Windows QQ UI 用来更新自己界面的，bot 上层
	* 拿到 URL 直接 https.get 就行。 */
	async getFlashFileDownloadUrl(opts) {
		const requestId = Math.floor(Math.random() * 2147483647) + 1;
		return await this.ctx.qqProtocol.flashFileDownloadUrl({
			fileSetId: opts.fileSetId,
			fileUuid: opts.fileUuid,
			fileName: opts.fileName,
			fileSize: opts.fileSize,
			fileSha1: opts.fileSha1Hex ? Buffer.from(opts.fileSha1Hex, "hex") : void 0,
			fileMd5: opts.fileMd5Hex ? Buffer.from(opts.fileMd5Hex, "hex") : void 0,
			fileId: opts.fileId,
			requestId
		});
	}
	flashFileInfoCache = /* @__PURE__ */ new Map();
	async getFlashFileInfo(fileSetId, _force = true) {
		const info = await this.ctx.qqProtocol.getFlashFileInfo(fileSetId);
		if (!info) throw new Error("getFlashFileInfo: empty response");
		return {
			fileSetId: info.fileSetId,
			name: info.title ?? "",
			totalFileCount: "1",
			totalFileSize: String(info.totalSize ?? 0),
			shareInfo: {
				shareLink: info.shareInfo?.url ?? "",
				extractionCode: ""
			},
			uploaders: [],
			uploadInfo: {
				totalUploadedFileSize: String(info.totalSize ?? 0),
				successCount: 1,
				failedCount: 0
			},
			expireTime: String(info.expireTime ?? 0),
			expireLeftTime: Math.max(0, (info.expireTime ?? 0) - Math.floor(Date.now() / 1e3)),
			status: 2,
			uploadStatus: 4,
			downloadStatus: 0
		};
	}
	/** 闪传：基于已有 fileSet 重新分享，拿到全新 share_link + 14 天有效期。
	*
	* 跟 Windows QQ 客户端"重新分享"按钮一样的事——抓包确认 Windows QQ 也是这个流程，
	* 但有个我之前漏的关键步骤 0x93e5_4：取每个老文件的完整元数据 (含 sha1/md5/historyToken)。
	*
	* 为啥需要 0x93e5_4：list (0x93d4_1) 对 bot 自己 own 的 fileSet 即使 field3=2
	* 也只返 name/size/uuid，sha1/md5/historyToken 全空——这是 server 端 ownership
	* 限制 (大概 server 觉得 client 自己的文件 client 自己有数据)。0x93e5_4 没这限制，
	* 对自己的 fileSet 也返完整字段，所以重新分享必经它。
	*
	* 流程：
	*   fileSetId → 0x93d4_1 (list) → 拿每个文件的 fileUuid (基础字段)
	*   for fileUuid in fileSet:
	*     → 0x93e5_4 → 完整 entry (sha1Hex/md5Hex/historyToken/name/size)
	*   → 0x93cf_1 createFlashFileSet (新 fileSetId + 新 share_link)
	*   → 0x93d0_1 registerFlashFile per file (带 sha1/md5)
	*   → 0x93db_1 prepFlashFileSet
	*   → 0x12a9_100 preflight (用 0x93e5_4 拿到的 sha1) → server 秒传命中
	*   → 0x12a9_103 commit
	*   → 0x93d1_1 finalize
	*
	* 限制：老 fileSet 必须没过期。 */
	async reshareFlashFile(fileSetId) {
		const sourceFiles = await this.ctx.qqProtocol.getFlashFileList(fileSetId);
		if (sourceFiles.length === 0) throw new Error("reshareFlashFile: 源 fileSet 无文件");
		const sourceInfo = await this.ctx.qqProtocol.getFlashFileInfo(fileSetId).catch(() => null);
		const reusable = [];
		for (const f of sourceFiles) {
			const fileUuid = f.fileUuid;
			if (!fileUuid) continue;
			const full = await this.ctx.qqProtocol.getFlashFileEntryFull(fileSetId, fileUuid).catch(() => null);
			if (!full) continue;
			if (!full.sha1Hex || !full.fileSize) continue;
			reusable.push({
				fileUuid,
				name: full.name ?? f.name ?? "",
				fileSize: full.fileSize ?? f.fileSize ?? 0,
				sha1Hex: full.sha1Hex,
				md5Hex: full.md5Hex
			});
		}
		if (reusable.length === 0) throw new Error("reshareFlashFile: 源 fileSet 没有可秒传的文件 (0x93e5_4 没返 sha1)");
		const totalSize = reusable.reduce((s, f) => s + (f.fileSize ?? 0), 0);
		if (!selfInfo.nick) await this.ctx.ntUserApi.getSelfNick(true).catch(() => {});
		const uploaderNick = selfInfo.nick || "QQ用户";
		const fset = await this.ctx.qqProtocol.createFlashFileSet({
			title: sourceInfo?.title ?? reusable[0].name ?? "",
			totalFileCount: reusable.length,
			totalFileSize: totalSize,
			uploaderUin: selfInfo.uin,
			uploaderNick,
			uploaderUid: selfInfo.uid
		});
		const newFileSetId = fset.fileSetId;
		const newFileUuids = reusable.map(() => randomUUID());
		for (let i = 0; i < reusable.length; i++) {
			const f = reusable[i];
			await this.ctx.qqProtocol.registerFlashFile(newFileSetId, {
				fileUuid: newFileUuids[i],
				name: f.name,
				fileSize: f.fileSize,
				sha1Hex: f.sha1Hex,
				md5Hex: f.md5Hex
			});
		}
		await this.ctx.qqProtocol.prepFlashFileSet(newFileSetId);
		let reqId = 0;
		for (let i = 0; i < reusable.length; i++) {
			const f = reusable[i];
			const sha1Hex = f.sha1Hex ?? "";
			const fileName = f.name ?? "";
			const pre = await this.ctx.qqProtocol.flashFileUploadPreflight({
				fileSize: f.fileSize ?? 0,
				sha1Hex,
				name: fileName,
				requestId: ++reqId,
				field103: 22
			});
			if (pre.uKey) throw new Error(`reshareFlashFile: 源文件不再在服务端缓存中（非秒传命中），无法重新分享`);
			if (!pre.token) throw new Error(`reshareFlashFile: preflight 没有返回 token (file ${fileName})`);
			await this.ctx.qqProtocol.flashFileUploadCommit({
				fileSize: f.fileSize ?? 0,
				sha1Hex,
				name: fileName,
				token: pre.token,
				time: pre.time,
				ttl: pre.ttl,
				requestId: ++reqId,
				field103: 22,
				fileSetId: newFileSetId,
				fileUuid: newFileUuids[i]
			});
		}
		await this.ctx.qqProtocol.downloadFlashFile(newFileSetId, 6).catch(() => {});
		return {
			result: 0,
			errMsg: "",
			createFlashTransferResult: {
				fileSetId: newFileSetId,
				shareLink: fset.shareLink,
				expireTime: String(fset.expireTime),
				expireLeftTime: String(fset.expireLeftTime)
			}
		};
	}
	async uploadGroupVideo(groupCode, filePath, thumbPath, duration, width, height) {
		const result = await this.ctx.qqProtocol.getGroupVideoUploadInfo(groupCode, filePath, thumbPath, duration, width, height);
		{
			const idxMain = result.ext?.msgInfoBody?.[0]?.index;
			const idxThumb = result.subExt?.msgInfoBody?.[1]?.index;
			this.ctx.logger.debug(`uploadGroupVideo main fileUuid=${idxMain?.fileUuid?.slice(0, 60)}... mainUKey=${result.ext?.uKey ? "set" : "EMPTY"}\nthumb fileUuid=${idxThumb?.fileUuid?.slice(0, 60)}... thumbUKey=${result.subExt?.uKey ? "set" : "EMPTY"}`);
		}
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			result.ext.hash.fileSha1 = await calculateSha1StreamBytes(filePath);
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1005,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		if (result.subExt.uKey) {
			const { index } = result.subExt.msgInfoBody[1];
			result.subExt.hash.fileSha1 = await calculateSha1StreamBytes(thumbPath);
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1006,
				readable: createReadStream(thumbPath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.subExt),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async uploadPrivateVideo(chatType, peerUid, filePath, thumbPath, duration, width, height) {
		const result = await this.ctx.qqProtocol.getC2CVideoUploadInfo(chatType, peerUid, filePath, thumbPath, duration, width, height);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			result.ext.hash.fileSha1 = await calculateSha1StreamBytes(filePath);
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1001,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		if (result.subExt.uKey) {
			const { index } = result.subExt.msgInfoBody[1];
			result.subExt.hash.fileSha1 = await calculateSha1StreamBytes(thumbPath);
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1002,
				readable: createReadStream(thumbPath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.subExt),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async uploadGroupFile(groupCode, filePath, fileName, parentFolderId = "/") {
		let result = await this.ctx.qqProtocol.getGroupFileUploadInfo(groupCode, filePath, fileName, parentFolderId, 102);
		if (result.retCode === -403n) result = await this.ctx.qqProtocol.getGroupFileUploadInfo(groupCode, filePath, fileName, parentFolderId, 104);
		if (!result.fileExist) {
			const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
			const ext = Media.FileUploadExt.encode({
				unknown1: 100,
				unknown2: 1,
				entry: {
					busiBuff: {
						senderUin: +selfInfo.uin,
						receiverUin: groupCode,
						groupCode
					},
					fileEntry: {
						fileSize: result.fileSize,
						md5: result.md5,
						checkKey: result.checkKey,
						fileId: result.fileId,
						uploadKey: result.fileKey
					},
					clientInfo: {
						clientType: 3,
						appId: "100",
						terminalType: 3,
						clientVer: "1.1.1",
						unknown: 4
					},
					fileNameInfo: { fileName },
					host: { hosts: [{
						url: {
							unknown: 1,
							host: result.uploadIp
						},
						port: result.uploadPort
					}] }
				}
			});
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 71,
				readable: createReadStream(filePath, { highWaterMark: 1048576 }),
				sum: result.md5,
				size: result.fileSize,
				ticket: highwaySession.sigSession,
				ext,
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			fileId: result.fileId,
			fileSize: result.fileSize,
			fileMd5: result.md5.toString("hex"),
			busId: result.busId
		};
	}
	async uploadPrivateFile(chatType, peerUid, filePath, fileName) {
		const result = await this.ctx.qqProtocol.getC2CFileUploadInfo(chatType, peerUid, filePath, fileName);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const ext = Media.FileUploadExt.encode({
			unknown1: 100,
			unknown2: 1,
			entry: {
				busiBuff: { senderUin: +selfInfo.uin },
				fileEntry: {
					fileSize: result.fileSize,
					md5: result.md5CheckSum,
					checkKey: result.sha1CheckSum,
					md510M: result.md510MCheckSum,
					sha3: result.sha3CheckSum,
					fileId: result.fileId,
					uploadKey: result.uploadKey
				},
				clientInfo: {
					clientType: 3,
					appId: "100",
					terminalType: 3,
					clientVer: "1.1.1",
					unknown: 4
				},
				fileNameInfo: { fileName },
				host: { hosts: result.rtpMediaPlatformUploadAddress.map(([ip, port]) => ({
					url: {
						unknown: 1,
						host: ip
					},
					port
				})) }
			},
			unknown200: 1
		});
		await new HighwayHttpSession({
			uin: selfInfo.uin,
			cmd: 95,
			readable: createReadStream(filePath, { highWaterMark: 1048576 }),
			sum: result.md5CheckSum,
			size: result.fileSize,
			ticket: highwaySession.sigSession,
			ext,
			server: highwaySession.highwayHostAndPorts[1]
		}).upload();
		return {
			fileId: result.fileId,
			file10MMd5: result.md510MCheckSum,
			fileSize: result.fileSize,
			crcMedia: result.crcMedia
		};
	}
	async uploadGroupImage(groupCode, filePath, width, height, summary, bizType) {
		const result = await this.ctx.qqProtocol.getGroupImageUploadInfo(groupCode, filePath, width, height, summary, bizType);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1004,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async uploadPrivateImage(chatType, peerUid, filePath, width, height, summary, bizType) {
		const result = await this.ctx.qqProtocol.getC2CImageUploadInfo(chatType, peerUid, filePath, width, height, summary, bizType);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1003,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async uploadGroupPtt(groupCode, filePath, duration) {
		const result = await this.ctx.qqProtocol.getGroupPttUploadInfo(groupCode, filePath, duration);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1008,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async uploadPrivatePtt(chatType, peerUid, filePath, duration) {
		const result = await this.ctx.qqProtocol.getC2CPttUploadInfo(chatType, peerUid, filePath, duration);
		const highwaySession = await this.ctx.qqProtocol.getHighwaySession();
		const maxBlockSize = 1048576;
		if (result.ext.uKey) {
			const { index } = result.ext.msgInfoBody[0];
			await new HighwayHttpSession({
				uin: selfInfo.uin,
				cmd: 1007,
				readable: createReadStream(filePath, { highWaterMark: maxBlockSize }),
				sum: Buffer.from(index.info.md5HexStr, "hex"),
				size: index.info.fileSize,
				ticket: highwaySession.sigSession,
				ext: Media.NTV2RichMediaHighwayExt.encode(result.ext),
				server: highwaySession.highwayHostAndPorts[1]
			}).upload();
		}
		return {
			msgInfo: result.info,
			compat: result.compat
		};
	}
	async getRKey() {
		const { result } = await this.ctx.qqProtocol.getRKey();
		return {
			privateRKey: result.rkeyItems[0].rkey,
			groupRKey: result.rkeyItems[1].rkey,
			expiredTime: result.rkeyItems[0].createTime + result.rkeyItems[0].ttlSec
		};
	}
};
//#endregion
//#region src/ntqqapi/api/friend.ts
var NTFriendApi = class extends Service {
	ctx;
	static inject = ["qqProtocol"];
	friendsCache = [];
	categoriesCache = /* @__PURE__ */ new Map();
	refreshingFriends;
	constructor(ctx) {
		super(ctx, "ntFriendApi");
		this.ctx = ctx;
		ctx.on("nt/friend-added", () => {
			if (this.friendsCache.length > 0) this.getFriends(true);
		});
		ctx.on("nt/friend-removed", () => {
			if (this.friendsCache.length > 0) this.getFriends(true);
		});
	}
	async getFriends(forceUpdate) {
		if (this.refreshingFriends) await this.refreshingFriends;
		else if (forceUpdate || this.friendsCache.length === 0) {
			const { promise, resolve, reject } = Promise.withResolvers();
			this.refreshingFriends = promise;
			const friends = [];
			const categories = /* @__PURE__ */ new Map();
			let cookie;
			try {
				while (true) {
					const res = await this.ctx.qqProtocol.fetchFriends(cookie);
					for (const cat of res.category) categories.set(cat.categoryId, cat);
					for (const friend of res.friendList) {
						const biz = friend.subBiz.get(1);
						friends.push({
							uid: friend.uid,
							uin: friend.uin,
							categoryId: friend.categoryId,
							categoryName: categories.get(friend.categoryId)?.categoryName ?? "",
							nick: biz.data.get(20002)?.toString() ?? "",
							bio: biz.data.get(102)?.toString() ?? "",
							remark: biz.data.get(103)?.toString() ?? "",
							qid: biz.data.get(27394)?.toString() ?? "",
							age: biz.numData.get(20037) ?? 0,
							gender: biz.numData.get(20009) ?? 0,
							birthdayYear: biz.data.has(20031) ? biz.data.get(20031)[0] << 8 | biz.data.get(20031)[1] : 0,
							birthdayMonth: biz.data.get(20031)?.[2] ?? 0,
							birthdayDay: biz.data.get(20031)?.[3] ?? 0,
							isSelf: friend.uin === res.selfUin
						});
					}
					cookie = res.cookie;
					if (!cookie) break;
				}
			} catch (e) {
				promise.catch(noop);
				reject(e);
				this.refreshingFriends = void 0;
				throw e;
			}
			this.friendsCache = friends;
			this.categoriesCache = categories;
			resolve();
			this.refreshingFriends = void 0;
		}
		return {
			friends: this.friendsCache,
			categories: this.categoriesCache
		};
	}
	async getFriendByUin(uin, forceUpdate) {
		let friend = (await this.getFriends(forceUpdate)).friends.find((e) => e.uin === uin);
		if (!friend) friend = (await this.getFriends(true)).friends.find((e) => e.uin === uin);
		return friend;
	}
	async getFriendByUid(uid, forceUpdate) {
		let friend = (await this.getFriends(forceUpdate)).friends.find((e) => e.uid === uid);
		if (!friend) friend = (await this.getFriends(true)).friends.find((e) => e.uid === uid);
		return friend;
	}
	async isFriend(uid) {
		return (await this.getFriends(false)).friends.some((e) => e.uid === uid);
	}
	async getFriendRecommendContactArk(uin) {
		const { ark } = await this.ctx.qqProtocol.getFriendRecommendContactArk(uin);
		return ark;
	}
	async setFriendRemark(uid, remark = "") {
		return await this.ctx.qqProtocol.setFriendRemark(uid, remark);
	}
	async deleteFriend(targetUid, block = false, bothDelete = true) {
		return await this.ctx.qqProtocol.deleteFriend(targetUid, block, bothDelete);
	}
	async setFriendCategory(uid, categoryId) {
		return await this.ctx.qqProtocol.setFriendCategory(uid, categoryId);
	}
	async getFriendRequests(limit) {
		return (await this.ctx.qqProtocol.fetchFriendRequests(selfInfo.uid, limit)).info.requests;
	}
	async getDoubtFriendRequests(limit) {
		const { info } = await this.ctx.qqProtocol.fetchFilteredFriendRequests(limit);
		return info.requests;
	}
	async approvalFriendRequest(friendUid, accept) {
		return await this.ctx.qqProtocol.setFriendRequest(friendUid, accept ? 3 : 5);
	}
	async approvalDoubtFriendRequest(requestUid) {
		return await this.ctx.qqProtocol.setFilteredFriendRequestReq(selfInfo.uid, requestUid);
	}
	async setFriendPin(friendUid, isPinned) {
		return await this.ctx.qqProtocol.setFriendPin(friendUid, isPinned);
	}
	async sendFriendNudge(friendUin, isSelf) {
		const toUin = isSelf ? +selfInfo.uin : friendUin;
		return await this.ctx.qqProtocol.sendFriendPoke(friendUin, toUin);
	}
	async getFriendsStatus() {
		return (await this.ctx.qqProtocol.getFriendsStatus(selfInfo.uid)).list;
	}
};
//#endregion
//#region src/ntqqapi/api/group.ts
var NTGroupApi = class extends Service {
	ctx;
	static inject = ["qqProtocol"];
	groupsCache = [];
	groupCache = /* @__PURE__ */ new Map();
	membersCache = /* @__PURE__ */ new Map();
	refreshingMembers = /* @__PURE__ */ new Map();
	constructor(ctx) {
		super(ctx, "ntGroupApi");
		this.ctx = ctx;
		ctx.on("nt/group-added", () => {
			if (this.groupsCache.length > 0) this.getGroups(true);
		});
		ctx.on("nt/group-removed", () => {
			if (this.groupsCache.length > 0) this.getGroups(true);
		});
		ctx.on("nt/group-member-added", (data) => {
			if (this.membersCache.has(data.groupCode)) this.getGroupMembers(data.groupCode, true);
		});
		ctx.on("nt/group-member-removed", (data) => {
			if (this.membersCache.has(data.groupCode)) this.getGroupMembers(data.groupCode, true);
		});
		ctx.on("nt/group-mute", (data) => {
			if (this.groupsCache.length > 0 && data.memberUid === selfInfo.uid) this.getGroups(true);
		});
		ctx.on("nt/group-whole-mute", () => {
			if (this.groupsCache.length > 0) this.getGroups(true);
		});
		ctx.on("nt/group-admin-changed", (data) => {
			if (this.groupsCache.length > 0 && data.targetUid === selfInfo.uid) this.getGroups(true);
			if (this.membersCache.has(data.groupCode)) this.getGroupMembers(data.groupCode, true);
		});
	}
	async getGroups(forceUpdate) {
		if (forceUpdate || this.groupsCache.length === 0) {
			const res = await this.ctx.qqProtocol.fetchGroups();
			this.groupsCache = res.groups.map((group) => ({
				groupCode: group.groupCode,
				groupName: group.info.groupName,
				ownerUid: group.info.groupOwner.uid,
				createdAt: group.info.createdTime,
				maxMemberCount: group.info.memberMax,
				memberCount: group.info.memberCount,
				description: group.info.richDescription ?? "",
				question: group.info.question ?? "",
				announcementPreview: group.info.announcement ?? "",
				remark: group.personInfo.remark ?? "",
				isPin: !!group.info.topTime,
				groupShutupExpireTime: group.info.groupShutupExpireTime ?? 0,
				personShutupExpireTime: group.personInfo.personShutupExpireTime ?? 0,
				memberRole: group.personInfo.memberRole,
				msgMask: group.personInfo.msgMask
			}));
		}
		return this.groupsCache;
	}
	async getGroup(groupCode, forceUpdate) {
		const group = (await this.getGroups(forceUpdate)).find((e) => e.groupCode === groupCode);
		if (group) return group;
		else if (forceUpdate || !this.groupCache.has(groupCode)) {
			const { info } = await this.ctx.qqProtocol.fetchGroup(groupCode);
			const group = {
				groupCode: info.groupCode,
				groupName: info.results.richGroupName ?? info.results.groupName,
				ownerUid: info.results.ownerUid,
				createdAt: info.results.groupCreateTime,
				maxMemberCount: info.results.maxMemberNum,
				memberCount: info.results.memberNum,
				description: info.results.description ?? "",
				question: info.results.question,
				announcementPreview: "",
				remark: "",
				isPin: false,
				groupShutupExpireTime: 0,
				personShutupExpireTime: info.results.shutUpMeTimestamp,
				memberRole: GroupMemberRole.Normal,
				msgMask: GroupMsgMask.AllowNotify
			};
			this.groupCache.set(group.groupCode, group);
			return group;
		}
		return this.groupCache.get(groupCode);
	}
	async getGroupMembers(groupCode, forceUpdate) {
		if (this.refreshingMembers.has(groupCode)) await this.refreshingMembers.get(groupCode);
		else if (forceUpdate || !this.membersCache.has(groupCode)) {
			const { promise, resolve, reject } = Promise.withResolvers();
			this.refreshingMembers.set(groupCode, promise);
			const members = [];
			let cookie;
			try {
				while (true) {
					const res = await this.ctx.qqProtocol.fetchGroupMembers(groupCode, cookie);
					for (const member of res.members) members.push({
						uin: member.id.uin,
						uid: member.id.uid,
						nick: member.memberName,
						cardName: member.memberCard.memberCard ?? "",
						specialTitle: member.specialTitle ?? "",
						level: member.level?.level ?? 0,
						joinedAt: member.joinTimestamp,
						lastSpokeAt: member.lastMsgTimestamp,
						shutupExpireTime: member.shutUpTimestamp ?? 0,
						role: {
							0: GroupMemberRole.Normal,
							1: GroupMemberRole.Owner,
							2: GroupMemberRole.Admin
						}[member.permission ?? 0]
					});
					cookie = res.cookie;
					if (!cookie) break;
				}
			} catch (e) {
				promise.catch(noop);
				reject(e);
				this.refreshingMembers.delete(groupCode);
				throw e;
			}
			this.membersCache.set(groupCode, members);
			resolve();
			this.refreshingMembers.delete(groupCode);
		}
		return this.membersCache.get(groupCode);
	}
	async getGroupMemberByUid(groupCode, uid, forceUpdate) {
		let members = this.membersCache.get(groupCode);
		const member = members?.find((e) => e.uid === uid);
		if (forceUpdate || !member) members = await this.getGroupMembers(groupCode, true);
		else return member;
		return members.find((e) => e.uid === uid);
	}
	async getGroupMemberByUin(groupCode, uin, forceUpdate) {
		let members = this.membersCache.get(groupCode);
		const member = members?.find((e) => e.uin === uin);
		if (forceUpdate || !member) members = await this.getGroupMembers(groupCode, true);
		else return member;
		return members.find((e) => e.uin === uin);
	}
	async getGroupNotifications(doubt, count, startSeq) {
		const res = await this.ctx.qqProtocol.fetchGroupNotifies(count, doubt, startSeq ? BigInt(startSeq) : void 0);
		return {
			nextStartSeq: Number(res.newLatestSequence),
			notifications: res.requests.map((e) => ({
				...e,
				sequence: Number(e.sequence)
			}))
		};
	}
	async setGroupRequest(doubt, groupCode, seq, type, accept, reason = "") {
		return await this.ctx.qqProtocol.handleGroupRequest(BigInt(seq), type, groupCode, accept ? 1 : 2, reason, doubt);
	}
	async quitGroup(groupCode) {
		return await this.ctx.qqProtocol.leaveGroup(groupCode);
	}
	async kickGroupMember(groupCode, kickUids, refuseForever = false, kickReason = "") {
		return await this.ctx.qqProtocol.kickGroupMember(groupCode, kickUids, refuseForever, kickReason);
	}
	/** duration 为秒数，为 0 时解除禁言 */
	async muteGroupMember(groupCode, memList) {
		return await this.ctx.qqProtocol.muteGroupMember(+groupCode, memList);
	}
	async muteGroup(groupCode, shutUp) {
		return await this.ctx.qqProtocol.muteAllGroupMembers(groupCode, shutUp);
	}
	async setGroupMemberCard(groupCode, memberUid, cardName) {
		return await this.ctx.qqProtocol.setGroupMemberCard(groupCode, memberUid, cardName);
	}
	async setGroupMemberAdmin(groupCode, memberUid, isSet) {
		return await this.ctx.qqProtocol.setGroupMemberAdmin(groupCode, memberUid, isSet);
	}
	async setGroupMemberSpecialTitle(groupCode, memberUid, specialTitle) {
		return await this.ctx.qqProtocol.setSpecialTitle(groupCode, memberUid, specialTitle);
	}
	async setGroupName(groupCode, groupName) {
		return await this.ctx.qqProtocol.setGroupName(groupCode, groupName);
	}
	async getGroupRemainAtTimes(groupCode) {
		return await this.ctx.qqProtocol.fetchGroupAtAllRemain(+selfInfo.uin, groupCode);
	}
	async addGroupEssence(groupCode, msgSeq, msgRandom) {
		return await this.ctx.qqProtocol.setGroupEssence(groupCode, msgSeq, msgRandom, true);
	}
	async removeGroupEssence(groupCode, msgSeq, msgRandom) {
		return await this.ctx.qqProtocol.setGroupEssence(groupCode, msgSeq, msgRandom, false);
	}
	async getGroupRecommendContactArk(groupCode) {
		const { ark } = await this.ctx.qqProtocol.getGroupRecommendContactArk(groupCode);
		return ark;
	}
	/**
	* 设群头像。HTTP-only 上传：PicUp.DataUp + cmd=3000 + GroupAvatarExtra（含 groupUin），
	* 字节级匹配 PMHQ 抓的 NTQQ Windows 客户端。
	*
	* 关键坑：GroupAvatarExtra.groupUin 是**内部 groupUin**，不是用户看到的 groupCode。
	* 错传 groupCode 会被服务器拒绝 "No Perm"（藏在 bytesRspExtendInfo.field4，outer errorCode 是 0）。
	*/
	async setGroupAvatar(groupCode, filePath) {
		const stat = await promises.stat(filePath);
		const md5 = await getMd5BufferFromFile(filePath);
		const session = await this.ctx.qqProtocol.getHighwaySession();
		const ext = Media.GroupAvatarExtra.encode({
			type: 101,
			groupUin: groupCodeToGroupUin(+groupCode),
			field3: { field1: 1 },
			field5: 3,
			field6: 1
		});
		const trans = {
			uin: selfInfo.uin,
			cmd: 3e3,
			readable: createReadStream(filePath, { highWaterMark: 1048576 }),
			sum: md5,
			size: stat.size,
			ticket: session.sigSession,
			ext,
			server: session.highwayHostAndPorts[1]
		};
		try {
			await new HighwayHttpSession(trans).upload();
			return {
				result: 0,
				errMsg: ""
			};
		} catch (e) {
			return {
				result: -1,
				errMsg: e.message
			};
		}
	}
	async setGroupMsgMask(groupCode, msgMask) {
		return (await this.ctx.qqProtocol.setGroupMsgMask(groupCode, selfInfo.uid, msgMask)).body;
	}
	async setGroupRemark(groupCode, groupRemark = "") {
		return await this.ctx.qqProtocol.setGroupRemark(+groupCode, groupRemark);
	}
	async getGroupFileList(groupCode, folderId, startIndex, fileCount) {
		const res = await this.ctx.qqProtocol.getGroupFileList(groupCode, folderId, startIndex, fileCount);
		return {
			...res.listResp,
			retCode: Number(res.listResp.retCode)
		};
	}
	async getGroupFileCount(groupCode) {
		return (await this.ctx.qqProtocol.getGroupFileCount(groupCode)).countResp;
	}
	async getGroupFileSpace(groupCode) {
		const res = await this.ctx.qqProtocol.getGroupFileSpace(groupCode);
		return {
			totalSpace: Number(res.spaceResp.totalSpace),
			usedSpace: Number(res.spaceResp.usedSpace)
		};
	}
	async deleteGroupFile(groupCode, fileId, busId = 102) {
		const res = await this.ctx.qqProtocol.deleteGroupFile(groupCode, fileId, busId);
		return {
			...res.delete,
			retCode: Number(res.delete.retCode)
		};
	}
	async moveGroupFile(groupCode, fileId, curFolderId, dstFolderId) {
		const res = await this.ctx.qqProtocol.moveGroupFile(groupCode, fileId, curFolderId, dstFolderId);
		return {
			...res.move,
			retCode: Number(res.move.retCode)
		};
	}
	async persistGroupFile(groupCode, fileId) {
		const res = await this.ctx.qqProtocol.transGroupFile(groupCode, fileId);
		return {
			...res,
			retCode: Number(res.retCode)
		};
	}
	async renameGroupFile(groupCode, fileId, parentFolderId, newFileName) {
		const res = await this.ctx.qqProtocol.renameGroupFile(groupCode, fileId, parentFolderId, newFileName);
		return {
			...res.rename,
			retCode: Number(res.rename.retCode)
		};
	}
	async forwardGroupFile(groupCode, dstUin, fileId, busId, toFriend) {
		const res = await this.ctx.qqProtocol.forwardGroupFile(groupCode, dstUin, fileId, busId, toFriend);
		return {
			...res.copyToRsp,
			retCode: Number(res.copyToRsp.retCode)
		};
	}
	async createGroupFolder(groupCode, folderName) {
		const res = await this.ctx.qqProtocol.createGroupFolder(groupCode, folderName, "/");
		return {
			...res.create,
			retCode: Number(res.create.retCode)
		};
	}
	async deleteGroupFolder(groupCode, folderId) {
		const res = await this.ctx.qqProtocol.deleteGroupFolder(groupCode, folderId);
		return {
			...res.delete,
			retCode: Number(res.delete.retCode)
		};
	}
	async renameGroupFolder(groupCode, folderId, newFolderName) {
		const res = await this.ctx.qqProtocol.renameGroupFolder(groupCode, folderId, newFolderName);
		return {
			...res.rename,
			retCode: Number(res.rename.retCode)
		};
	}
	async getGroupAlbumList(groupCode) {
		const res = await this.ctx.qqProtocol.fetchGroupAlbumList(groupCode);
		return {
			retCode: res.retCode,
			retMsg: res.retMsg,
			albumList: res.body?.albums ?? []
		};
	}
	async createGroupAlbum(groupCode, name, desc) {
		const res = await this.ctx.qqProtocol.createGroupAlbum(groupCode, name, desc);
		return {
			retCode: res.retCode,
			retMsg: res.retMsg,
			info: res.body?.info
		};
	}
	async deleteGroupAlbum(groupCode, albumId) {
		return await this.ctx.qqProtocol.deleteGroupAlbum(groupCode, albumId);
	}
	async getGroupAlbumMediaList(groupCode, albumId, attachInfo) {
		return await this.ctx.qqProtocol.fetchGroupAlbumMediaList(groupCode, albumId, attachInfo);
	}
	async setGroupPin(groupCode, isPinned) {
		return await this.ctx.qqProtocol.setGroupPin(groupCode, isPinned);
	}
	async sendGroupNudge(groupCode, targetUin) {
		return await this.ctx.qqProtocol.sendGroupPoke(groupCode, targetUin);
	}
	async groupClockIn(groupCode) {
		return await this.ctx.qqProtocol.groupClockIn(groupCode.toString());
	}
};
//#endregion
//#region src/ntqqapi/api/login.ts
var NTLoginApi = class extends Service {
	ctx;
	static inject = ["qqProtocol"];
	constructor(ctx) {
		super(ctx, "ntLoginApi");
		this.ctx = ctx;
	}
	async getQuickLoginList() {
		return { LocalLoginInfoList: this.ctx.qqProtocol.listQuickLoginAccounts().map((a) => ({
			uin: a.uin,
			uid: a.uid,
			nickName: a.nick,
			faceUrl: `https://q1.qlogo.cn/g?b=qq&nk=${a.uin}&s=100`,
			loginType: 0,
			isQuickLogin: true,
			isAutoLogin: false,
			isUserLogin: false
		})) };
	}
	async getLoginQrCode() {
		return await this.ctx.qqProtocol.getLoginQrCode();
	}
};
//#endregion
//#region src/ntqqapi/helper/messageBuilding.ts
var MessageBuilding = class MessageBuilding {
	ctx;
	inputElems;
	outputElems;
	chatType;
	peerUid;
	nestedForwardTrace;
	content;
	isInsideForward;
	constructor(ctx, elements, chatType, peerUid, nestedForwardTrace = /* @__PURE__ */ new Map(), isInsideForward = false) {
		this.ctx = ctx;
		this.inputElems = elements;
		this.outputElems = [];
		this.chatType = chatType;
		this.peerUid = peerUid;
		this.nestedForwardTrace = nestedForwardTrace;
		this.isInsideForward = isInsideForward;
	}
	async [ElementType.Text](data) {
		const { textElement } = data;
		if (textElement.atType === 1) {
			const attr6 = Buffer.from([
				0,
				1,
				0,
				0,
				0,
				5,
				1,
				0,
				0,
				0,
				0,
				0,
				0
			]);
			this.outputElems.push({ text: {
				str: textElement.content,
				attr6Buf: attr6
			} });
		} else if (textElement.atType === 2) {
			const attr6Buf = Buffer.alloc(20);
			attr6Buf.writeUInt16BE(1, 0);
			attr6Buf.writeUInt16BE(0, 2);
			attr6Buf.writeUInt16BE(textElement.content.length, 4);
			attr6Buf.writeUInt8(0, 6);
			attr6Buf.writeUInt32BE(textElement.atUin, 7);
			attr6Buf.writeUInt16BE(0, 11);
			this.outputElems.push({ text: {
				str: textElement.content,
				attr6Buf
			} });
		} else this.outputElems.push({ text: { str: textElement.content } });
	}
	async [ElementType.Face](data) {
		const { faceElement } = data;
		if (faceElement.faceType === 5) {
			const f = faceElement;
			const pbElem = Msg.PokeExtra.encode({ type: f.faceIndex });
			this.outputElems.push({ commonElem: {
				serviceType: 2,
				pbElem,
				businessType: f.faceIndex
			} });
		} else if (faceElement.faceType === 3) {
			const f = faceElement;
			const pbElem = Msg.LargeFaceExtra.encode({
				aniStickerPackId: f.packId ? String(f.packId) : "1",
				aniStickerId: String(f.stickerId),
				faceId: faceElement.faceIndex,
				aniStickerType: f.stickerType ?? 2,
				resultId: f.resultId ? +f.resultId : void 0
			});
			this.outputElems.push({ commonElem: {
				serviceType: 37,
				pbElem,
				businessType: f.stickerType ?? 1
			} });
		} else if (faceElement.faceType === 2) {
			const f = faceElement;
			const pbElem = Msg.QSmallFaceExtra.encode({
				faceId: f.faceIndex,
				text: f.faceText,
				compatText: f.faceText
			});
			this.outputElems.push({ commonElem: {
				serviceType: 33,
				pbElem,
				businessType: f.stickerType ?? 1
			} });
		} else this.outputElems.push({ face: { index: faceElement.faceIndex } });
	}
	async [ElementType.MarketFace](data) {
		const { marketFaceElement } = data;
		this.outputElems.push({ marketFace: {
			summary: marketFaceElement.faceName,
			itemType: 6,
			info: 1,
			faceId: Buffer.from(marketFaceElement.emojiId, "hex"),
			tabId: marketFaceElement.emojiPackageId,
			subType: 3,
			key: marketFaceElement.key,
			width: marketFaceElement.imageWidth,
			height: marketFaceElement.imageHeight
		} });
	}
	async [ElementType.Reply](data) {
		const { replyElement } = data;
		let srcMsg = replyElement.srcMsg;
		if (srcMsg) {
			const decoded = Msg.Message.decode(srcMsg);
			const { elems } = decoded.body.richText;
			const indexToExclude = [];
			for (const [index, elem] of elems.entries()) if (elem.text) {
				const textElem = elem.text;
				if (textElem.attr6Buf && textElem.attr6Buf.length > 0 && textElem.attr6Buf.length >= 11 && textElem.attr6Buf[6] !== 1) {
					if (elem.text.pbReserve) {
						const attr = Msg.TextResvAttr.decode(elem.text.pbReserve);
						if (attr.atType === 2 && attr.atMemberUin === 0) {
							indexToExclude.push(index, index + 1);
							break;
						}
					}
				}
			}
			if (indexToExclude.length > 0) {
				decoded.body.richText.elems = elems.filter((_, index) => {
					return !indexToExclude.includes(index);
				});
				srcMsg = Msg.Message.encode(decoded);
			}
		}
		this.outputElems.push({ srcMsg: {
			origSeqs: [replyElement.replyMsgClientSeq || replyElement.replyMsgSeq],
			senderUin: replyElement.senderUin,
			time: replyElement.replyMsgTime,
			attr: {
				senderUid: replyElement.senderUid,
				ntMsgSeq: replyElement.replyMsgClientSeq ? replyElement.replyMsgSeq : void 0
			},
			srcMsg
		} });
		if (this.chatType === ChatType.Group && !this.isInsideForward) {
			const attr6Buf = Buffer.alloc(20);
			attr6Buf.writeUInt16BE(1, 0);
			attr6Buf.writeUInt16BE(0, 2);
			attr6Buf.writeUInt16BE(1, 4);
			attr6Buf.writeUInt8(0, 6);
			attr6Buf.writeUInt32BE(replyElement.senderUin, 7);
			attr6Buf.writeUInt16BE(0, 11);
			const pbReserve = Msg.TextResvAttr.encode({
				atType: 2,
				atMemberUin: 0,
				atMemberUid: replyElement.senderUid
			});
			this.outputElems.push({ text: {
				str: "@",
				attr6Buf,
				pbReserve
			} }, { text: { str: " " } });
		}
	}
	async [ElementType.Pic](data) {
		const { picElement: p } = data;
		const isGroup = this.chatType === ChatType.Group;
		const result = isGroup ? await this.ctx.ntFileApi.uploadGroupImage(this.peerUid, p.sourcePath, p.picWidth, p.picHeight, p.summary, p.picSubType) : await this.ctx.ntFileApi.uploadPrivateImage(this.chatType, this.peerUid, p.sourcePath, p.picWidth, p.picHeight, p.summary, p.picSubType);
		this.outputElems.push({ commonElem: {
			serviceType: 48,
			pbElem: result.msgInfo,
			businessType: isGroup ? 20 : 10
		} });
	}
	async [ElementType.Video](data) {
		const { videoElement: v } = data;
		const isGroup = this.chatType === ChatType.Group;
		const result = isGroup ? await this.ctx.ntFileApi.uploadGroupVideo(this.peerUid, v.filePath, v.thumbPath, v.fileTime, v.thumbWidth, v.thumbHeight) : await this.ctx.ntFileApi.uploadPrivateVideo(this.chatType, this.peerUid, v.filePath, v.thumbPath, v.fileTime, v.thumbWidth, v.thumbHeight);
		this.outputElems.push({ commonElem: {
			serviceType: 48,
			pbElem: result.msgInfo,
			businessType: isGroup ? 21 : 11
		} });
	}
	async [ElementType.Ptt](data) {
		const { pttElement: p } = data;
		const isGroup = this.chatType === ChatType.Group;
		const result = isGroup ? await this.ctx.ntFileApi.uploadGroupPtt(this.peerUid, p.filePath, p.duration) : await this.ctx.ntFileApi.uploadPrivatePtt(this.chatType, this.peerUid, p.filePath, p.duration);
		this.outputElems.push({ commonElem: {
			serviceType: 48,
			pbElem: result.msgInfo,
			businessType: isGroup ? 22 : 12
		} });
	}
	async [ElementType.Ark](data) {
		const { arkElement } = data;
		this.outputElems.push({ lightApp: { data: Buffer.concat([Buffer.from([1]), deflateSync(Buffer.from(arkElement.bytesData, "utf-8"))]) } });
	}
	async [ElementType.MultiForward](data) {
		const { multiForwardMsgElement } = data;
		const messages = [];
		const preview = multiForwardMsgElement.preview ?? [];
		const needGeneratePreview = preview.length === 0;
		const isGroup = this.chatType === ChatType.Group;
		for (const node of multiForwardMsgElement.nodes) {
			if (needGeneratePreview && preview.length < 4) {
				const content = node.elements.reduce((acc, curr) => {
					let preview;
					if (curr.elementType === ElementType.Text) preview = curr.textElement.content.slice(0, 70);
					else if (curr.elementType === ElementType.Face) preview = curr.faceElement.faceText;
					else if (curr.elementType === ElementType.MarketFace) preview = curr.marketFaceElement.faceName;
					else if (curr.elementType === ElementType.Pic) preview = curr.picElement.summary || "[图片]";
					else if (curr.elementType === ElementType.Video) preview = "[视频]";
					else if (curr.elementType === ElementType.Ptt) preview = "[语音]";
					else if (curr.elementType === ElementType.Ark) preview = curr.arkElement.bytesData.match(/"prompt"\s*:\s*"([^"]*)"/)?.[1] ?? "";
					else if (curr.elementType === ElementType.MultiForward) preview = "[合并转发]";
					else if (curr.elementType === ElementType.Reply) preview = "";
					return acc + preview;
				}, "");
				preview.push(`${node.senderName}: ${content}`);
			}
			const { elems, content } = await new MessageBuilding(this.ctx, node.elements, this.chatType, this.peerUid, this.nestedForwardTrace, true).build();
			if (node.msgStyle) {
				let font = node.msgStyle.fontId === 0 ? 65536n : BigInt(node.msgStyle.fontId >> 8 | node.msgStyle.fontId << 8 & 65535) | 131072n;
				if (node.msgStyle.isCsFontEffectEnabled) font |= 1n << 24n;
				elems.push({ elemFlags2: { colorTextId: BigInt(node.msgStyle.bubbleId) } }, { generalFlags: {
					bubbleDiyTextId: node.msgStyle.bubbleDiyTextId,
					pendantId: BigInt(node.msgStyle.pendantId),
					pbReserve: Msg.MessageStyleExtra.encode({
						font,
						fontEffectId: node.msgStyle.fontEffectId
					})
				} });
			}
			messages.push(Msg.Message.encode({
				routingHead: {
					fromUin: node.senderUin,
					c2c: isGroup ? void 0 : { name: node.senderName },
					group: isGroup ? {
						groupCode: 284840486,
						groupCard: node.senderName,
						groupCardType: 2
					} : void 0
				},
				contentHead: {
					msgType: isGroup ? 82 : 9,
					random: Math.floor(Math.random() * 4294967290),
					groupMsgSeqOrC2cClientSeq: node.msgSeq,
					msgTime: node.msgTime ?? Math.trunc(Date.now() / 1e3),
					pkgNum: 1,
					pkgIndex: 0,
					divSeq: 0,
					forward: {
						field1: 0,
						field2: 0,
						field3: 0,
						field4: "",
						avatar: ""
					}
				},
				body: {
					richText: { elems },
					msgContent: content
				}
			}));
		}
		const items = [{
			fileName: "MultiMsg",
			buffer: { msg: messages }
		}];
		for (const [key, value] of this.nestedForwardTrace) items.push({
			fileName: key,
			buffer: { msg: value }
		});
		const resid = await this.ctx.ntMsgApi.uploadForwardMsgs(this.peerUid, isGroup, items);
		const id = crypto.randomUUID();
		this.nestedForwardTrace.set(id, messages);
		const prompt = multiForwardMsgElement.prompt ?? "[聊天记录]";
		const content = JSON.stringify({
			app: "com.tencent.multimsg",
			config: {
				autosize: 1,
				forward: 1,
				round: 1,
				type: "normal",
				width: 300
			},
			desc: prompt,
			extra: JSON.stringify({
				filename: id,
				tsum: 0
			}),
			meta: { detail: {
				news: preview.map((e) => ({ text: e })),
				resid,
				source: multiForwardMsgElement.title ?? isGroup ? "群聊的聊天记录" : "聊天记录",
				summary: multiForwardMsgElement.summary ?? `查看${multiForwardMsgElement.nodes.length}条转发消息`,
				uniseq: id
			} },
			prompt,
			ver: "0.0.0.5",
			view: "contact"
		});
		this.outputElems.push({ lightApp: { data: Buffer.concat([Buffer.from([1]), deflateSync(Buffer.from(content, "utf-8"))]) } });
	}
	async [ElementType.File](data) {
		const fileName = data.fileElement.fileName;
		if (this.chatType === ChatType.Group) {
			const uploaded = await this.ctx.ntFileApi.uploadGroupFile(+this.peerUid, data.fileElement.filePath, fileName);
			const extra = Msg.GroupFileExtra.encode({
				field1: 6,
				fileName,
				inner: { info: {
					busId: uploaded.busId,
					fileId: uploaded.fileId,
					fileSize: uploaded.fileSize,
					fileName,
					fileMd5: uploaded.fileMd5
				} }
			});
			const lenBuf = Buffer.alloc(2);
			lenBuf.writeUInt16BE(extra.length);
			this.outputElems.push({ transElemInfo: {
				elemType: 24,
				elemValue: Buffer.concat([
					Buffer.from([1]),
					lenBuf,
					extra
				])
			} });
		} else {
			const uploaded = await this.ctx.ntFileApi.uploadPrivateFile(this.chatType, this.peerUid, data.fileElement.filePath, fileName);
			const extra = Msg.FileExtra.encode({ file: {
				fileType: 0,
				fileUuid: uploaded.fileId,
				fileMd5: uploaded.file10MMd5,
				fileName,
				fileSize: uploaded.fileSize,
				subCmd: 1,
				dangerLevel: 0,
				expireTime: Math.floor(Date.now() / 1e3 + 604800),
				fileIdCrcMedia: uploaded.crcMedia
			} });
			this.content = extra;
		}
	}
	async build() {
		for (const element of this.inputElems) await this[element.elementType].call(this, element);
		return {
			elems: this.outputElems,
			content: this.content
		};
	}
};
//#endregion
//#region src/ntqqapi/api/msg.ts
var NTMsgApi = class extends Service {
	ctx;
	static inject = [
		"ntUserApi",
		"qqProtocol",
		"store",
		"ntFileApi"
	];
	constructor(ctx) {
		super(ctx, "ntMsgApi");
		this.ctx = ctx;
	}
	async setGroupMsgReaction(groupCode, msgSeq, emojiId, setEmoji, emojiType) {
		return await this.ctx.qqProtocol.setGroupReaction(groupCode, msgSeq, emojiId, setEmoji, emojiType);
	}
	async getMsgReactionList(peer, msgSeq, emojiId, count, cookie) {
		return await this.ctx.qqProtocol.fetchMsgEmojiLikes(+peer.peerUid, msgSeq, emojiId, count, cookie);
	}
	async recallMsg(peer, msgSeq, clientSeq, msgRandom, msgTime) {
		if (peer.chatType === ChatType.Group) await this.ctx.qqProtocol.recallGroupMessage(+peer.peerUid, msgSeq);
		else await this.ctx.qqProtocol.recallC2CMessage(peer.peerUid, clientSeq, msgRandom, msgTime, msgSeq);
	}
	/**
	* 挂一次性 listener 等 OlPush 推回我们刚发出去那条消息的回声。
	* 用 (peerUid, msgRandom) 匹配——random 是发送方在 PbSendMsg 里自己造、server 原样
	* 广播给所有人的 32-bit 值，两端唯一可靠对得上的字段。msgSeq 偶尔会差 1-N 个槽。
	*/
	waitForSelfEcho(peer, random, timeoutMs) {
		return new Promise((resolve, reject) => {
			const dispose = this.ctx.on("nt/message-sent", (data) => {
				const msg = data.message;
				if (String(msg.peerUid) !== String(peer.peerUid)) return;
				if (+msg.msgRandom !== random) return;
				clearTimeout(timer);
				dispose();
				resolve(msg);
			});
			const timer = setTimeout(() => {
				dispose();
				reject(/* @__PURE__ */ new Error("waitForSelfEcho timeout"));
			}, timeoutMs);
		});
	}
	/**
	* C2C 发完 PbSendMsg 后用 SsoGetRoamMsg 反查刚发的那条，拿真 msgSeq + msgUid。
	* 匹配条件：random 一致 + msgTime 跟 PbSendMsgResp.sendTime 同秒附近（防同 random 撞）。
	* 加重试是因为 server 入库 c2c 历史流稍滞后（~50-200ms）。
	*/
	async sendMsg(peer, msgElements, groupMsgMask) {
		let chatType = peer.chatType;
		let groupCode;
		if (peer.chatType === ChatType.Group) groupCode = +peer.peerUid;
		else if (peer.chatType === ChatType.TempC2CFromGroup) {
			const tempChatInfo = await this.ctx.store.getTempChatInfo(peer.peerUid);
			if (tempChatInfo) groupCode = tempChatInfo.groupCode;
			else chatType = ChatType.C2C;
		}
		const { elems, content } = await new MessageBuilding(this.ctx, msgElements, chatType, peer.peerUid).build();
		const random = randomBytes(4).readUInt32BE(0);
		const echoP = chatType === ChatType.Group && groupMsgMask !== GroupMsgMask.NotAllow ? this.waitForSelfEcho(peer, random, 1e4) : null;
		echoP?.catch(() => {});
		const fileElem = elems.find((e) => e.transElemInfo?.elemType === 24);
		if (fileElem) {
			const buf = fileElem.transElemInfo.elemValue.subarray(3);
			const extra = Msg.GroupFileExtra.decode(buf);
			const ret = await this.ctx.qqProtocol.feedGroupFile(groupCode, extra.inner.info.fileId, random, extra.inner.info.busId);
			if (ret.feedsInfoRsp.retCode !== 0n) throw new Error(`发送文件失败 (code=${ret.feedsInfoRsp.retCode}): ${ret.feedsInfoRsp.clientWording}`);
			return await echoP;
		}
		const ret = await this.ctx.qqProtocol.sendMessage({
			chatType,
			groupCode,
			toUid: chatType !== ChatType.Group ? peer.peerUid : void 0,
			elems,
			random,
			content
		});
		if (ret.resultCode !== 0) throw new Error(`发送消息失败 (code=${ret.resultCode}): ${ret.errMsg}`);
		if (ret.sequence === 0) throw new Error("发送消息失败 (sequence=0)");
		return (echoP ? await echoP : void 0) ?? {
			msgId: (16777216n << 32n | BigInt(ret.random)).toString(),
			msgTime: ret.timestamp,
			msgSeq: ret.sequence,
			msgRandom: ret.random,
			senderUid: selfInfo.uid,
			senderUin: +selfInfo.uin,
			peerUid: peer.peerUid,
			peerUin: chatType === ChatType.Group ? +peer.peerUid : await this.ctx.ntUserApi.getUinByUid(peer.peerUid),
			sendNickName: "",
			sendMemberName: "",
			chatType,
			elements: parseElements(elems, chatType === ChatType.Group),
			peerName: "",
			tempFromGroupCode: chatType === ChatType.TempC2CFromGroup ? groupCode : 0,
			clientSeq: ret.clientSequence,
			forwardAvatar: "",
			memberRole: GroupMemberRole.NotApplicable
		};
	}
	rawPbHex(bytes) {
		return bytes.toString("hex");
	}
	async getSingleMsg(peer, msgSeq) {
		let retcode, errorMsg, messages;
		if (peer.chatType === ChatType.Group) {
			const res = await this.ctx.qqProtocol.getGroupMessages(+peer.peerUid, msgSeq, msgSeq);
			retcode = res.retcode;
			errorMsg = res.errorMsg;
			messages = res.body.messages;
		} else {
			const res = await this.ctx.qqProtocol.getC2CMessages(peer.peerUid, msgSeq, msgSeq);
			retcode = res.retcode;
			errorMsg = res.errorMsg;
			messages = res.messages;
		}
		return {
			retcode,
			errorMsg,
			msgList: filterNullable(messages.map((e) => convertToRawMessage(Msg.Message.decode(e), this.rawPbHex(e))))
		};
	}
	/** 一次最多拉取 30 条消息 */
	async getMsgsBySeqAndCount(peer, msgSeq, cnt, queryOrder) {
		const startSeq = queryOrder ? Math.max(1, msgSeq - cnt + 1) : msgSeq;
		const endSeq = queryOrder ? msgSeq : msgSeq + cnt - 1;
		let retcode, errorMsg, messages;
		if (peer.chatType === ChatType.Group) {
			const res = await this.ctx.qqProtocol.getGroupMessages(+peer.peerUid, startSeq, endSeq);
			retcode = res.retcode;
			errorMsg = res.errorMsg;
			messages = res.body.messages;
		} else {
			const res = await this.ctx.qqProtocol.getC2CMessages(peer.peerUid, startSeq, endSeq);
			retcode = res.retcode;
			errorMsg = res.errorMsg;
			messages = res.messages;
		}
		return {
			retcode,
			errorMsg,
			msgList: filterNullable(messages.map((e) => convertToRawMessage(Msg.Message.decode(e), this.rawPbHex(e))))
		};
	}
	async getC2CMsgsByTimeAndCount(peer, msgTime, cnt, queryOrder) {
		return { msgList: filterNullable((await this.ctx.qqProtocol.getC2CRoamMessages(peer.peerUid, msgTime, cnt, queryOrder ? 1 : 2)).messages.map((e) => convertToRawMessage(Msg.Message.decode(e), this.rawPbHex(e)))) };
	}
	async setMsgRead(peer, startSeq) {
		return await this.ctx.qqProtocol.reportMessageRead(peer.chatType, peer.peerUid, startSeq);
	}
	async getCustomFaceList() {
		const resp = await this.ctx.qqProtocol.listFavEmojis();
		const ui = resp.userInfo;
		const bid = ui.bid || "qq_expression";
		const uin = selfInfo.uin;
		const emojiInfoList = ui.fileName.map((emojiId) => ({
			emojiId,
			url: `https://p.qpic.cn/${bid}/${uin}/${emojiId}/0`
		}));
		return {
			retCode: resp.retCode,
			errMsg: resp.errMsg,
			emojiInfoList
		};
	}
	async addCustomFace(emojiPath) {
		const stat = await promises.stat(emojiPath);
		const md5 = await getMd5BufferFromFile(emojiPath);
		const body = (await this.ctx.qqProtocol.addFavEmojiPrep({
			md5,
			fileSize: stat.size
		})).body;
		if (!body || body.retCode !== 0) return {
			retCode: body?.retCode ?? -1,
			errMsg: "",
			emojiId: ""
		};
		const emojiId = body.ext?.emojiId || "";
		if (!body.uKey || body.uKey.length === 0) return {
			retCode: 0,
			errMsg: "",
			emojiId
		};
		const ips = body.uploadIps;
		body.uploadPorts;
		if (ips.length === 0) return {
			retCode: -1,
			errMsg: "no upload server returned",
			emojiId
		};
		const server = [];
		for (const [index, ip] of ips.entries()) server.push(`${uint32ToIPV4Addr(ip)}:15000`);
		await new HighwayHttpSession({
			uin: selfInfo.uin,
			cmd: 9,
			readable: createReadStream(emojiPath, { highWaterMark: 1048576 }),
			sum: md5,
			size: stat.size,
			ticket: body.uKey,
			ext: Buffer.alloc(0),
			server
		}).upload();
		return {
			retCode: 0,
			errMsg: "",
			emojiId
		};
	}
	async deleteCustomFace(emojiIds) {
		return await this.ctx.qqProtocol.deleteFavEmojis(emojiIds);
	}
	async translatePtt2Text(msgId, peer, senderUin, voiceMsgElement) {
		const ptt = voiceMsgElement.pttElement;
		const result = new Promise((resolve, reject) => {
			const dispose = this.ctx.on("nt/ptt-trans-result", (input) => {
				if (input.msgId !== msgId) return;
				clearTimeout(timer);
				dispose();
				resolve(input.text);
			});
			const timer = setTimeout(() => {
				dispose();
				reject(/* @__PURE__ */ new Error("translatePtt2Text 超时（30s 未收到转写结果）"));
			}, 3e4);
		});
		if (peer.chatType === ChatType.Group) await this.ctx.qqProtocol.pttTransGroupReq({
			msgUid: BigInt(msgId),
			senderUin,
			groupUin: +peer.peerUid,
			voiceMd5Hex: ptt.md5HexStr,
			voiceFileId: ptt.fileUuid
		});
		else await this.ctx.qqProtocol.pttTransC2CReq({
			msgUid: BigInt(msgId),
			senderUin,
			receiverUin: +selfInfo.uin,
			voiceMd5Hex: ptt.md5HexStr,
			voiceFileId: ptt.fileUuid
		});
		return result;
	}
	async setPrivateInputStatus(toUid, eventType) {
		const { body } = await this.ctx.qqProtocol.setInputStatus(toUid, eventType);
		return body;
	}
	async getPins() {
		return await this.ctx.qqProtocol.fetchPins();
	}
	async sendPrivateFileMessage(opts) {
		return await this.ctx.qqProtocol.sendC2CFileMessage(opts);
	}
	async sendGroupFileMessage(groupCode, fileId, busId) {
		const random = Math.floor(Math.random() * 4294967295);
		const res = await this.ctx.qqProtocol.feedGroupFile(groupCode, fileId, random, busId);
		return {
			...res.feedsInfoRsp,
			retCode: Number(res.feedsInfoRsp.retCode),
			feedsResultList: res.feedsInfoRsp.feedsResultList.map((e) => ({
				...e,
				retCode: Number(e.retCode)
			}))
		};
	}
	async getLatestMsgSeq(peer) {
		if (peer.chatType === ChatType.Group) {
			const { info } = await this.ctx.qqProtocol.fetchGroupExtra(+peer.peerUid);
			return info.results.latestMessageSeq;
		} else {
			const { seq1, seq2 } = await this.ctx.qqProtocol.getFriendLatestSequence(peer.peerUid);
			return Math.max(seq1, seq2);
		}
	}
	async getForwardedMsgs(resId) {
		const { pbItemList } = await this.ctx.qqProtocol.getMultiMsg(resId);
		return { msgList: filterNullable((pbItemList.find((x) => x.fileName === "MultiMsg") ?? pbItemList[0]).buffer.msg.map((e) => convertToRawMessage(Msg.Message.decode(e), this.rawPbHex(e)))) };
	}
	async uploadForwardMsgs(peerUid, isGroup, items) {
		return (await this.ctx.qqProtocol.uploadForward(peerUid, isGroup, items)).result.resId;
	}
	async getRecommendFace(word) {
		return await this.ctx.qqProtocol.pullPics(word);
	}
};
//#endregion
//#region src/ntqqapi/api/user.ts
var NTUserApi = class extends Service {
	ctx;
	static inject = [
		"ntGroupApi",
		"qqProtocol",
		"store",
		"ntFriendApi"
	];
	constructor(ctx) {
		super(ctx, "ntUserApi");
		this.ctx = ctx;
	}
	async setSelfAvatar(filePath) {
		const stat = await promises.stat(filePath);
		const md5 = await getMd5BufferFromFile(filePath);
		const session = await this.ctx.qqProtocol.getHighwaySession();
		const trans = {
			uin: selfInfo.uin,
			cmd: 90,
			readable: createReadStream(filePath, { highWaterMark: 1048576 }),
			sum: md5,
			size: stat.size,
			ticket: session.sigSession,
			ext: Buffer.alloc(0),
			server: session.highwayHostAndPorts[1]
		};
		try {
			await new HighwayHttpSession(trans).upload();
			return {
				result: 0,
				errMsg: ""
			};
		} catch (e) {
			return {
				result: -1,
				errMsg: e.message
			};
		}
	}
	async getUidByUin(uin, groupCode) {
		if (uin === +selfInfo.uin && selfInfo.uid) return selfInfo.uid;
		try {
			const uid = await this.ctx.store.getUidByUin(uin);
			if (uid) return uid;
		} catch (e) {
			this.ctx.logger.error("getUidByUin via store failed", e);
		}
		if (groupCode) try {
			const member = await this.ctx.ntGroupApi.getGroupMemberByUin(+groupCode, uin, false);
			if (member) {
				this.ctx.store.addUix([{
					uid: member.uid,
					uin: member.uin
				}]).catch((e) => this.ctx.logger.warn(e));
				return member.uid;
			}
		} catch (e) {
			this.ctx.logger.error("getUidByUin via group members failed", e);
		}
		try {
			const friend = await this.ctx.ntFriendApi.getFriendByUin(uin, false);
			if (friend) {
				this.ctx.store.addUix([{
					uid: friend.uid,
					uin: friend.uin
				}]).catch((e) => this.ctx.logger.warn(e));
				return friend.uid;
			}
		} catch (e) {
			this.ctx.logger.error("getUidByUin via friends failed", e);
		}
		try {
			const groups = await this.ctx.ntGroupApi.getGroups(false);
			for (const g of groups) try {
				const member = await this.ctx.ntGroupApi.getGroupMemberByUin(g.groupCode, uin, false);
				if (member) {
					this.ctx.store.addUix([{
						uid: member.uid,
						uin: member.uin
					}]).catch((e) => this.ctx.logger.warn(e));
					return member.uid;
				}
			} catch {}
		} catch (e) {
			this.ctx.logger.error("getUidByUin via group scan failed", e);
		}
		return "";
	}
	async getUinByUid(uid) {
		if (uid === selfInfo.uid && selfInfo.uin) return +selfInfo.uin;
		try {
			const uin = await this.ctx.store.getUinByUid(uid);
			if (uin) return uin;
		} catch (e) {
			this.ctx.logger.error("getUinByUid via store failed", e);
		}
		try {
			const user = await this.getUserByUid(uid);
			if (user.uin) {
				this.ctx.store.addUix([{
					uid,
					uin: user.uin
				}]).catch((e) => this.ctx.logger.warn(e));
				return user.uin;
			}
		} catch (e) {
			this.ctx.logger.error("getUinByUid via user failed", e);
		}
		return 0;
	}
	async getUserByUin(uin) {
		const resp = await this.ctx.qqProtocol.fetchUserInfoByUin(uin);
		const numbers = resp.body.properties.numberProperties;
		const bytes = resp.body.properties.bytesProperties;
		const vipInfo = (bytes.has(107) ? Misc.UserInfoBusiness.decode(bytes.get(107)) : void 0)?.body.lists.find((e) => e.type === 1);
		return {
			uin: resp.body.uin,
			nick: bytes.get(20002)?.toString() ?? "",
			gender: numbers.get(20009) ?? 0,
			age: numbers.get(20037) ?? 0,
			qid: bytes.get(27394)?.toString() ?? "",
			level: numbers.get(105) ?? 0,
			registerTime: numbers.get(20026) ?? 0,
			bio: bytes.get(102)?.toString() ?? "",
			city: bytes.get(20020)?.toString() ?? "",
			country: bytes.get(20003)?.toString() ?? "",
			birthdayYear: bytes.has(20031) ? bytes.get(20031)[0] << 8 | bytes.get(20031)[1] : 0,
			birthdayMonth: bytes.get(20031)?.[2] ?? 0,
			birthdayDay: bytes.get(20031)?.[3] ?? 0,
			labels: bytes.has(104) ? Misc.UserInfoLabel.decode(bytes.get(104)).labels.map((e) => e.content) : [],
			school: bytes.get(20021)?.toString() ?? "",
			remark: bytes.get(103)?.toString() ?? "",
			isVip: !!vipInfo,
			isSvip: !!vipInfo?.isPro,
			isYearsVip: !!vipInfo?.isYear,
			vipLevel: vipInfo?.level ?? 0
		};
	}
	async getUserByUid(uid) {
		const resp = await this.ctx.qqProtocol.fetchUserInfoByUid(uid);
		const numbers = resp.body.properties.numberProperties;
		const bytes = resp.body.properties.bytesProperties;
		const vipInfo = (bytes.has(107) ? Misc.UserInfoBusiness.decode(bytes.get(107)) : void 0)?.body.lists.find((e) => e.type === 1);
		return {
			uin: resp.body.uin,
			nick: bytes.get(20002)?.toString() ?? "",
			gender: numbers.get(20009) ?? 0,
			age: numbers.get(20037) ?? 0,
			qid: bytes.get(27394)?.toString() ?? "",
			level: numbers.get(105) ?? 0,
			registerTime: numbers.get(20026) ?? 0,
			bio: bytes.get(102)?.toString() ?? "",
			city: bytes.get(20020)?.toString() ?? "",
			country: bytes.get(20003)?.toString() ?? "",
			birthdayYear: bytes.has(20031) ? bytes.get(20031)[0] << 8 | bytes.get(20031)[1] : 0,
			birthdayMonth: bytes.get(20031)?.[2] ?? 0,
			birthdayDay: bytes.get(20031)?.[3] ?? 0,
			labels: bytes.has(104) ? Misc.UserInfoLabel.decode(bytes.get(104)).labels.map((e) => e.content) : [],
			school: bytes.get(20021)?.toString() ?? "",
			remark: bytes.get(103)?.toString() ?? "",
			isVip: !!vipInfo,
			isSvip: !!vipInfo?.isPro,
			isYearsVip: !!vipInfo?.isYear,
			vipLevel: vipInfo?.level ?? 0
		};
	}
	async getPSkey(domains) {
		const { psKeys } = await this.ctx.qqProtocol.fetchPSkey(domains);
		return psKeys;
	}
	async getClientKey() {
		const { clientKey, expiration } = await this.ctx.qqProtocol.fetchClientKey();
		return {
			clientKey,
			expiration
		};
	}
	async getSelfNick(refresh = true) {
		if (!refresh && selfInfo.nick) return selfInfo.nick;
		let nick = "";
		if (selfInfo.uin) try {
			nick = (await this.getUserByUin(+selfInfo.uin)).nick;
		} catch (e) {
			if (!selfInfo.uid) throw e;
		}
		if (!nick && selfInfo.uid) nick = (await this.getUserByUid(selfInfo.uid)).nick;
		selfInfo.nick = nick;
		return nick;
	}
	async setSelfStatus(status, extStatus, batteryStatus) {
		return await this.ctx.qqProtocol.setOnlineStatus(status, extStatus, batteryStatus);
	}
	async sendProfileLike(uid, count = 1) {
		return await this.ctx.qqProtocol.sendFriendLike(uid, count);
	}
	async getProfileLike(uid, start, limit) {
		return await this.ctx.qqProtocol.fetchProfileLikes(uid, 0, BigInt(start), limit);
	}
	async getProfileLikeMe(uid, start, limit) {
		return await this.ctx.qqProtocol.fetchProfileLikes(uid, 1, BigInt(start), limit);
	}
	async getProfileLikeCount(uid) {
		return await this.ctx.qqProtocol.fetchProfileLikeCount(uid);
	}
	async modifySelfProfile(profile) {
		return await this.ctx.qqProtocol.modifySelfProfile({
			nick: profile.nick,
			longNick: profile.bio,
			sex: profile.gender,
			birthdayYear: profile.birthdayYear,
			birthdayMonth: profile.birthdayMonth,
			birthdayDay: profile.birthdayDay
		});
	}
};
//#endregion
//#region src/common/utils/request.ts
var HttpUtil = class HttpUtil {
	static async getCookies(url) {
		const client = url.startsWith("https") ? https : http;
		return new Promise((resolve, reject) => {
			client.get(url, (res) => {
				let cookies = {};
				const handleRedirect = (res) => {
					if (res.statusCode === 301 || res.statusCode === 302) if (res.headers.location) {
						const redirectUrl = new URL(res.headers.location, url);
						HttpUtil.getCookies(redirectUrl.href).then((redirectCookies) => {
							cookies = {
								...cookies,
								...redirectCookies
							};
							resolve(cookies);
						}).catch(reject);
					} else resolve(cookies);
					else resolve(cookies);
				};
				res.on("data", () => {});
				res.on("end", () => {
					handleRedirect(res);
				});
				if (res.headers["set-cookie"]) res.headers["set-cookie"].forEach((cookie) => {
					const parts = cookie.split(";")[0].split("=");
					const key = parts[0];
					const value = parts[1];
					if (key && value && key.length > 0 && value.length > 0) cookies[key] = value;
				});
			}).on("error", (err) => {
				reject(err);
			});
		});
	}
	static async getJson(url, method = "GET", data, headers = {}, isJsonRet = true, isArgJson = true) {
		const option = new URL(url);
		const protocol = url.startsWith("https://") ? https : http;
		const options = {
			hostname: option.hostname,
			port: option.port,
			path: option.href,
			method,
			headers
		};
		return new Promise((resolve, reject) => {
			const req = protocol.request(options, (res) => {
				let responseBody = "";
				res.on("data", (chunk) => {
					responseBody += chunk.toString();
				});
				res.on("end", () => {
					try {
						if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) if (isJsonRet) resolve(JSON.parse(responseBody));
						else resolve(responseBody);
						else reject(/* @__PURE__ */ new Error(`Unexpected status code: ${res.statusCode}`));
					} catch (parseError) {
						reject(parseError);
					}
				});
			});
			req.on("error", (error) => {
				reject(error);
			});
			if (method === "POST" || method === "PUT" || method === "PATCH") if (isArgJson) req.write(JSON.stringify(data));
			else req.write(data);
			req.end();
		});
	}
	static async getText(url, method = "GET", data, headers = {}) {
		return this.getJson(url, method, data, headers, false, false);
	}
	static async post(url, data = {}, cookies = "", headers = {}) {
		const _headers = {
			"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) QQ/9.9.23-41857 Chrome/138.0.7204.35 Electron/37.1.0 Safari/537.36 OS/win32,x64,10.0.26100,Windows 11 Pro QQAppId/537320161",
			"Cookie": cookies,
			"Content-Type": "application/json",
			"origin": url.startsWith("https") ? "https://" + new URL(url).hostname : "http://" + new URL(url).hostname,
			...headers
		};
		const response = await fetch(url, {
			method: "POST",
			headers: _headers,
			body: JSON.stringify(data)
		});
		if (!response.ok) throw new Error(`HTTP error! status: ${response.status} statusText: ${response.statusText}`);
		return response;
	}
};
//#endregion
//#region src/ntqqapi/api/webapi.ts
var NTWebApi = class extends Service {
	ctx;
	static inject = ["ntUserApi"];
	constructor(ctx) {
		super(ctx, "ntWebApi");
		this.ctx = ctx;
	}
	genBkn(key) {
		key = key || "";
		let hash = 5381;
		for (let i = 0; i < key.length; i++) {
			const code = key.charCodeAt(i);
			hash = hash + (hash << 5) + code;
		}
		return (hash & 2147483647).toString();
	}
	cookieToString(cookieObject) {
		return Object.entries(cookieObject).map(([key, value]) => `${key}=${value}`).join("; ");
	}
	async getGroupHonorTalkative(groupCode, pSkey) {
		const cookie = `p_uin=o${selfInfo.uin}; p_skey=${pSkey}; uin=o${selfInfo.uin}`;
		const bkn = this.genBkn(pSkey.substring(0, 10));
		return await (await fetch(`https://qun.qq.com/cgi-bin/qunapp/honor_talkative?gc=${groupCode}&num=3000&bkn=${bkn}`, { headers: { "Cookie": cookie } })).json();
	}
	async getGroupHonorContinuous(groupCode, type, pSkey) {
		const cookie = `p_uin=o${selfInfo.uin}; p_skey=${pSkey}; uin=o${selfInfo.uin}`;
		const bkn = this.genBkn(pSkey.substring(0, 10));
		return await (await fetch(`https://qun.qq.com/cgi-bin/qunapp/honor_continuous?gc=${groupCode}&num=3000&continuous_type=${type}&bkn=${bkn}`, { headers: { "Cookie": cookie } })).json();
	}
	async getGroupHonorEmotion(groupCode, pSkey) {
		const cookie = `p_uin=o${selfInfo.uin}; p_skey=${pSkey}; uin=o${selfInfo.uin}`;
		const bkn = this.genBkn(pSkey.substring(0, 10));
		return await (await fetch(`https://qun.qq.com/cgi-bin/qunapp/honor_emotion?gc=${groupCode}&num=3000&bkn=${bkn}`, { headers: { "Cookie": cookie } })).json();
	}
	async batchDeleteGroupMember(groupCode, memberUinList) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const bkn = this.genBkn(cookieObject.skey);
		const url = `https://qun.qq.com/cgi-bin/qun_mgr/delete_group_member?bkn=${bkn}&ts=${Date.now()}`;
		const cookieStr = this.cookieToString(cookieObject);
		const formData = new FormData();
		formData.append("gc", groupCode.toString());
		formData.append("ul", memberUinList.join("|"));
		formData.append("flag", "0");
		formData.append("bkn", bkn);
		const responseText = await (await fetch(url, {
			method: "POST",
			headers: { "Cookie": cookieStr },
			body: formData
		})).text();
		return JSON.parse(responseText);
	}
	async getExpertInfo(uin) {
		const pSkey = (await this.ctx.ntUserApi.getPSkey(["vip.qq.com"])).get("vip.qq.com");
		const bkn = this.genBkn(pSkey);
		const url = `https://cgi.vip.qq.com/card/getExpertInfo?ps_tk=${bkn}&fuin=${uin}&g_tk=${bkn}`;
		const cookie = `p_uin=o${selfInfo.uin}; p_skey=${pSkey}; uin=o${selfInfo.uin}`;
		return await (await fetch(url, { headers: {
			"User-Agent": "Reqable/2.30.1",
			"Referer": "https://cgi.vip.qq.com/",
			"Cookie": cookie
		} })).json();
	}
	async uploadGroupAlbum(groupCode, filePathList, albumID) {
		const domain = "h5.qzone.qq.com";
		const cookiesObject = await this.getCookies(domain);
		const gtk = this.genBkn(cookiesObject.skey);
		const errIndexList = [];
		const fileLen = filePathList.length.toString();
		const iBatchID = Math.floor(Date.now() / 1e3);
		for (let i = 0; i < filePathList.length; i++) {
			const filePath = filePathList[i];
			const fileBuffer = await fsPromise.readFile(filePath);
			const fileSize = fileBuffer.length;
			const fileType = await fileTypeFromBuffer(fileBuffer);
			const timestamp = Math.floor(Date.now() / 1e3);
			const isVideo = fileType?.mime.startsWith("video");
			let res;
			if (isVideo) {
				const checksum = getSha1HexFromBuffer(fileBuffer);
				const getSessionUrl = `https://${domain}/webapp/json/sliceUpload/FileBatchControl/${checksum}?g_tk=${gtk}`;
				const getSessionPostData = { "control_req": [{
					"uin": selfInfo.uin,
					"token": {
						"type": 4,
						"data": cookiesObject.p_skey,
						"appid": 5
					},
					"appid": "video_qun",
					"checksum": checksum,
					"check_type": 1,
					"file_len": fileSize,
					"env": {
						"refer": "qzone",
						"deviceInfo": "h5"
					},
					"model": 0,
					"biz_req": {
						"sPicTitle": "",
						"sPicDesc": "",
						"sAlbumName": "",
						"sAlbumID": "",
						"iAlbumTypeID": 0,
						"iBitmap": 0,
						"iUploadType": 3,
						"iUpPicType": 0,
						"iBatchID": 0,
						"sPicPath": "",
						"iPicWidth": 0,
						"iPicHight": 0,
						"iWaterType": 0,
						"iDistinctUse": 0,
						"sTitle": "",
						"sDesc": "",
						"iFlag": 0,
						"iUploadTime": timestamp,
						"iPlayTime": 0,
						"sCoverUrl": "",
						"iIsNew": 111,
						"iIsOriginalVideo": 0,
						"iIsFormatF20": 0,
						"extend_info": {
							"video_type": "3",
							"domainid": "5",
							"photo_num": "0",
							"video_num": fileLen,
							"batch_num": fileLen,
							"qun_id": groupCode.toString()
						}
					},
					"session": "",
					"asy_upload": 0,
					"cmd": "FileUploadVideo"
				}] };
				res = await HttpUtil.post(getSessionUrl, getSessionPostData, this.cookieToString(cookiesObject));
			} else {
				const checksum = getMd5HexFromBuffer(fileBuffer);
				const getSessionUrl = `https://${domain}/webapp/json/sliceUpload/FileBatchControl/${checksum}?g_tk=${gtk}`;
				const getSessionPostData = { "control_req": [{
					"uin": selfInfo.uin,
					"token": {
						"type": 4,
						"data": cookiesObject.p_skey,
						"appid": 5
					},
					"appid": "qun",
					"checksum": checksum,
					"check_type": 0,
					"file_len": fileSize,
					"env": {
						"refer": "qzone",
						"deviceInfo": "h5"
					},
					"model": 0,
					"biz_req": {
						"sPicTitle": "",
						"sPicDesc": "",
						"sAlbumName": "",
						"sAlbumID": albumID,
						"iAlbumTypeID": 0,
						"iBitmap": 0,
						"iUploadType": 0,
						"iUpPicType": 0,
						"iBatchID": iBatchID,
						"sPicPath": "",
						"iPicWidth": 0,
						"iPicHight": 0,
						"iWaterType": 0,
						"iDistinctUse": 0,
						"iNeedFeeds": 1,
						"iUploadTime": timestamp,
						"mapExt": {
							"appid": "qun",
							"userid": groupCode.toString()
						},
						"stExtendInfo": { "mapParams": {
							"photo_num": fileLen,
							"video_num": "0",
							"batch_num": fileLen
						} },
						"mutliPicInfo": {
							"iBatUploadNum": fileLen,
							"iCurUpload": i,
							"iSuccNum": 0,
							"iFailNum": 0
						}
					},
					"session": "",
					"asy_upload": 0,
					"cmd": "FileUpload"
				}] };
				res = await HttpUtil.post(getSessionUrl, getSessionPostData, this.cookieToString(cookiesObject));
			}
			const resJson = await res.json();
			if (resJson.ret !== 0) {
				this.ctx.logger.error(`获取群相册上传 session 失败: ${resJson.msg}`);
				errIndexList.push(i);
				continue;
			}
			const sliceSize = resJson.data.slice_size;
			let offset = 0;
			let seq = 1;
			const concurrency = 10;
			let sVid;
			const uploadSlice = async (slice) => {
				const cmd = slice.isVideo ? "FileUploadVideo" : "FileUpload";
				const uploadUrl = `https://${domain}/webapp/json/sliceUpload/${cmd}?seq=${slice.seq}&retry=0&offset=${slice.offset}&end=${slice.end}&total=${fileSize}&type=form&g_tk=${gtk}`;
				const formData = new FormData();
				formData.append("uin", selfInfo.uin);
				formData.append("appid", slice.isVideo ? "video_qun" : "qun");
				formData.append("data", new Blob([Uint8Array.from(slice.chunk)]));
				formData.append("session", slice.sessionId);
				formData.append("offset", slice.offset.toString());
				formData.append("checksum", "");
				formData.append("check_type", "0");
				formData.append("retry", "0");
				formData.append("seq", slice.seq.toString());
				formData.append("end", slice.end.toString());
				formData.append("cmd", cmd);
				formData.append("slice_size", slice.sliceSize);
				formData.append("biz_req.iUploadType", "0");
				const uploadResJson = await (await fetch(uploadUrl, {
					method: "POST",
					headers: { "Cookie": this.cookieToString(cookiesObject) },
					body: formData
				})).json();
				if (uploadResJson.ret !== 0) {
					if (!errIndexList.includes(i)) errIndexList.push(i);
					throw new Error(`群相册分片上传失败 (seq: ${slice.seq}): ${uploadResJson.msg}, file: ${filePath}`);
				} else if (uploadResJson.data.biz.sVid) sVid = uploadResJson.data.biz.sVid;
			};
			const slices = [];
			while (offset < fileSize) {
				const end = Math.min(offset + sliceSize, fileSize);
				const chunk = fileBuffer.subarray(offset, end);
				slices.push({
					offset,
					end,
					seq,
					chunk,
					isVideo: !!isVideo,
					sessionId: resJson.data.session,
					sliceSize: sliceSize.toString()
				});
				offset = end;
				seq++;
			}
			for (let i = 0; i < slices.length; i += concurrency) {
				const batch = slices.slice(i, i + concurrency);
				try {
					await Promise.all(batch.map((slice) => uploadSlice(slice)));
				} catch (e) {
					this.ctx.logger.error(e);
				}
			}
			if (sVid) {
				const filePath = await createThumb(this.ctx, filePathList[i]);
				const fileBuffer = await fsPromise.readFile(filePath);
				const fileSize = fileBuffer.length;
				const timestamp = Math.floor(Date.now() / 1e3);
				const checksum = getMd5HexFromBuffer(fileBuffer);
				const getSessionUrl = `https://${domain}/webapp/json/sliceUpload/FileBatchControl/${checksum}?g_tk=${gtk}`;
				const getSessionPostData = { "control_req": [{
					"uin": selfInfo.uin,
					"token": {
						"type": 4,
						"data": cookiesObject.p_skey,
						"appid": 5
					},
					"appid": "qun",
					"checksum": checksum,
					"check_type": 0,
					"file_len": fileSize,
					"env": {
						"refer": "huodong",
						"deviceInfo": "h5"
					},
					"model": 0,
					"biz_req": {
						"sPicTitle": "",
						"sPicDesc": "",
						"sAlbumName": "",
						"sAlbumID": albumID,
						"iAlbumTypeID": 0,
						"iBitmap": 0,
						"iUploadType": 2,
						"iUpPicType": 0,
						"iBatchID": iBatchID,
						"sPicPath": "",
						"iPicWidth": 0,
						"iPicHight": 0,
						"iWaterType": 0,
						"iDistinctUse": 0,
						"mutliPicInfo": {
							"iBatUploadNum": fileLen,
							"iCurUpload": i,
							"iSuccNum": 0,
							"iFailNum": 0
						},
						"iNeedFeeds": 1,
						"iUploadTime": timestamp,
						"stExtendInfo": { "mapParams": {
							"vid": sVid,
							"photo_num": "0",
							"video_num": fileLen,
							"batch_num": fileLen
						} },
						"stExternalMapExt": {
							"is_client_upload_cover": "1",
							"is_pic_video_mix_feeds": "1"
						},
						"mapExt": {
							"appid": "qun",
							"userid": groupCode.toString()
						},
						"sExif_CameraMaker": "",
						"sExif_CameraModel": "",
						"sExif_Time": "",
						"sExif_LatitudeRef": "",
						"sExif_Latitude": "",
						"sExif_LongitudeRef": "",
						"sExif_Longitude": ""
					},
					"session": "",
					"asy_upload": 0
				}] };
				const resJson = await (await HttpUtil.post(getSessionUrl, getSessionPostData, this.cookieToString(cookiesObject))).json();
				if (resJson.ret !== 0) {
					this.ctx.logger.error(`获取群相册上传 session 失败: ${resJson.msg}`);
					errIndexList.push(i);
					continue;
				}
				const sliceSize = resJson.data.slice_size;
				let offset = 0;
				let seq = 1;
				const concurrency = 10;
				const slices = [];
				while (offset < fileSize) {
					const end = Math.min(offset + sliceSize, fileSize);
					const chunk = fileBuffer.subarray(offset, end);
					slices.push({
						offset,
						end,
						seq,
						chunk,
						isVideo: false,
						sessionId: resJson.data.session,
						sliceSize: sliceSize.toString()
					});
					offset = end;
					seq++;
				}
				for (let i = 0; i < slices.length; i += concurrency) {
					const batch = slices.slice(i, i + concurrency);
					try {
						await Promise.all(batch.map((slice) => uploadSlice(slice)));
					} catch (e) {
						this.ctx.logger.error(e);
					}
				}
			}
		}
		this.ctx.logger.info("群相册上传完成");
		return {
			success_count: filePathList.length - errIndexList.length,
			fail_count: errIndexList.length,
			fail_indexes: errIndexList
		};
	}
	async publishGroupBulletin(groupCode, text, pinned, type, isShowEditCard, tipWindowType, confirmRequired, picId, imgWidth, imgHeight) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const bkn = this.genBkn(cookieObject.skey);
		const picInfo = {
			pic: picId,
			imgWidth: imgWidth?.toString(),
			imgHeight: imgHeight?.toString()
		};
		const res = await fetch(type === 20 ? "https://web.qun.qq.com/cgi-bin/announce/add_qun_instruction" : "https://web.qun.qq.com/cgi-bin/announce/add_qun_notice", {
			method: "POST",
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
				"Cookie": this.cookieToString(cookieObject)
			},
			body: new URLSearchParams({
				qid: groupCode.toString(),
				bkn,
				text,
				pinned: pinned.toString(),
				type: type.toString(),
				settings: JSON.stringify({
					is_show_edit_card: isShowEditCard,
					tip_window_type: tipWindowType,
					confirm_required: confirmRequired
				}),
				...picId ? picInfo : {}
			})
		});
		if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
		return await res.json();
	}
	/** 拉群公告列表 — web.qun.qq.com/cgi-bin/announce/list_announce */
	async getGroupBulletinList(groupCode) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const url = `https://web.qun.qq.com/cgi-bin/announce/list_announce?qid=${groupCode}&bkn=${this.genBkn(cookieObject.skey)}&ft=23&s=-1&n=20&ni=1&i=1`;
		const res = await fetch(url, {
			method: "GET",
			headers: { "Cookie": this.cookieToString(cookieObject) }
		});
		if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
		return await res.json();
	}
	/** 删群公告 — web.qun.qq.com/cgi-bin/announce/del_feed */
	async deleteGroupBulletin(groupCode, feedsId) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const bkn = this.genBkn(cookieObject.skey);
		const res = await fetch("https://web.qun.qq.com/cgi-bin/announce/del_feed", {
			method: "POST",
			headers: {
				"Content-Type": "application/x-www-form-urlencoded",
				"Cookie": this.cookieToString(cookieObject)
			},
			body: new URLSearchParams({
				qid: groupCode.toString(),
				bkn,
				fid: feedsId
			})
		});
		if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
		return await res.json();
	}
	/** 拉群精华消息 — qun.qq.com/cgi-bin/group_digest/digest_list */
	async getGroupEssenceList(groupCode, pageStart = 0, pageLimit = 20) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const url = `https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=${this.genBkn(cookieObject.skey)}&group_code=${groupCode}&page_start=${pageStart}&page_limit=${pageLimit}`;
		const res = await fetch(url, {
			method: "GET",
			headers: { "Cookie": this.cookieToString(cookieObject) }
		});
		if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
		return await res.json();
	}
	/** 上传群公告图片 — web.qun.qq.com/cgi-bin/announce/upload_img */
	async uploadGroupBulletinPic(groupCode, filePath) {
		const cookieObject = await this.getCookies("qun.qq.com");
		const bkn = this.genBkn(cookieObject.skey);
		const buf = await fsPromise.readFile(filePath);
		const ft = await fileTypeFromBuffer(buf);
		const formData = new FormData();
		formData.append("bkn", bkn);
		formData.append("qid", groupCode.toString());
		formData.append("pic_up", new Blob([new Uint8Array(buf)], { type: ft?.mime || "image/png" }), `pic.${ft?.ext || "png"}`);
		const res = await fetch("https://web.qun.qq.com/cgi-bin/announce/upload_img", {
			method: "POST",
			headers: { "Cookie": this.cookieToString(cookieObject) },
			body: formData
		});
		if (!res.ok) throw new Error(`HTTP error! Status: ${res.status}`);
		const data = await res.json();
		if (data.ec !== 0) return {
			errCode: data.ec,
			errMsg: data.em,
			picInfo: {
				id: "",
				width: 0,
				height: 0
			}
		};
		const decoded = data.id.replace(/&quot;/g, "\"");
		const info = JSON.parse(decoded);
		return {
			errCode: 0,
			errMsg: "",
			picInfo: {
				id: info.id,
				width: +info.w,
				height: +info.h
			}
		};
	}
	async getDaySignedList(groupCode) {
		const pSkey = (await this.ctx.ntUserApi.getPSkey(["qun.qq.com"])).get("qun.qq.com");
		const cookie = `p_uin=o${selfInfo.uin}; p_skey=${pSkey}; uin=o${selfInfo.uin}`;
		return await (await fetch(`https://qun.qq.com/v2/signin/trpc/GetDaySignedList?g_tk=${this.genBkn(pSkey)}`, {
			method: "POST",
			headers: {
				"Cookie": cookie,
				"Content-Type": "application/json"
			},
			body: JSON.stringify({
				dayYmd: formatYYYYMMDD(),
				offset: 0,
				limit: 100,
				uid: selfInfo.uin,
				groupId: groupCode.toString()
			})
		})).json();
	}
	async getCookies(domain) {
		const clientKeyData = await this.ctx.ntUserApi.getClientKey();
		const uin = selfInfo.uin;
		const requestUrl = "https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=" + uin + "&clientkey=" + clientKeyData.clientKey + "&u1=https%3A%2F%2F" + domain + "%2F" + uin + "%2Finfocenter&keyindex=19%27";
		return await HttpUtil.getCookies(requestUrl);
	}
};
//#endregion
//#region src/ntqqapi/api/system.ts
var NTSystemApi = class extends Service {
	ctx;
	static inject = ["qqProtocol"];
	constructor(ctx) {
		super(ctx, "ntSystemApi");
		this.ctx = ctx;
	}
	async restart() {}
	async getSettingAutoLogin() {
		return true;
	}
	async setSettingAutoLogin(_state) {}
	async getDeviceInfo() {
		return {
			devType: "Linux",
			buildVer: "3.2.28-48517"
		};
	}
};
//#endregion
//#region node_modules/get-port/index.js
var Locked = class extends Error {
	constructor(port) {
		super(`${port} is locked`);
	}
};
var lockedPorts = {
	old: /* @__PURE__ */ new Set(),
	young: /* @__PURE__ */ new Set()
};
var releaseOldLockedPortsIntervalMs = 15e3;
var reservedPorts = /* @__PURE__ */ new Set();
var timeout;
var getLocalHosts = () => {
	const interfaces = os.networkInterfaces();
	const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
	for (const _interface of Object.values(interfaces)) for (const config of _interface) results.add(config.address);
	return results;
};
var checkAvailablePort = (options) => new Promise((resolve, reject) => {
	const server = net.createServer();
	server.unref();
	server.on("error", reject);
	server.listen(options, () => {
		const { port } = server.address();
		server.close(() => {
			resolve(port);
		});
	});
});
var getAvailablePort$1 = async (options, hosts) => {
	if (options.host || options.port === 0) return checkAvailablePort(options);
	for (const host of hosts) try {
		await checkAvailablePort({
			port: options.port,
			host
		});
	} catch (error) {
		if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) throw error;
	}
	return options.port;
};
var isLockedPort = (port) => lockedPorts.old.has(port) || lockedPorts.young.has(port) || reservedPorts.has(port);
var portCheckSequence = function* (ports) {
	if (ports) yield* ports;
	yield 0;
};
async function getPorts(options) {
	let ports;
	let exclude = /* @__PURE__ */ new Set();
	if (options) {
		if (options.port) ports = typeof options.port === "number" ? [options.port] : options.port;
		if (options.exclude) {
			const excludeIterable = options.exclude;
			if (typeof excludeIterable[Symbol.iterator] !== "function") throw new TypeError("The `exclude` option must be an iterable.");
			for (const element of excludeIterable) {
				if (typeof element !== "number") throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
				if (!Number.isSafeInteger(element)) throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
			}
			exclude = new Set(excludeIterable);
		}
	}
	const { reserve, ...netOptions } = options ?? {};
	if (timeout === void 0) {
		timeout = setTimeout(() => {
			timeout = void 0;
			lockedPorts.old = lockedPorts.young;
			lockedPorts.young = /* @__PURE__ */ new Set();
		}, releaseOldLockedPortsIntervalMs);
		if (timeout.unref) timeout.unref();
	}
	const hosts = getLocalHosts();
	for (const port of portCheckSequence(ports)) try {
		if (exclude.has(port)) continue;
		let availablePort = await getAvailablePort$1({
			...netOptions,
			port
		}, hosts);
		while (isLockedPort(availablePort)) {
			if (port !== 0) throw new Locked(port);
			availablePort = await getAvailablePort$1({
				...netOptions,
				port
			}, hosts);
		}
		if (reserve) reservedPorts.add(availablePort);
		else lockedPorts.young.add(availablePort);
		return availablePort;
	} catch (error) {
		if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) throw error;
	}
	throw new Error("No available ports found");
}
//#endregion
//#region src/common/utils/port.ts
async function getAvailablePort(startPort, range = 100) {
	return await getPorts({ port: Array.from({ length: range }, (_, i) => startPort + i) });
}
//#endregion
//#region src/webui/BE/passwordHash.ts
/**
* 使用 SHA-256 对密码进行哈希
* @param password 明文密码
* @returns 哈希后的密码（十六进制字符串）
*/
function hashPassword(password) {
	return crypto$1.createHash("sha256").update(password).digest("hex");
}
var defaultConfig = {
	webui: {
		enable: true,
		host: "127.0.0.1",
		port: 3080
	},
	milky: {
		enable: false,
		reportSelfMessage: false,
		http: {
			host: "127.0.0.1",
			port: 3010,
			prefix: "",
			accessToken: ""
		},
		webhook: {
			urls: [],
			accessToken: ""
		}
	},
	satori: {
		enable: false,
		host: "127.0.0.1",
		port: 5600,
		token: ""
	},
	ob11: {
		enable: true,
		connect: []
	},
	enableLocalFile2Url: false,
	log: true,
	autoDeleteFile: false,
	autoDeleteFileSecond: 60,
	musicSignUrl: "https://ss.xingzhige.com/music_card/card",
	msgCacheExpire: 120,
	ffmpeg: ""
};
//#endregion
//#region src/common/utils/environment.ts
var import_dist = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
	(function(global, factory) {
		typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : global.JSON5 = factory();
	})(exports, (function() {
		"use strict";
		function createCommonjsModule(fn, module$2) {
			return module$2 = { exports: {} }, fn(module$2, module$2.exports), module$2.exports;
		}
		var _global = createCommonjsModule(function(module$3) {
			var global = module$3.exports = typeof window != "undefined" && window.Math == Math ? window : typeof self != "undefined" && self.Math == Math ? self : Function("return this")();
			if (typeof __g == "number") __g = global;
		});
		var _core = createCommonjsModule(function(module$4) {
			var core = module$4.exports = { version: "2.6.5" };
			if (typeof __e == "number") __e = core;
		});
		_core.version;
		var _isObject = function(it) {
			return typeof it === "object" ? it !== null : typeof it === "function";
		};
		var _anObject = function(it) {
			if (!_isObject(it)) throw TypeError(it + " is not an object!");
			return it;
		};
		var _fails = function(exec) {
			try {
				return !!exec();
			} catch (e) {
				return true;
			}
		};
		var _descriptors = !_fails(function() {
			return Object.defineProperty({}, "a", { get: function() {
				return 7;
			} }).a != 7;
		});
		var document = _global.document;
		var is = _isObject(document) && _isObject(document.createElement);
		var _domCreate = function(it) {
			return is ? document.createElement(it) : {};
		};
		var _ie8DomDefine = !_descriptors && !_fails(function() {
			return Object.defineProperty(_domCreate("div"), "a", { get: function() {
				return 7;
			} }).a != 7;
		});
		var _toPrimitive = function(it, S) {
			if (!_isObject(it)) return it;
			var fn, val;
			if (S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
			if (typeof (fn = it.valueOf) == "function" && !_isObject(val = fn.call(it))) return val;
			if (!S && typeof (fn = it.toString) == "function" && !_isObject(val = fn.call(it))) return val;
			throw TypeError("Can't convert object to primitive value");
		};
		var dP = Object.defineProperty;
		var _objectDp = { f: _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
			_anObject(O);
			P = _toPrimitive(P, true);
			_anObject(Attributes);
			if (_ie8DomDefine) try {
				return dP(O, P, Attributes);
			} catch (e) {}
			if ("get" in Attributes || "set" in Attributes) throw TypeError("Accessors not supported!");
			if ("value" in Attributes) O[P] = Attributes.value;
			return O;
		} };
		var _propertyDesc = function(bitmap, value) {
			return {
				enumerable: !(bitmap & 1),
				configurable: !(bitmap & 2),
				writable: !(bitmap & 4),
				value
			};
		};
		var _hide = _descriptors ? function(object, key, value) {
			return _objectDp.f(object, key, _propertyDesc(1, value));
		} : function(object, key, value) {
			object[key] = value;
			return object;
		};
		var hasOwnProperty = {}.hasOwnProperty;
		var _has = function(it, key) {
			return hasOwnProperty.call(it, key);
		};
		var id = 0;
		var px = Math.random();
		var _uid = function(key) {
			return "Symbol(".concat(key === void 0 ? "" : key, ")_", (++id + px).toString(36));
		};
		var _library = false;
		var _functionToString = createCommonjsModule(function(module$5) {
			var SHARED = "__core-js_shared__";
			var store = _global[SHARED] || (_global[SHARED] = {});
			(module$5.exports = function(key, value) {
				return store[key] || (store[key] = value !== void 0 ? value : {});
			})("versions", []).push({
				version: _core.version,
				mode: _library ? "pure" : "global",
				copyright: "© 2019 Denis Pushkarev (zloirock.ru)"
			});
		})("native-function-to-string", Function.toString);
		var _redefine = createCommonjsModule(function(module$6) {
			var SRC = _uid("src");
			var TO_STRING = "toString";
			var TPL = ("" + _functionToString).split(TO_STRING);
			_core.inspectSource = function(it) {
				return _functionToString.call(it);
			};
			(module$6.exports = function(O, key, val, safe) {
				var isFunction = typeof val == "function";
				if (isFunction) _has(val, "name") || _hide(val, "name", key);
				if (O[key] === val) return;
				if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? "" + O[key] : TPL.join(String(key)));
				if (O === _global) O[key] = val;
				else if (!safe) {
					delete O[key];
					_hide(O, key, val);
				} else if (O[key]) O[key] = val;
				else _hide(O, key, val);
			})(Function.prototype, TO_STRING, function toString() {
				return typeof this == "function" && this[SRC] || _functionToString.call(this);
			});
		});
		var _aFunction = function(it) {
			if (typeof it != "function") throw TypeError(it + " is not a function!");
			return it;
		};
		var _ctx = function(fn, that, length) {
			_aFunction(fn);
			if (that === void 0) return fn;
			switch (length) {
				case 1: return function(a) {
					return fn.call(that, a);
				};
				case 2: return function(a, b) {
					return fn.call(that, a, b);
				};
				case 3: return function(a, b, c) {
					return fn.call(that, a, b, c);
				};
			}
			return function() {
				return fn.apply(that, arguments);
			};
		};
		var PROTOTYPE = "prototype";
		var $export = function(type, name, source) {
			var IS_FORCED = type & $export.F;
			var IS_GLOBAL = type & $export.G;
			var IS_STATIC = type & $export.S;
			var IS_PROTO = type & $export.P;
			var IS_BIND = type & $export.B;
			var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
			var exports$1 = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
			var expProto = exports$1[PROTOTYPE] || (exports$1[PROTOTYPE] = {});
			var key, own, out, exp;
			if (IS_GLOBAL) source = name;
			for (key in source) {
				own = !IS_FORCED && target && target[key] !== void 0;
				out = (own ? target : source)[key];
				exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == "function" ? _ctx(Function.call, out) : out;
				if (target) _redefine(target, key, out, type & $export.U);
				if (exports$1[key] != out) _hide(exports$1, key, exp);
				if (IS_PROTO && expProto[key] != out) expProto[key] = out;
			}
		};
		_global.core = _core;
		$export.F = 1;
		$export.G = 2;
		$export.S = 4;
		$export.P = 8;
		$export.B = 16;
		$export.W = 32;
		$export.U = 64;
		$export.R = 128;
		var _export = $export;
		var ceil = Math.ceil;
		var floor = Math.floor;
		var _toInteger = function(it) {
			return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
		};
		var _defined = function(it) {
			if (it == void 0) throw TypeError("Can't call method on  " + it);
			return it;
		};
		var _stringAt = function(TO_STRING) {
			return function(that, pos) {
				var s = String(_defined(that));
				var i = _toInteger(pos);
				var l = s.length;
				var a, b;
				if (i < 0 || i >= l) return TO_STRING ? "" : void 0;
				a = s.charCodeAt(i);
				return a < 55296 || a > 56319 || i + 1 === l || (b = s.charCodeAt(i + 1)) < 56320 || b > 57343 ? TO_STRING ? s.charAt(i) : a : TO_STRING ? s.slice(i, i + 2) : (a - 55296 << 10) + (b - 56320) + 65536;
			};
		};
		var $at = _stringAt(false);
		_export(_export.P, "String", { codePointAt: function codePointAt(pos) {
			return $at(this, pos);
		} });
		_core.String.codePointAt;
		var max = Math.max;
		var min = Math.min;
		var _toAbsoluteIndex = function(index, length) {
			index = _toInteger(index);
			return index < 0 ? max(index + length, 0) : min(index, length);
		};
		var fromCharCode = String.fromCharCode;
		var $fromCodePoint = String.fromCodePoint;
		_export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), "String", { fromCodePoint: function fromCodePoint(x) {
			var arguments$1 = arguments;
			var res = [];
			var aLen = arguments.length;
			var i = 0;
			var code;
			while (aLen > i) {
				code = +arguments$1[i++];
				if (_toAbsoluteIndex(code, 1114111) !== code) throw RangeError(code + " is not a valid code point");
				res.push(code < 65536 ? fromCharCode(code) : fromCharCode(((code -= 65536) >> 10) + 55296, code % 1024 + 56320));
			}
			return res.join("");
		} });
		_core.String.fromCodePoint;
		var unicode = {
			Space_Separator: /[\u1680\u2000-\u200A\u202F\u205F\u3000]/,
			ID_Start: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,
			ID_Continue: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
		};
		var util = {
			isSpaceSeparator: function isSpaceSeparator(c) {
				return typeof c === "string" && unicode.Space_Separator.test(c);
			},
			isIdStartChar: function isIdStartChar(c) {
				return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "$" || c === "_" || unicode.ID_Start.test(c));
			},
			isIdContinueChar: function isIdContinueChar(c) {
				return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "$" || c === "_" || c === "‌" || c === "‍" || unicode.ID_Continue.test(c));
			},
			isDigit: function isDigit(c) {
				return typeof c === "string" && /[0-9]/.test(c);
			},
			isHexDigit: function isHexDigit(c) {
				return typeof c === "string" && /[0-9A-Fa-f]/.test(c);
			}
		};
		var source;
		var parseState;
		var stack;
		var pos;
		var line;
		var column;
		var token;
		var key;
		var root;
		var parse = function parse(text, reviver) {
			source = String(text);
			parseState = "start";
			stack = [];
			pos = 0;
			line = 1;
			column = 0;
			token = void 0;
			key = void 0;
			root = void 0;
			do {
				token = lex();
				parseStates[parseState]();
			} while (token.type !== "eof");
			if (typeof reviver === "function") return internalize({ "": root }, "", reviver);
			return root;
		};
		function internalize(holder, name, reviver) {
			var value = holder[name];
			if (value != null && typeof value === "object") if (Array.isArray(value)) for (var i = 0; i < value.length; i++) {
				var key = String(i);
				var replacement = internalize(value, key, reviver);
				if (replacement === void 0) delete value[key];
				else Object.defineProperty(value, key, {
					value: replacement,
					writable: true,
					enumerable: true,
					configurable: true
				});
			}
			else for (var key$1 in value) {
				var replacement$1 = internalize(value, key$1, reviver);
				if (replacement$1 === void 0) delete value[key$1];
				else Object.defineProperty(value, key$1, {
					value: replacement$1,
					writable: true,
					enumerable: true,
					configurable: true
				});
			}
			return reviver.call(holder, name, value);
		}
		var lexState;
		var buffer;
		var doubleQuote;
		var sign;
		var c;
		function lex() {
			lexState = "default";
			buffer = "";
			doubleQuote = false;
			sign = 1;
			for (;;) {
				c = peek();
				var token = lexStates[lexState]();
				if (token) return token;
			}
		}
		function peek() {
			if (source[pos]) return String.fromCodePoint(source.codePointAt(pos));
		}
		function read() {
			var c = peek();
			if (c === "\n") {
				line++;
				column = 0;
			} else if (c) column += c.length;
			else column++;
			if (c) pos += c.length;
			return c;
		}
		var lexStates = {
			default: function default$1() {
				switch (c) {
					case "	":
					case "\v":
					case "\f":
					case " ":
					case "\xA0":
					case "﻿":
					case "\n":
					case "\r":
					case "\u2028":
					case "\u2029":
						read();
						return;
					case "/":
						read();
						lexState = "comment";
						return;
					case void 0:
						read();
						return newToken("eof");
				}
				if (util.isSpaceSeparator(c)) {
					read();
					return;
				}
				return lexStates[parseState]();
			},
			comment: function comment() {
				switch (c) {
					case "*":
						read();
						lexState = "multiLineComment";
						return;
					case "/":
						read();
						lexState = "singleLineComment";
						return;
				}
				throw invalidChar(read());
			},
			multiLineComment: function multiLineComment() {
				switch (c) {
					case "*":
						read();
						lexState = "multiLineCommentAsterisk";
						return;
					case void 0: throw invalidChar(read());
				}
				read();
			},
			multiLineCommentAsterisk: function multiLineCommentAsterisk() {
				switch (c) {
					case "*":
						read();
						return;
					case "/":
						read();
						lexState = "default";
						return;
					case void 0: throw invalidChar(read());
				}
				read();
				lexState = "multiLineComment";
			},
			singleLineComment: function singleLineComment() {
				switch (c) {
					case "\n":
					case "\r":
					case "\u2028":
					case "\u2029":
						read();
						lexState = "default";
						return;
					case void 0:
						read();
						return newToken("eof");
				}
				read();
			},
			value: function value() {
				switch (c) {
					case "{":
					case "[": return newToken("punctuator", read());
					case "n":
						read();
						literal("ull");
						return newToken("null", null);
					case "t":
						read();
						literal("rue");
						return newToken("boolean", true);
					case "f":
						read();
						literal("alse");
						return newToken("boolean", false);
					case "-":
					case "+":
						if (read() === "-") sign = -1;
						lexState = "sign";
						return;
					case ".":
						buffer = read();
						lexState = "decimalPointLeading";
						return;
					case "0":
						buffer = read();
						lexState = "zero";
						return;
					case "1":
					case "2":
					case "3":
					case "4":
					case "5":
					case "6":
					case "7":
					case "8":
					case "9":
						buffer = read();
						lexState = "decimalInteger";
						return;
					case "I":
						read();
						literal("nfinity");
						return newToken("numeric", Infinity);
					case "N":
						read();
						literal("aN");
						return newToken("numeric", NaN);
					case "\"":
					case "'":
						doubleQuote = read() === "\"";
						buffer = "";
						lexState = "string";
						return;
				}
				throw invalidChar(read());
			},
			identifierNameStartEscape: function identifierNameStartEscape() {
				if (c !== "u") throw invalidChar(read());
				read();
				var u = unicodeEscape();
				switch (u) {
					case "$":
					case "_": break;
					default: if (!util.isIdStartChar(u)) throw invalidIdentifier();
				}
				buffer += u;
				lexState = "identifierName";
			},
			identifierName: function identifierName() {
				switch (c) {
					case "$":
					case "_":
					case "‌":
					case "‍":
						buffer += read();
						return;
					case "\\":
						read();
						lexState = "identifierNameEscape";
						return;
				}
				if (util.isIdContinueChar(c)) {
					buffer += read();
					return;
				}
				return newToken("identifier", buffer);
			},
			identifierNameEscape: function identifierNameEscape() {
				if (c !== "u") throw invalidChar(read());
				read();
				var u = unicodeEscape();
				switch (u) {
					case "$":
					case "_":
					case "‌":
					case "‍": break;
					default: if (!util.isIdContinueChar(u)) throw invalidIdentifier();
				}
				buffer += u;
				lexState = "identifierName";
			},
			sign: function sign$1() {
				switch (c) {
					case ".":
						buffer = read();
						lexState = "decimalPointLeading";
						return;
					case "0":
						buffer = read();
						lexState = "zero";
						return;
					case "1":
					case "2":
					case "3":
					case "4":
					case "5":
					case "6":
					case "7":
					case "8":
					case "9":
						buffer = read();
						lexState = "decimalInteger";
						return;
					case "I":
						read();
						literal("nfinity");
						return newToken("numeric", sign * Infinity);
					case "N":
						read();
						literal("aN");
						return newToken("numeric", NaN);
				}
				throw invalidChar(read());
			},
			zero: function zero() {
				switch (c) {
					case ".":
						buffer += read();
						lexState = "decimalPoint";
						return;
					case "e":
					case "E":
						buffer += read();
						lexState = "decimalExponent";
						return;
					case "x":
					case "X":
						buffer += read();
						lexState = "hexadecimal";
						return;
				}
				return newToken("numeric", sign * 0);
			},
			decimalInteger: function decimalInteger() {
				switch (c) {
					case ".":
						buffer += read();
						lexState = "decimalPoint";
						return;
					case "e":
					case "E":
						buffer += read();
						lexState = "decimalExponent";
						return;
				}
				if (util.isDigit(c)) {
					buffer += read();
					return;
				}
				return newToken("numeric", sign * Number(buffer));
			},
			decimalPointLeading: function decimalPointLeading() {
				if (util.isDigit(c)) {
					buffer += read();
					lexState = "decimalFraction";
					return;
				}
				throw invalidChar(read());
			},
			decimalPoint: function decimalPoint() {
				switch (c) {
					case "e":
					case "E":
						buffer += read();
						lexState = "decimalExponent";
						return;
				}
				if (util.isDigit(c)) {
					buffer += read();
					lexState = "decimalFraction";
					return;
				}
				return newToken("numeric", sign * Number(buffer));
			},
			decimalFraction: function decimalFraction() {
				switch (c) {
					case "e":
					case "E":
						buffer += read();
						lexState = "decimalExponent";
						return;
				}
				if (util.isDigit(c)) {
					buffer += read();
					return;
				}
				return newToken("numeric", sign * Number(buffer));
			},
			decimalExponent: function decimalExponent() {
				switch (c) {
					case "+":
					case "-":
						buffer += read();
						lexState = "decimalExponentSign";
						return;
				}
				if (util.isDigit(c)) {
					buffer += read();
					lexState = "decimalExponentInteger";
					return;
				}
				throw invalidChar(read());
			},
			decimalExponentSign: function decimalExponentSign() {
				if (util.isDigit(c)) {
					buffer += read();
					lexState = "decimalExponentInteger";
					return;
				}
				throw invalidChar(read());
			},
			decimalExponentInteger: function decimalExponentInteger() {
				if (util.isDigit(c)) {
					buffer += read();
					return;
				}
				return newToken("numeric", sign * Number(buffer));
			},
			hexadecimal: function hexadecimal() {
				if (util.isHexDigit(c)) {
					buffer += read();
					lexState = "hexadecimalInteger";
					return;
				}
				throw invalidChar(read());
			},
			hexadecimalInteger: function hexadecimalInteger() {
				if (util.isHexDigit(c)) {
					buffer += read();
					return;
				}
				return newToken("numeric", sign * Number(buffer));
			},
			string: function string() {
				switch (c) {
					case "\\":
						read();
						buffer += escape();
						return;
					case "\"":
						if (doubleQuote) {
							read();
							return newToken("string", buffer);
						}
						buffer += read();
						return;
					case "'":
						if (!doubleQuote) {
							read();
							return newToken("string", buffer);
						}
						buffer += read();
						return;
					case "\n":
					case "\r": throw invalidChar(read());
					case "\u2028":
					case "\u2029":
						separatorChar(c);
						break;
					case void 0: throw invalidChar(read());
				}
				buffer += read();
			},
			start: function start() {
				switch (c) {
					case "{":
					case "[": return newToken("punctuator", read());
				}
				lexState = "value";
			},
			beforePropertyName: function beforePropertyName() {
				switch (c) {
					case "$":
					case "_":
						buffer = read();
						lexState = "identifierName";
						return;
					case "\\":
						read();
						lexState = "identifierNameStartEscape";
						return;
					case "}": return newToken("punctuator", read());
					case "\"":
					case "'":
						doubleQuote = read() === "\"";
						lexState = "string";
						return;
				}
				if (util.isIdStartChar(c)) {
					buffer += read();
					lexState = "identifierName";
					return;
				}
				throw invalidChar(read());
			},
			afterPropertyName: function afterPropertyName() {
				if (c === ":") return newToken("punctuator", read());
				throw invalidChar(read());
			},
			beforePropertyValue: function beforePropertyValue() {
				lexState = "value";
			},
			afterPropertyValue: function afterPropertyValue() {
				switch (c) {
					case ",":
					case "}": return newToken("punctuator", read());
				}
				throw invalidChar(read());
			},
			beforeArrayValue: function beforeArrayValue() {
				if (c === "]") return newToken("punctuator", read());
				lexState = "value";
			},
			afterArrayValue: function afterArrayValue() {
				switch (c) {
					case ",":
					case "]": return newToken("punctuator", read());
				}
				throw invalidChar(read());
			},
			end: function end() {
				throw invalidChar(read());
			}
		};
		function newToken(type, value) {
			return {
				type,
				value,
				line,
				column
			};
		}
		function literal(s) {
			for (var i = 0, list = s; i < list.length; i += 1) {
				var c = list[i];
				if (peek() !== c) throw invalidChar(read());
				read();
			}
		}
		function escape() {
			switch (peek()) {
				case "b":
					read();
					return "\b";
				case "f":
					read();
					return "\f";
				case "n":
					read();
					return "\n";
				case "r":
					read();
					return "\r";
				case "t":
					read();
					return "	";
				case "v":
					read();
					return "\v";
				case "0":
					read();
					if (util.isDigit(peek())) throw invalidChar(read());
					return "\0";
				case "x":
					read();
					return hexEscape();
				case "u":
					read();
					return unicodeEscape();
				case "\n":
				case "\u2028":
				case "\u2029":
					read();
					return "";
				case "\r":
					read();
					if (peek() === "\n") read();
					return "";
				case "1":
				case "2":
				case "3":
				case "4":
				case "5":
				case "6":
				case "7":
				case "8":
				case "9": throw invalidChar(read());
				case void 0: throw invalidChar(read());
			}
			return read();
		}
		function hexEscape() {
			var buffer = "";
			var c = peek();
			if (!util.isHexDigit(c)) throw invalidChar(read());
			buffer += read();
			c = peek();
			if (!util.isHexDigit(c)) throw invalidChar(read());
			buffer += read();
			return String.fromCodePoint(parseInt(buffer, 16));
		}
		function unicodeEscape() {
			var buffer = "";
			var count = 4;
			while (count-- > 0) {
				var c = peek();
				if (!util.isHexDigit(c)) throw invalidChar(read());
				buffer += read();
			}
			return String.fromCodePoint(parseInt(buffer, 16));
		}
		var parseStates = {
			start: function start() {
				if (token.type === "eof") throw invalidEOF();
				push();
			},
			beforePropertyName: function beforePropertyName() {
				switch (token.type) {
					case "identifier":
					case "string":
						key = token.value;
						parseState = "afterPropertyName";
						return;
					case "punctuator":
						pop();
						return;
					case "eof": throw invalidEOF();
				}
			},
			afterPropertyName: function afterPropertyName() {
				if (token.type === "eof") throw invalidEOF();
				parseState = "beforePropertyValue";
			},
			beforePropertyValue: function beforePropertyValue() {
				if (token.type === "eof") throw invalidEOF();
				push();
			},
			beforeArrayValue: function beforeArrayValue() {
				if (token.type === "eof") throw invalidEOF();
				if (token.type === "punctuator" && token.value === "]") {
					pop();
					return;
				}
				push();
			},
			afterPropertyValue: function afterPropertyValue() {
				if (token.type === "eof") throw invalidEOF();
				switch (token.value) {
					case ",":
						parseState = "beforePropertyName";
						return;
					case "}": pop();
				}
			},
			afterArrayValue: function afterArrayValue() {
				if (token.type === "eof") throw invalidEOF();
				switch (token.value) {
					case ",":
						parseState = "beforeArrayValue";
						return;
					case "]": pop();
				}
			},
			end: function end() {}
		};
		function push() {
			var value;
			switch (token.type) {
				case "punctuator":
					switch (token.value) {
						case "{":
							value = {};
							break;
						case "[": value = [];
					}
					break;
				case "null":
				case "boolean":
				case "numeric":
				case "string": value = token.value;
			}
			if (root === void 0) root = value;
			else {
				var parent = stack[stack.length - 1];
				if (Array.isArray(parent)) parent.push(value);
				else Object.defineProperty(parent, key, {
					value,
					writable: true,
					enumerable: true,
					configurable: true
				});
			}
			if (value !== null && typeof value === "object") {
				stack.push(value);
				if (Array.isArray(value)) parseState = "beforeArrayValue";
				else parseState = "beforePropertyName";
			} else {
				var current = stack[stack.length - 1];
				if (current == null) parseState = "end";
				else if (Array.isArray(current)) parseState = "afterArrayValue";
				else parseState = "afterPropertyValue";
			}
		}
		function pop() {
			stack.pop();
			var current = stack[stack.length - 1];
			if (current == null) parseState = "end";
			else if (Array.isArray(current)) parseState = "afterArrayValue";
			else parseState = "afterPropertyValue";
		}
		function invalidChar(c) {
			if (c === void 0) return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
			return syntaxError("JSON5: invalid character '" + formatChar(c) + "' at " + line + ":" + column);
		}
		function invalidEOF() {
			return syntaxError("JSON5: invalid end of input at " + line + ":" + column);
		}
		function invalidIdentifier() {
			column -= 5;
			return syntaxError("JSON5: invalid identifier character at " + line + ":" + column);
		}
		function separatorChar(c) {
			console.warn("JSON5: '" + formatChar(c) + "' in strings is not valid ECMAScript; consider escaping");
		}
		function formatChar(c) {
			var replacements = {
				"'": "\\'",
				"\"": "\\\"",
				"\\": "\\\\",
				"\b": "\\b",
				"\f": "\\f",
				"\n": "\\n",
				"\r": "\\r",
				"	": "\\t",
				"\v": "\\v",
				"\0": "\\0",
				"\u2028": "\\u2028",
				"\u2029": "\\u2029"
			};
			if (replacements[c]) return replacements[c];
			if (c < " ") {
				var hexString = c.charCodeAt(0).toString(16);
				return "\\x" + ("00" + hexString).substring(hexString.length);
			}
			return c;
		}
		function syntaxError(message) {
			var err = new SyntaxError(message);
			err.lineNumber = line;
			err.columnNumber = column;
			return err;
		}
		return {
			parse,
			stringify: function stringify(value, replacer, space) {
				var stack = [];
				var indent = "";
				var propertyList;
				var replacerFunc;
				var gap = "";
				var quote;
				if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) {
					space = replacer.space;
					quote = replacer.quote;
					replacer = replacer.replacer;
				}
				if (typeof replacer === "function") replacerFunc = replacer;
				else if (Array.isArray(replacer)) {
					propertyList = [];
					for (var i = 0, list = replacer; i < list.length; i += 1) {
						var v = list[i];
						var item = void 0;
						if (typeof v === "string") item = v;
						else if (typeof v === "number" || v instanceof String || v instanceof Number) item = String(v);
						if (item !== void 0 && propertyList.indexOf(item) < 0) propertyList.push(item);
					}
				}
				if (space instanceof Number) space = Number(space);
				else if (space instanceof String) space = String(space);
				if (typeof space === "number") {
					if (space > 0) {
						space = Math.min(10, Math.floor(space));
						gap = "          ".substr(0, space);
					}
				} else if (typeof space === "string") gap = space.substr(0, 10);
				return serializeProperty("", { "": value });
				function serializeProperty(key, holder) {
					var value = holder[key];
					if (value != null) {
						if (typeof value.toJSON5 === "function") value = value.toJSON5(key);
						else if (typeof value.toJSON === "function") value = value.toJSON(key);
					}
					if (replacerFunc) value = replacerFunc.call(holder, key, value);
					if (value instanceof Number) value = Number(value);
					else if (value instanceof String) value = String(value);
					else if (value instanceof Boolean) value = value.valueOf();
					switch (value) {
						case null: return "null";
						case true: return "true";
						case false: return "false";
					}
					if (typeof value === "string") return quoteString(value, false);
					if (typeof value === "number") return String(value);
					if (typeof value === "object") return Array.isArray(value) ? serializeArray(value) : serializeObject(value);
				}
				function quoteString(value) {
					var quotes = {
						"'": .1,
						"\"": .2
					};
					var replacements = {
						"'": "\\'",
						"\"": "\\\"",
						"\\": "\\\\",
						"\b": "\\b",
						"\f": "\\f",
						"\n": "\\n",
						"\r": "\\r",
						"	": "\\t",
						"\v": "\\v",
						"\0": "\\0",
						"\u2028": "\\u2028",
						"\u2029": "\\u2029"
					};
					var product = "";
					for (var i = 0; i < value.length; i++) {
						var c = value[i];
						switch (c) {
							case "'":
							case "\"":
								quotes[c]++;
								product += c;
								continue;
							case "\0": if (util.isDigit(value[i + 1])) {
								product += "\\x00";
								continue;
							}
						}
						if (replacements[c]) {
							product += replacements[c];
							continue;
						}
						if (c < " ") {
							var hexString = c.charCodeAt(0).toString(16);
							product += "\\x" + ("00" + hexString).substring(hexString.length);
							continue;
						}
						product += c;
					}
					var quoteChar = quote || Object.keys(quotes).reduce(function(a, b) {
						return quotes[a] < quotes[b] ? a : b;
					});
					product = product.replace(new RegExp(quoteChar, "g"), replacements[quoteChar]);
					return quoteChar + product + quoteChar;
				}
				function serializeObject(value) {
					if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
					stack.push(value);
					var stepback = indent;
					indent = indent + gap;
					var keys = propertyList || Object.keys(value);
					var partial = [];
					for (var i = 0, list = keys; i < list.length; i += 1) {
						var key = list[i];
						var propertyString = serializeProperty(key, value);
						if (propertyString !== void 0) {
							var member = serializeKey(key) + ":";
							if (gap !== "") member += " ";
							member += propertyString;
							partial.push(member);
						}
					}
					var final;
					if (partial.length === 0) final = "{}";
					else {
						var properties;
						if (gap === "") {
							properties = partial.join(",");
							final = "{" + properties + "}";
						} else {
							var separator = ",\n" + indent;
							properties = partial.join(separator);
							final = "{\n" + indent + properties + ",\n" + stepback + "}";
						}
					}
					stack.pop();
					indent = stepback;
					return final;
				}
				function serializeKey(key) {
					if (key.length === 0) return quoteString(key, true);
					var firstChar = String.fromCodePoint(key.codePointAt(0));
					if (!util.isIdStartChar(firstChar)) return quoteString(key, true);
					for (var i = firstChar.length; i < key.length; i++) if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) return quoteString(key, true);
					return key;
				}
				function serializeArray(value) {
					if (stack.indexOf(value) >= 0) throw TypeError("Converting circular structure to JSON5");
					stack.push(value);
					var stepback = indent;
					indent = indent + gap;
					var partial = [];
					for (var i = 0; i < value.length; i++) {
						var propertyString = serializeProperty(String(i), value);
						partial.push(propertyString !== void 0 ? propertyString : "null");
					}
					var final;
					if (partial.length === 0) final = "[]";
					else if (gap === "") final = "[" + partial.join(",") + "]";
					else {
						var separator = ",\n" + indent;
						var properties$1 = partial.join(separator);
						final = "[\n" + indent + properties$1 + ",\n" + stepback + "]";
					}
					stack.pop();
					indent = stepback;
					return final;
				}
			}
		};
	}));
})))(), 1);
function isDockerEnvironment() {
	try {
		return existsSync$1("/.dockerenv");
	} catch {
		return false;
	}
}
/** PMHQ 模式必须传 --pmhq-port (CLI/Desktop/docker 启动脚本都会带), 以此区分直连模式 */
function isPmhqMode() {
	return process.argv.some((arg) => arg.startsWith("--pmhq-port="));
}
/**
* 从 process.argv 里解析指定 uin. 支持 4 种写法:
*   -q <uin> / -q=<uin> / --qq <uin> / --qq=<uin>
* 用于多账号场景: 指定一个 uin 后会读写对应的 qq-session-<uin>.json / config_<uin>.json。
* 纯 argv 解析, 无依赖 (config service 也要用, 不能牵扯 native-sign 依赖链)。
*/
function getSpecifiedUin(argv = process.argv) {
	for (let i = 0; i < argv.length; i++) {
		const a = argv[i];
		if ((a === "-q" || a === "--qq") && i + 1 < argv.length) return argv[i + 1];
		if (a.startsWith("-q=")) return a.slice(3);
		if (a.startsWith("--qq=")) return a.slice(5);
	}
}
//#endregion
//#region src/main/config/index.ts
var Config = class extends Service {
	configPath;
	config = null;
	watching = false;
	skipNextWatch = false;
	defaultConfigPath = path.join(import.meta.dirname, "default_config.json");
	logger;
	WATCH_DEBOUNCE_MS = 2e3;
	/** 保存 fs.watchFile 的回调引用，用于 unwatchFile 清理 */
	watchFileListener;
	constructor(ctx) {
		super(ctx, "config");
		this.logger = ctx.logger("config");
	}
	async [Service.init]() {
		return () => {
			if (this.configPath && this.watchFileListener) {
				fs.unwatchFile(this.configPath, this.watchFileListener);
				this.watchFileListener = void 0;
			}
		};
	}
	listenChange(cb) {
		this.logger.info("配置文件位于", this.configPath);
		this.config = this.get();
		if (this.configPath) {
			let lastReloadTime = 0;
			this.watchFileListener = () => {
				if (!this.watching) return;
				if (this.skipNextWatch) {
					this.skipNextWatch = false;
					return;
				}
				const now = Date.now();
				if (now - lastReloadTime < this.WATCH_DEBOUNCE_MS) return;
				lastReloadTime = now;
				this.logger.info("配置重載");
				cb(this.reloadConfig());
			};
			fs.watchFile(this.configPath, {
				persistent: false,
				interval: 1e3
			}, this.watchFileListener);
			setTimeout(() => this.watching = true, 1500);
		}
	}
	get(cache = true) {
		if (this.config && cache) return this.config;
		let uin = selfInfo.uin;
		if (!uin) {
			const argUin = getSpecifiedUin();
			if (argUin && fs.existsSync(path.join(DATA_DIR, `config_${argUin}.json`))) uin = argUin;
		}
		this.configPath = uin ? path.join(DATA_DIR, `config_${uin}.json`) : void 0;
		return this.reloadConfig();
	}
	getDefaultConfig() {
		const _defaultConfig = { ...defaultConfig };
		const defaultConfigFromFile = fs.readFileSync(this.defaultConfigPath, "utf-8");
		try {
			const parsedDefaultConfig = import_dist.default.parse(defaultConfigFromFile);
			Object.assign(_defaultConfig, parsedDefaultConfig);
		} catch (e) {
			this.logger.error("解析 default_config.json 错误", e);
		}
		return _defaultConfig;
	}
	reloadConfig() {
		if (!this.configPath) return this.getDefaultConfig();
		if (!fs.existsSync(this.configPath)) {
			this.config = this.getDefaultConfig();
			this.set(this.config);
			return this.config;
		} else {
			const data = fs.readFileSync(this.configPath, "utf-8");
			let jsonData = defaultConfig;
			try {
				jsonData = import_dist.default.parse(data);
				this.logger.info("配置加载成功");
				jsonData = this.migrateConfig(jsonData);
				mergeNewProperties(defaultConfig, jsonData);
				jsonData.webui = this.migrateWebUIToken(jsonData.webui);
				jsonData = this.cleanupConfig(defaultConfig, jsonData);
				if (JSON.stringify(jsonData, null, 2) !== data) this.set(jsonData);
				this.config = jsonData;
				return this.config;
			} catch (e) {
				this.logger.error(`${this.configPath} json 内容不合格`, e);
				this.config = this.getDefaultConfig();
				return this.config;
			}
		}
	}
	set(config) {
		this.config = config;
		this.writeConfig(config);
	}
	writeConfig(config) {
		if (!this.configPath) return;
		this.skipNextWatch = true;
		fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), "utf-8");
	}
	/**
	* 递归清理配置对象，以 defaultConfig 为基准，删除 oldConfig 中不存在于 defaultConfig 的 key
	*/
	cleanupConfig(defaultConfig, oldConfig) {
		if (typeof defaultConfig !== "object" || defaultConfig === null || Array.isArray(defaultConfig)) return oldConfig;
		if (typeof oldConfig !== "object" || oldConfig === null) return oldConfig;
		const cleaned = {};
		for (const key in defaultConfig) if (defaultConfig.hasOwnProperty(key)) if (oldConfig.hasOwnProperty(key)) {
			const defaultValue = defaultConfig[key];
			const oldValue = oldConfig[key];
			if (typeof defaultValue === "object" && defaultValue !== null && !Array.isArray(defaultValue) && typeof oldValue === "object" && oldValue !== null && !Array.isArray(oldValue)) cleaned[key] = this.cleanupConfig(defaultValue, oldValue);
			else cleaned[key] = oldValue;
		} else cleaned[key] = defaultConfig[key];
		return cleaned;
	}
	migrateConfig(oldConfig) {
		let migratedConfig = oldConfig;
		if (oldConfig.musicSignUrl && oldConfig.musicSignUrl.includes("linyuchen")) oldConfig.musicSignUrl = defaultConfig.musicSignUrl;
		if (!oldConfig.ob11 || !Array.isArray(oldConfig.ob11.connect)) {
			const ob11 = oldConfig.ob11 || {};
			migratedConfig = {
				...oldConfig,
				ob11: {
					enable: ob11.enable || false,
					connect: [
						{
							type: "ws",
							enable: ob11.enableWs || false,
							port: ob11.wsPort || 3001,
							heartInterval: oldConfig.heartInterval || 3e4,
							token: ob11.token || "",
							messageFormat: ob11.messagePostFormat || "array",
							reportSelfMessage: ob11.reportSelfMessage || false,
							reportOfflineMessage: oldConfig.receiveOfflineMsg || false,
							debug: oldConfig.debug || false
						},
						{
							type: "ws-reverse",
							enable: ob11.enableWsReverse || false,
							url: ob11.wsReverseUrls && ob11.wsReverseUrls[0] || "",
							heartInterval: oldConfig.heartInterval || 3e4,
							token: ob11.token || "",
							messageFormat: ob11.messagePostFormat || "array",
							reportSelfMessage: ob11.reportSelfMessage || false,
							reportOfflineMessage: oldConfig.receiveOfflineMsg || false,
							debug: oldConfig.debug || false
						},
						{
							type: "http",
							enable: ob11.enableHttp || false,
							port: ob11.httpPort || 3e3,
							token: ob11.token || "",
							messageFormat: ob11.messagePostFormat || "array",
							reportSelfMessage: ob11.reportSelfMessage || false,
							reportOfflineMessage: oldConfig.receiveOfflineMsg || false,
							debug: oldConfig.debug || false
						},
						{
							type: "http-post",
							enable: ob11.enableHttpPost || false,
							url: ob11.httpPostUrls && ob11.httpPostUrls[0] || "",
							enableHeart: ob11.enableHttpHeart || false,
							heartInterval: oldConfig.heartInterval || 3e4,
							token: ob11.httpSecret || "",
							messageFormat: ob11.messagePostFormat || "array",
							reportSelfMessage: ob11.reportSelfMessage || false,
							reportOfflineMessage: oldConfig.receiveOfflineMsg || false,
							debug: oldConfig.debug || false
						}
					]
				}
			};
		}
		if ("onlyLocalhost" in oldConfig) {
			const host = oldConfig.onlyLocalhost ? "127.0.0.1" : "";
			if (migratedConfig.webui && !migratedConfig.webui.host) migratedConfig.webui.host = host;
			if (migratedConfig.satori && !migratedConfig.satori.host) migratedConfig.satori.host = host;
			if (migratedConfig.milky?.http && !migratedConfig.milky.http.host) migratedConfig.milky.http.host = host;
			if (Array.isArray(migratedConfig.ob11?.connect)) {
				for (const conn of migratedConfig.ob11.connect) if ((conn.type === "ws" || conn.type === "http") && !conn.host) conn.host = host;
			}
			delete migratedConfig.onlyLocalhost;
		}
		return migratedConfig;
	}
	migrateWebUIToken(oldWebuiConfig) {
		if (oldWebuiConfig.token && !webuiTokenUtil.getToken()) {
			webuiTokenUtil.setToken(oldWebuiConfig.token);
			delete oldWebuiConfig["token"];
		}
		return oldWebuiConfig;
	}
};
var WebUITokenUtil = class {
	tokenPath;
	token = "";
	constructor(tokenPath) {
		this.tokenPath = tokenPath;
		this.tokenPath = tokenPath;
	}
	getToken() {
		if (!this.token) {
			if (fs.existsSync(this.tokenPath)) this.token = fs.readFileSync(this.tokenPath, "utf-8").trim();
		}
		return this.token;
	}
	setToken(token) {
		this.token = token.trim();
		fs.writeFileSync(this.tokenPath, token, "utf-8");
	}
};
var webuiTokenUtil = new WebUITokenUtil(path.join(DATA_DIR, "webui_token.txt"));
var AuthTokenUtil = class {
	tokenPath;
	token = "";
	loaded = false;
	constructor(tokenPath) {
		this.tokenPath = tokenPath;
		this.tokenPath = tokenPath;
	}
	getToken() {
		if (!this.loaded) {
			if (fs.existsSync(this.tokenPath)) this.token = fs.readFileSync(this.tokenPath, "utf-8").trim();
			this.loaded = true;
		}
		return this.token;
	}
	/** 绝对路径, 给报错提示直接告诉用户去哪贴 token. */
	getPath() {
		return path.resolve(this.tokenPath);
	}
	setToken(token) {
		this.token = token.trim();
		fs.writeFileSync(this.tokenPath, this.token, "utf-8");
		this.loaded = true;
	}
	reload() {
		this.loaded = false;
		return this.getToken();
	}
};
var authTokenUtil = new AuthTokenUtil(path.join(DATA_DIR, "auth_token.txt"));
var AUTH_VALIDATE_API = "https://api-auth.luckylillia.com/api/sign/info";
/**
* 校验 auth token 是否有效.
* 2xx=valid, 401/403=invalid (失效/无权限).
* 纯 HTTP 探测, 不依赖 native sign 初始化, 未登录时也能用.
*/
async function validateAuthToken(token) {
	const t = token.trim();
	if (!t) return "invalid";
	const controller = new AbortController();
	const timer = setTimeout(() => controller.abort(), 15e3);
	try {
		const res = await fetch(AUTH_VALIDATE_API, {
			headers: { Authorization: `Bearer ${t}` },
			signal: controller.signal
		});
		if (res.ok) return "valid";
		if (res.status === 401 || res.status === 403) return "invalid";
		return res.status;
	} catch (e) {
		return e;
	} finally {
		clearTimeout(timer);
	}
}
//#endregion
//#region src/webui/BE/auth.ts
var globalLoginAttempt = {
	consecutiveFailures: 0,
	lockedUntil: null,
	lastAttempt: 0
};
var accessLogPath = path$1.join(LOG_DIR, "webui_access.log");
function logAccess(ip, method, path, status, message) {
	const logEntry = `${(/* @__PURE__ */ new Date()).toISOString()} | IP: ${ip} | ${method} ${path} | Status: ${status}${message ? ` | ${message}` : ""}\n`;
	try {
		appendFileSync(accessLogPath, logEntry);
	} catch (err) {
		getLogger("webui-auth").error("写入访问日志失败:", err);
	}
}
setInterval(() => {
	if (globalLoginAttempt.lockedUntil) {
		if (Date.now() >= globalLoginAttempt.lockedUntil) {
			globalLoginAttempt.consecutiveFailures = 0;
			globalLoginAttempt.lockedUntil = null;
		}
	}
}, 36e5);
async function authMiddleware(c, next) {
	const clientIp = c.env.incoming.socket.remoteAddress;
	const token = webuiTokenUtil.getToken();
	if (!token) {
		if (c.req.path === "/api/set-token") return await next();
		logAccess(clientIp, c.req.method, c.req.path, 401, "未设置密码");
		return c.json({
			success: false,
			message: "请先设置WebUI密码"
		}, 401);
	}
	if (globalLoginAttempt.lockedUntil) {
		const now = Date.now();
		if (now < globalLoginAttempt.lockedUntil) {
			const remainingMinutes = Math.ceil((globalLoginAttempt.lockedUntil - now) / 6e4);
			logAccess(clientIp, c.req.method, c.req.path, 403, `账户锁定中，剩余${remainingMinutes}分钟`);
			return c.json({
				success: false,
				message: `密码错误次数过多，请在 ${remainingMinutes} 分钟后重试`,
				locked: true,
				remainingMinutes
			}, 403);
		} else {
			globalLoginAttempt.consecutiveFailures = 0;
			globalLoginAttempt.lockedUntil = null;
		}
	}
	const reqToken = c.req.header("X-Webui-Token") || c.req.query("token");
	if (!reqToken) return c.json({
		success: false,
		message: `请输入密码`
	}, 403);
	if (reqToken !== hashPassword(token)) {
		globalLoginAttempt.consecutiveFailures++;
		globalLoginAttempt.lastAttempt = Date.now();
		const passwordFailureMax = 4;
		if (globalLoginAttempt.consecutiveFailures >= passwordFailureMax) {
			globalLoginAttempt.lockedUntil = Date.now() + 36e5;
			logAccess(clientIp, c.req.method, c.req.path, 403, `密码连续错误3次，账户锁定1小时`);
			return c.json({
				success: false,
				message: "密码连续错误3次，账户已被锁定1小时",
				locked: true,
				remainingMinutes: 60
			}, 403);
		}
		const remainingAttempts = passwordFailureMax - globalLoginAttempt.consecutiveFailures;
		logAccess(clientIp, c.req.method, c.req.path, 403, `Token验证失败，剩余${remainingAttempts}次尝试`);
		return c.json({
			success: false,
			message: `Token校验失败，剩余尝试次数：${remainingAttempts}`,
			remainingAttempts
		}, 403);
	}
	if (globalLoginAttempt.consecutiveFailures > 0) {
		logAccess(clientIp, c.req.method, c.req.path, 200, "登录成功，重置失败计数");
		globalLoginAttempt.consecutiveFailures = 0;
		globalLoginAttempt.lockedUntil = null;
	}
	logAccess(clientIp, c.req.method, c.req.path, 200);
	await next();
}
//#endregion
//#region src/webui/BE/utils.ts
function serializeResult(result) {
	if (result === null || result === void 0) return result;
	if (result instanceof Map) {
		const obj = {};
		for (const [key, value] of result) obj[String(key)] = serializeResult(value);
		return obj;
	}
	if (Array.isArray(result)) return result.map((item) => serializeResult(item));
	if (typeof result === "object") {
		const obj = {};
		for (const [key, value] of Object.entries(result)) obj[key] = serializeResult(value);
		return obj;
	}
	return result;
}
function encodeGroupRequestFlag(groupCode, seq, type, doubt) {
	return `${groupCode}|${seq}|${type}|${doubt ? 1 : 0}`;
}
function decodeGroupRequestFlag(flag) {
	const flagitem = flag.split("|");
	return {
		groupCode: +flagitem[0],
		seq: +flagitem[1],
		type: +flagitem[2],
		doubt: flagitem[3] === "1"
	};
}
//#endregion
//#region src/webui/BE/routes/config.ts
function isListenAllInterfaces(host) {
	return !host || host === "0.0.0.0" || host === "::";
}
function validateTokenConfig(config) {
	if (config.satori?.enable && isListenAllInterfaces(config.satori.host) && !config.satori.token) return "Satori 监听全部地址时必须设置 Token";
	if (config.milky?.enable && isListenAllInterfaces(config.milky.http?.host) && !config.milky.http?.accessToken) return "Milky HTTP 监听全部地址时必须设置 Token";
	if (config.ob11?.enable && Array.isArray(config.ob11.connect)) for (const conn of config.ob11.connect) {
		if (!conn.enable) continue;
		if ((conn.type === "ws" || conn.type === "http") && isListenAllInterfaces(conn.host) && !conn.token) return `OneBot11 ${conn.type === "ws" ? "WebSocket" : "HTTP"} 适配器监听全部地址时必须设置 Token`;
	}
	return null;
}
function createConfigRoutes(ctx) {
	const router = new Hono();
	router.get("/network-interfaces", async (c) => {
		try {
			const isDocker = isDockerEnvironment();
			const interfaces = networkInterfaces();
			const addresses = [];
			if (!isDocker) {
				for (const name in interfaces) for (const iface of interfaces[name] || []) if (iface.family === "IPv4" && !iface.internal) addresses.push(iface.address);
			}
			return c.json({
				success: true,
				data: addresses,
				isDocker
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取网卡列表失败",
				error: e
			}, 500);
		}
	});
	router.post("/set-token", async (c) => {
		const { token } = await c.req.json();
		if (!token) return c.json({
			success: false,
			message: "Token不能为空"
		}, 400);
		webuiTokenUtil.setToken(token);
		return c.json({
			success: true,
			message: "Token设置成功"
		});
	});
	router.get("/config", async (c) => {
		try {
			const resJson = {
				config: ctx.config.get(),
				selfInfo
			};
			return c.json({
				success: true,
				data: resJson
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取配置失败",
				error: e
			}, 500);
		}
	});
	router.post("/config", async (c) => {
		try {
			const { config } = await c.req.json();
			const newConfig = {
				...ctx.config.get(),
				...config
			};
			const validationError = validateTokenConfig(newConfig);
			if (validationError) return c.json({
				success: false,
				message: validationError
			}, 400);
			ctx.config.set(newConfig);
			ctx.parallel("llob/config-updated", newConfig);
			return c.json({
				success: true,
				message: "配置保存成功"
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "保存配置失败",
				error: e
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/main/qqProtocol/direct-lib/authTokenWatcher.ts
var started = false;
var processing = false;
var pending = false;
var lastValidToken = "";
var warnedNoToken = false;
var retryTimer = null;
var onValidCb = () => {};
var log = console;
var RETRY_MS = 15e3;
var POLL_MS = 1e3;
function startAuthTokenWatcher(onValid, logger) {
	if (started) return;
	started = true;
	onValidCb = onValid;
	log = logger;
	const file = authTokenUtil.getPath();
	processTokenFile();
	watchFile(file, { interval: POLL_MS }, () => void processTokenFile());
}
function triggerAuthTokenCheck() {
	if (started) processTokenFile();
}
async function processTokenFile() {
	if (processing) {
		pending = true;
		return;
	}
	processing = true;
	try {
		do {
			pending = false;
			await processOnce();
		} while (pending);
	} finally {
		processing = false;
	}
}
async function processOnce() {
	const token = authTokenUtil.reload() || (process.env.AUTH_TOKEN || "").trim();
	if (!token) {
		lastValidToken = "";
		authTokenStatus.hasToken = false;
		authTokenStatus.validation = "idle";
		authTokenStatus.message = "";
		if (!warnedNoToken) {
			warnedNoToken = true;
			log.warn("[Sign] auth_token 未配置: 请到 https://auth.luckylillia.com 获取 Auth Token, 在 WebUI 中录入或写入 data/auth_token.txt (录入后会自动校验并登录)");
		}
		return;
	}
	warnedNoToken = false;
	authTokenStatus.hasToken = true;
	if (token === lastValidToken && authTokenStatus.validation === "valid") return;
	clearRetry();
	authTokenStatus.validation = "validating";
	authTokenStatus.message = "";
	const result = await validateAuthToken(token);
	if (result === "valid") {
		authTokenStatus.validation = "valid";
		authTokenStatus.message = "";
		authTokenStatus.loginError = "";
		lastValidToken = token;
		log.info("[Sign] auth_token 校验通过, 开始登录流程");
		try {
			await onValidCb(token);
		} catch {
			lastValidToken = "";
			scheduleRetry();
		}
		return;
	}
	lastValidToken = "";
	if (result === "invalid") {
		authTokenStatus.validation = "invalid";
		authTokenStatus.message = "Auth Token 无效、已失效或无权限，请重新获取";
		log.warn("[Sign] auth_token 无效/失效/无权限, 等待重新录入");
	} else {
		authTokenStatus.validation = "error";
		authTokenStatus.message = "无法连接验证服务器（网络问题），将自动重试";
		if (result instanceof Error) log.warn("[Sign]", result.cause);
		else log.warn("[Sign] status code", result);
		log.warn("[Sign] auth_token 校验网络失败, 15s 后重试");
		scheduleRetry();
	}
}
function scheduleRetry() {
	clearRetry();
	retryTimer = setTimeout(() => {
		retryTimer = null;
		if (!selfInfo.online) processTokenFile();
	}, RETRY_MS);
}
function clearRetry() {
	if (retryTimer) {
		clearTimeout(retryTimer);
		retryTimer = null;
	}
}
//#endregion
//#region src/webui/BE/routes/authToken.ts
function createAuthTokenRoutes() {
	const router = new Hono();
	router.get("/auth-token/status", async (c) => {
		return c.json({
			success: true,
			data: {
				applicable: !isPmhqMode(),
				online: selfInfo.online,
				hasToken: authTokenStatus.hasToken,
				validation: authTokenStatus.validation,
				message: authTokenStatus.message,
				loginError: authTokenStatus.loginError
			}
		});
	});
	router.post("/auth-token", async (c) => {
		const body = await c.req.json().catch(() => ({}));
		const token = typeof body.token === "string" ? body.token.trim() : "";
		if (!token) return c.json({
			success: false,
			message: "Auth Token 不能为空"
		}, 400);
		authTokenUtil.setToken(token);
		authTokenStatus.hasToken = true;
		authTokenStatus.validation = "validating";
		authTokenStatus.message = "";
		authTokenStatus.loginError = "";
		triggerAuthTokenCheck();
		return c.json({
			success: true,
			message: "Auth Token 已保存，正在校验"
		});
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/dashboard.ts
function readCpuTimes() {
	let idle = 0;
	let total = 0;
	for (const c of os.cpus()) {
		idle += c.times.idle;
		total += c.times.user + c.times.nice + c.times.sys + c.times.idle + c.times.irq;
	}
	return {
		idle,
		total
	};
}
async function sampleSystemCpuPercent(sampleMs = 150) {
	const a = readCpuTimes();
	await new Promise((r) => setTimeout(r, sampleMs));
	const b = readCpuTimes();
	const totalDelta = b.total - a.total;
	const idleDelta = b.idle - a.idle;
	if (totalDelta <= 0) return 0;
	return Math.min(100, Math.max(0, (1 - idleDelta / totalDelta) * 100));
}
function createDashboardRoutes(ctx) {
	const router = new Hono();
	router.get("/dashboard/stats", async (c) => {
		try {
			const app = ctx.get("app");
			if (!app) return c.json({
				success: false,
				message: "服务尚未就绪，请等待登录完成"
			}, 503);
			const friends = await ctx.ntFriendApi.getFriends(false);
			const groups = await ctx.ntGroupApi.getGroups(false);
			const qqMemory = 0;
			const qqCpu = 0;
			const qqMemoryPercent = 0;
			const botTotalMem = os.totalmem();
			const cpuCores = os.cpus().length;
			const memUsage = process.memoryUsage();
			const cpuUsage = process.cpuUsage();
			const botCpuPercent = (cpuUsage.user + cpuUsage.system) / 1e6 / process.uptime() / cpuCores * 100;
			const botMemoryPercent = memUsage.rss / botTotalMem * 100;
			const sysTotalMem = os.totalmem();
			const sysUsedMem = sysTotalMem - os.freemem();
			const sysMemPercent = sysUsedMem / sysTotalMem * 100;
			const sysCpuPercent = await sampleSystemCpuPercent();
			return c.json({
				success: true,
				data: {
					friendCount: friends.friends.length,
					groupCount: groups.length,
					messageReceived: app.messageReceivedCount,
					messageSent: app.messageSentCount,
					startupTime: app.startupTime,
					lastMessageTime: app.lastMessageTime,
					mode: isPmhqMode() ? "pmhq" : "direct",
					bot: {
						memory: memUsage.rss,
						totalMemory: botTotalMem,
						memoryPercent: botMemoryPercent,
						cpu: botCpuPercent
					},
					qq: {
						memory: qqMemory,
						totalMemory: 0,
						memoryPercent: qqMemoryPercent,
						cpu: qqCpu
					},
					system: {
						memory: sysUsedMem,
						totalMemory: sysTotalMem,
						memoryPercent: sysMemPercent,
						cpu: sysCpuPercent,
						label: `${cpuCores} 核`
					}
				}
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取统计数据失败",
				error: e
			}, 500);
		}
	});
	router.get("/device-info", async (c) => {
		try {
			const deviceInfo = await ctx.ntSystemApi.getDeviceInfo();
			return c.json({
				success: true,
				data: deviceInfo
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取设备信息失败",
				error: e
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/login.ts
function createLoginRoutes(ctx) {
	const router = new Hono();
	router.get("/login-qrcode", async (c) => {
		try {
			const data = await ctx.ntLoginApi.getLoginQrCode();
			return c.json({
				success: true,
				data
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取登录二维码失败",
				error: e
			}, 500);
		}
	});
	router.get("/quick-login-list", async (c) => {
		try {
			const data = await ctx.ntLoginApi.getQuickLoginList();
			return c.json({
				success: true,
				data
			});
		} catch (e) {
			return c.json({
				success: false,
				message: "获取快速登录账号列表失败",
				error: e
			}, 500);
		}
	});
	router.post("/quick-login", async (c) => {
		const { uin } = await c.req.json();
		if (!uin) return c.json({
			success: false,
			message: "没有选择QQ号"
		}, 400);
		try {
			await ctx.qqProtocol.quickLogin(String(uin));
			return c.json({
				success: true,
				data: {
					result: "0",
					loginErrorInfo: { errMsg: "" }
				}
			});
		} catch (e) {
			return c.json({
				success: false,
				message: e.message || "快速登录失败",
				data: {
					result: "-1",
					loginErrorInfo: { errMsg: e.message || "快速登录失败" }
				}
			}, 500);
		}
	});
	router.post("/logout", async (c) => {
		if (isPmhqMode()) return c.json({
			success: false,
			message: "PMHQ 模式暂不支持退出 QQ"
		}, 400);
		try {
			await ctx.qqProtocol.logout();
			return c.json({ success: true });
		} catch (e) {
			return c.json({
				success: false,
				message: e.message || "退出登录失败"
			}, 500);
		}
	});
	router.get("/login-info", (c) => {
		let webui;
		if (selfInfo.online && selfInfo.uin) try {
			const p = path.join(DATA_DIR, `config_${selfInfo.uin}.json`);
			if (existsSync(p)) {
				const cfg = import_dist.default.parse(readFileSync(p, "utf-8"));
				if (cfg?.webui) webui = {
					enable: cfg.webui.enable !== false,
					host: cfg.webui.host ?? "",
					port: Number(cfg.webui.port) || 0
				};
			}
		} catch {}
		return c.json({
			success: true,
			data: {
				...selfInfo,
				mode: isPmhqMode() ? "pmhq" : "direct",
				webui
			}
		});
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/logs.ts
function createLogsRoutes(ctx) {
	const router = new Hono();
	router.get("/logs/stream", async (c) => {
		return streamSSE(c, async (stream) => {
			stream.writeSSE({
				data: "{}",
				event: "connected"
			});
			for (const record of getLogCache()) stream.writeSSE({ data: JSON.stringify(record) });
			const dispose = ctx.on("llob/log", (record) => {
				stream.writeSSE({ data: JSON.stringify(record) });
			});
			stream.onAbort(() => {
				dispose();
			});
			return new Promise((resolve) => {
				stream.onAbort(resolve);
			});
		});
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/messages.ts
function isSelfEchoTimeout(e) {
	return e instanceof Error && e.message.includes("waitForSelfEcho timeout");
}
function createMessagesRoutes(ctx, createPicElement) {
	const router = new Hono();
	const resolvePeer = async (chatType, peerId) => {
		let peerUid = String(peerId);
		if (chatType === ChatType.C2C || chatType === ChatType.TempC2CFromGroup) {
			const uid = await ctx.ntUserApi.getUidByUin(+peerId);
			if (!uid) throw new Error("无法获取用户信息");
			peerUid = uid;
		}
		return {
			chatType,
			peerUid,
			guildId: ""
		};
	};
	router.get("/messages", async (c) => {
		try {
			const { chatType, peerId, beforeMsgSeq, afterMsgSeq, limit = "20" } = c.req.query();
			if (!chatType || !peerId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const chatTypeNum = Number(chatType);
			if (chatTypeNum !== ChatType.C2C && chatTypeNum !== ChatType.Group && chatTypeNum !== ChatType.TempC2CFromGroup) return c.json({
				success: false,
				message: `无效的 chatType: ${chatType}，应为 1(私聊)、2(群聊) 或 100(临时会话)`
			}, 400);
			let peerUid = peerId;
			if (chatTypeNum === ChatType.C2C || chatTypeNum === ChatType.TempC2CFromGroup) {
				const uid = await ctx.ntUserApi.getUidByUin(+peerId);
				if (!uid) return c.json({
					success: false,
					message: "无法获取用户信息"
				}, 400);
				peerUid = uid;
			}
			const peer = {
				chatType: chatTypeNum,
				peerUid,
				guildId: ""
			};
			let result;
			if (afterMsgSeq) result = await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, +afterMsgSeq, +limit, false);
			else if (beforeMsgSeq && beforeMsgSeq !== "0") result = await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, +beforeMsgSeq, +limit, true);
			else {
				const latestSeq = await ctx.ntMsgApi.getLatestMsgSeq(peer);
				result = await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, latestSeq, +limit, true);
			}
			const messages = result?.msgList || [];
			messages.sort((a, b) => a.msgTime - b.msgTime);
			return c.json({
				success: true,
				data: serializeResult({
					messages,
					hasMore: messages.length >= parseInt(limit)
				})
			});
		} catch (e) {
			ctx.logger.error("获取消息历史失败:", e);
			return c.json({
				success: false,
				message: "获取消息历史失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/messages", async (c) => {
		const uploadedFiles = [];
		try {
			const { chatType, peerId, content } = await c.req.json();
			if (chatType === void 0 || chatType === null || !peerId || !content || content.length === 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const chatTypeNum = Number(chatType);
			if (chatTypeNum !== ChatType.C2C && chatTypeNum !== ChatType.Group && chatTypeNum !== ChatType.TempC2CFromGroup) return c.json({
				success: false,
				message: `无效的 chatType: ${chatType}，应为 1(私聊)、2(群聊) 或 100(临时会话)`
			}, 400);
			let peerUid = peerId;
			if (chatTypeNum === ChatType.C2C || chatTypeNum === ChatType.TempC2CFromGroup) {
				const uid = await ctx.ntUserApi.getUidByUin(+peerId);
				if (!uid) return c.json({
					success: false,
					message: "无法获取用户信息"
				}, 400);
				peerUid = uid;
			}
			const peer = {
				chatType: chatTypeNum,
				peerUid,
				guildId: ""
			};
			const elements = [];
			const files = [];
			for (const item of content) if (item.type === "reply" && item.msgId && item.msgSeq) elements.push({
				elementType: ElementType.Reply,
				replyElement: {
					replyMsgSeq: Number(item.msgSeq),
					replyMsgTime: 0,
					senderUin: Number(item.uin ?? 0),
					senderUid: item.uid ?? "",
					replyMsgClientSeq: 0
				}
			});
			else if (item.type === "text" && item.text) elements.push({
				elementType: ElementType.Text,
				textElement: {
					content: item.text,
					atType: 0,
					atUin: 0
				}
			});
			else if (item.type === "at" && item.uid) {
				const atUin = item.uin || "";
				const display = item.name ? `@${item.name}` : "@";
				elements.push({
					elementType: ElementType.Text,
					textElement: {
						content: display,
						atType: 2,
						atUin: +atUin
					}
				});
			} else if (item.type === "image" && item.imagePath) {
				uploadedFiles.push(item.imagePath);
				const picElement = await createPicElement(item.imagePath);
				if (picElement) elements.push(picElement);
			} else if (item.type === "face" && item.faceId !== void 0) elements.push(SendElement.face(item.faceId));
			else if (item.type === "file" && item.filePath && item.fileName) {
				uploadedFiles.push(item.filePath);
				files.push({
					filePath: item.filePath,
					fileName: item.fileName
				});
			}
			if (files.length > 0) {
				if (elements.length > 0) return c.json({
					success: false,
					message: "文件不能和文字/图片/表情一起发送"
				}, 400);
				const sentMsgIds = [];
				for (const f of files) if (chatTypeNum === ChatType.Group) {
					const info = await ctx.ntFileApi.uploadGroupFile(+peerId, f.filePath, f.fileName);
					const result = await ctx.ntMsgApi.sendGroupFileMessage(+peerId, info.fileId, info.busId);
					if (result.retCode !== 0) return c.json({
						success: false,
						message: "发送群文件失败",
						error: result.clientWording || ""
					}, 500);
					sentMsgIds.push(info.fileId);
				} else {
					const info = await ctx.ntFileApi.uploadPrivateFile(ChatType.C2C, peerUid, f.filePath, f.fileName);
					const result = await ctx.ntMsgApi.sendPrivateFileMessage({
						toUin: +peerId,
						toUid: peerUid,
						fileUuid: info.fileId,
						fileName: f.fileName,
						fileSize: info.fileSize,
						file10MMd5: info.file10MMd5,
						crcMedia: info.crcMedia
					});
					if (result.resultCode !== 0) return c.json({
						success: false,
						message: "发送私聊文件失败",
						error: result.errMsg ?? ""
					}, 500);
					sentMsgIds.push(info.fileId);
				}
				for (const filePath of uploadedFiles) unlink(filePath).catch((err) => {
					ctx.logger.warn(`清理临时文件失败: ${filePath}`, err);
				});
				return c.json({
					success: true,
					data: { msgId: sentMsgIds[0] }
				});
			}
			if (elements.length === 0) return c.json({
				success: false,
				message: "消息内容为空"
			}, 400);
			const result = await ctx.ntMsgApi.sendMsg(peer, elements);
			for (const filePath of uploadedFiles) unlink(filePath).catch((err) => {
				ctx.logger.warn(`清理临时文件失败: ${filePath}`, err);
			});
			return c.json({
				success: true,
				data: { msgId: result.msgId }
			});
		} catch (e) {
			ctx.logger.error("发送消息失败:", e);
			for (const filePath of uploadedFiles) unlink(filePath).catch((err) => {
				ctx.logger.warn(`清理临时文件失败: ${filePath}`, err);
			});
			return c.json({
				success: false,
				message: "发送消息失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/messages/forward", async (c) => {
		let cleanup = [];
		try {
			const { srcChatType, srcPeerId, msgSeq, targetChatType, targetPeerId } = await c.req.json();
			if (srcChatType == null || !srcPeerId || msgSeq == null || targetChatType == null || !targetPeerId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const srcPeer = await resolvePeer(Number(srcChatType), srcPeerId);
			const targetPeer = await resolvePeer(Number(targetChatType), targetPeerId);
			const msg = (await ctx.ntMsgApi.getSingleMsg(srcPeer, Number(msgSeq))).msgList?.[0];
			if (!msg) return c.json({
				success: false,
				message: "找不到源消息"
			}, 404);
			const { elements, deleteAfterSentFiles } = await rawElementsToSend(ctx, msg.elements, srcPeer);
			cleanup = deleteAfterSentFiles;
			if (elements.length === 0) return c.json({
				success: false,
				message: "该消息无可转发内容"
			}, 400);
			const result = await ctx.ntMsgApi.sendMsg(targetPeer, elements);
			return c.json({
				success: true,
				data: { msgId: result.msgId }
			});
		} catch (e) {
			if (isSelfEchoTimeout(e)) return c.json({
				success: true,
				data: { msgId: "" }
			});
			ctx.logger.error("转发消息失败:", e);
			return c.json({
				success: false,
				message: "转发消息失败",
				error: e.message
			}, 500);
		} finally {
			for (const f of cleanup) unlink(f).catch(() => {});
		}
	});
	router.post("/messages/forward-multi", async (c) => {
		const cleanup = [];
		try {
			const { srcChatType, srcPeerId, msgSeqs, targetChatType, targetPeerId } = await c.req.json();
			if (srcChatType == null || !srcPeerId || !Array.isArray(msgSeqs) || msgSeqs.length === 0 || targetChatType == null || !targetPeerId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const srcPeer = await resolvePeer(Number(srcChatType), srcPeerId);
			const targetPeer = await resolvePeer(Number(targetChatType), targetPeerId);
			const seqs = [...msgSeqs].map(Number).sort((a, b) => a - b);
			const nodes = [];
			for (const seq of seqs) {
				const msg = (await ctx.ntMsgApi.getSingleMsg(srcPeer, seq)).msgList?.[0];
				if (!msg) continue;
				const { elements, deleteAfterSentFiles } = await rawElementsToSend(ctx, msg.elements, srcPeer);
				if (elements.length === 0) continue;
				cleanup.push(...deleteAfterSentFiles);
				nodes.push({
					senderUin: msg.senderUin,
					senderName: msg.sendMemberName || msg.sendNickName || String(msg.senderUin),
					elements,
					msgSeq: msg.msgSeq,
					msgTime: msg.msgTime,
					msgStyle: msg.msgStyle
				});
			}
			if (nodes.length === 0) return c.json({
				success: false,
				message: "没有可转发的消息"
			}, 400);
			const forwardElement = SendElement.forward(nodes);
			const result = await ctx.ntMsgApi.sendMsg(targetPeer, [forwardElement]);
			return c.json({
				success: true,
				data: { msgId: result.msgId }
			});
		} catch (e) {
			if (isSelfEchoTimeout(e)) return c.json({
				success: true,
				data: { msgId: "" }
			});
			ctx.logger.error("合并转发失败:", e);
			return c.json({
				success: false,
				message: "合并转发失败",
				error: e.message
			}, 500);
		} finally {
			for (const f of cleanup) unlink(f).catch(() => {});
		}
	});
	router.get("/forward-msg", async (c) => {
		try {
			const { resId } = c.req.query();
			if (!resId) return c.json({
				success: false,
				message: "缺少 resId 参数"
			}, 400);
			const { msgList } = await ctx.ntMsgApi.getForwardedMsgs(resId);
			const transformed = await Promise.all(msgList.map(async (msg) => {
				const segments = [];
				for (const elem of msg.elements ?? []) if (elem.elementType === ElementType.Text && elem.textElement?.content) segments.push({
					type: "text",
					data: { text: elem.textElement.content }
				});
				else if (elem.elementType === ElementType.Pic && elem.picElement) {
					const p = elem.picElement;
					try {
						const url = await ctx.ntFileApi.getImageUrl(p.originImageUrl ?? "", p.md5HexStr ?? "");
						segments.push({
							type: "image",
							data: {
								url,
								width: p.picWidth,
								height: p.picHeight
							}
						});
					} catch {
						segments.push({
							type: "text",
							data: { text: "[图片]" }
						});
					}
				} else if (elem.elementType === ElementType.Face && elem.faceElement) segments.push({
					type: "face",
					data: { faceId: elem.faceElement.faceIndex }
				});
				else if (elem.elementType === ElementType.MarketFace && elem.marketFaceElement) {
					const mf = elem.marketFaceElement;
					segments.push({
						type: "text",
						data: { text: mf.faceName || "[表情]" }
					});
				} else if (elem.elementType === ElementType.Video) segments.push({
					type: "text",
					data: { text: "[视频]" }
				});
				else if (elem.elementType === ElementType.Ptt) segments.push({
					type: "text",
					data: { text: "[语音]" }
				});
				else if (elem.elementType === ElementType.File) segments.push({
					type: "text",
					data: { text: "[文件]" }
				});
				else if (elem.elementType === ElementType.MultiForward && elem.multiForwardMsgElement) {
					const mf = elem.multiForwardMsgElement;
					const briefMatch = mf.xmlContent?.match(/brief="([^"]+)"/);
					segments.push({
						type: "forward",
						data: {
							resId: mf.resId,
							title: briefMatch?.[1] || "[聊天记录]"
						}
					});
				} else if (elem.elementType === ElementType.Ark && elem.arkElement?.bytesData) segments.push({
					type: "forward",
					data: { title: "[聊天记录]" }
				});
				return {
					senderName: msg.sendMemberName || msg.sendNickName || "",
					senderUin: Number(msg.senderUin) || 0,
					time: Number(msg.msgTime) || 0,
					segments
				};
			}));
			return c.json({
				success: true,
				data: transformed
			});
		} catch (e) {
			ctx.logger.error("获取合并转发消息失败:", e);
			return c.json({
				success: false,
				message: "获取合并转发消息失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/video-url", async (c) => {
		try {
			const { fileUuid, isGroup } = c.req.query();
			if (!fileUuid) return c.json({
				success: false,
				message: "缺少 fileUuid 参数"
			}, 400);
			const url = await ctx.ntFileApi.getVideoUrl(fileUuid, isGroup === "true");
			return c.json({
				success: true,
				data: url
			});
		} catch (e) {
			ctx.logger.error("获取视频 URL 失败:", e);
			return c.json({
				success: false,
				message: "获取视频 URL 失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/messages/recall", async (c) => {
		try {
			const { msgId, chatType, peerUid } = await c.req.json();
			if (!msgId || chatType === void 0 || !peerUid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const peer = {
				chatType,
				peerUid,
				guildId: ""
			};
			const msg = ctx.store.getMsgByMsgId(msgId);
			if (!msg) return c.json({
				success: false,
				message: "找不到要撤回的消息（可能 store 缓存丢了）"
			}, 400);
			if (chatType === ChatType.Group) await ctx.ntMsgApi.recallMsg(peer, msg.msgSeq);
			else await ctx.ntMsgApi.recallMsg(peer, msg.msgSeq, msg.clientSeq, msg.msgRandom, +msg.msgTime);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("撤回消息失败:", e);
			return c.json({
				success: false,
				message: "撤回消息失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/messages/emoji-like", async (c) => {
		try {
			const { groupCode, msgSeq, emojiId, set } = await c.req.json();
			if (!groupCode || msgSeq === void 0 || !emojiId || set === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntMsgApi.setGroupMsgReaction(+groupCode, +msgSeq, emojiId, set);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("贴表情失败:", e);
			return c.json({
				success: false,
				message: "贴表情失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/messages/ptt-to-text", async (c) => {
		try {
			const { msgId, chatType, peerUid } = await c.req.json();
			if (!msgId || chatType === void 0 || !peerUid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const peer = {
				chatType,
				peerUid,
				guildId: ""
			};
			const msg = ctx.store.getMsgByMsgId(msgId);
			if (!msg) return c.json({
				success: false,
				message: "找不到原消息（store 缓存丢了）"
			}, 400);
			const voiceElement = msg.elements.find((e) => e.elementType === ElementType.Ptt);
			if (!voiceElement) return c.json({
				success: false,
				message: "该消息不是语音消息"
			}, 400);
			const text = await ctx.ntMsgApi.translatePtt2Text(msgId, peer, +msg.senderUin, voiceElement);
			return c.json({
				success: true,
				data: text || ""
			});
		} catch (e) {
			ctx.logger.error("语音转文字失败:", e);
			return c.json({
				success: false,
				message: "语音转文字失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/fav-emoji", async (c) => {
		try {
			const result = await ctx.ntMsgApi.getCustomFaceList();
			return c.json({
				success: true,
				data: serializeResult(result)
			});
		} catch (e) {
			ctx.logger.error("获取收藏表情失败:", e);
			return c.json({
				success: false,
				message: "获取收藏表情失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/fav-emoji/delete", async (c) => {
		try {
			const { emojiIds } = await c.req.json();
			if (!emojiIds || !emojiIds.length) return c.json({
				success: false,
				message: "缺少 emojiIds 参数"
			}, 400);
			const result = await ctx.ntMsgApi.deleteCustomFace(emojiIds);
			return c.json({
				success: true,
				data: serializeResult(result)
			});
		} catch (e) {
			ctx.logger.error("删除收藏表情失败:", e);
			return c.json({
				success: false,
				message: "删除收藏表情失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/fav-emoji/add", async (c) => {
		try {
			const { filePath } = await c.req.json();
			if (!filePath) return c.json({
				success: false,
				message: "缺少 filePath 参数"
			}, 400);
			const result = await ctx.ntMsgApi.addCustomFace(filePath);
			return c.json({
				success: true,
				data: serializeResult(result)
			});
		} catch (e) {
			ctx.logger.error("添加收藏表情失败:", e);
			return c.json({
				success: false,
				message: "添加收藏表情失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/fav-emoji/add-from-url", async (c) => {
		let tempPath = null;
		try {
			const { url: rawUrl } = await c.req.json();
			if (!rawUrl) return c.json({
				success: false,
				message: "缺少 url 参数"
			}, 400);
			let url = rawUrl;
			let parsedUrl;
			try {
				parsedUrl = new URL(url);
			} catch {
				return c.json({
					success: false,
					message: "无效的 URL"
				}, 400);
			}
			if (![
				"gchat.qpic.cn",
				"multimedia.nt.qq.com.cn",
				"c2cpicdw.qpic.cn",
				"p.qlogo.cn",
				"q1.qlogo.cn",
				"p.qpic.cn"
			].some((host) => parsedUrl.hostname.includes(host))) return c.json({
				success: false,
				message: "不允许下载此域名的图片"
			}, 403);
			if (!url.includes("rkey=") && (parsedUrl.hostname.includes("multimedia.nt.qq.com.cn") || parsedUrl.hostname.includes("gchat.qpic.cn"))) try {
				const appid = parsedUrl.searchParams.get("appid");
				if (appid && ["1406", "1407"].includes(appid)) {
					const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey();
					const rkey = appid === "1406" ? rkeyData.private_rkey : rkeyData.group_rkey;
					if (rkey) url = url + rkey;
				}
			} catch (e) {
				ctx.logger.warn("add-from-url 添加 rkey 失败:", e);
			}
			const response = await fetch(url, { headers: {
				"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
				"Accept": "image/webp,image/apng,image/*,*/*;q=0.8"
			} });
			if (!response.ok) return c.json({
				success: false,
				message: `下载图片失败: ${response.status} ${response.statusText}`
			}, 500);
			const buffer = Buffer.from(await response.arrayBuffer());
			if (!existsSync(TEMP_DIR)) await mkdir(TEMP_DIR, { recursive: true });
			const pathExt = parsedUrl.pathname.match(/\.([a-zA-Z0-9]{1,5})$/)?.[1] ?? "png";
			tempPath = join(TEMP_DIR, `fav-emoji-${randomUUID()}.${pathExt}`);
			await writeFile(tempPath, buffer);
			const result = await ctx.ntMsgApi.addCustomFace(tempPath);
			return c.json({
				success: true,
				data: serializeResult(result)
			});
		} catch (e) {
			ctx.logger.error("从 URL 添加收藏表情失败:", e);
			return c.json({
				success: false,
				message: "从 URL 添加收藏表情失败",
				error: e.message
			}, 500);
		} finally {
			if (tempPath) unlink(tempPath).catch(() => {});
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/upload.ts
function createUploadRoutes(ctx, uploadDir) {
	const router = new Hono();
	router.post("/upload", async (c) => {
		try {
			if (c.req.header("Content-Type")?.includes("application/json")) {
				const imageUrl = (await c.req.json()).imageUrl;
				if (imageUrl) {
					const response = await fetch(imageUrl);
					if (!response.ok) return c.json({
						success: false,
						message: "下载图片失败"
					}, 400);
					const buffer = Buffer.from(await response.arrayBuffer());
					const ext = imageUrl.includes(".gif") ? ".gif" : imageUrl.includes(".png") ? ".png" : ".jpg";
					const filename = `url_${Date.now()}${ext}`;
					const filePath = path$1.join(uploadDir, filename);
					await promises.writeFile(filePath, buffer);
					return c.json({
						success: true,
						data: {
							imagePath: filePath,
							filename
						}
					});
				}
			}
			const { image } = await c.req.parseBody();
			if (!(image instanceof File)) return c.json({
				success: false,
				message: "没有上传文件"
			}, 400);
			if (![
				"image/jpeg",
				"image/png",
				"image/gif",
				"image/jpg"
			].includes(image.type)) throw new Error("不支持的图片格式，仅支持 JPG、PNG、GIF");
			if (image.size > 10485760) throw new Error("图片体积超出限制");
			const ext = path$1.extname(image.name);
			const fileName = `${randomUUID()}${ext}`;
			const filePath = path$1.join(uploadDir, fileName);
			await promises.writeFile(filePath, await image.bytes());
			return c.json({
				success: true,
				data: {
					imagePath: filePath,
					filename: fileName
				}
			});
		} catch (e) {
			ctx.logger.error("上传图片失败:", e);
			return c.json({
				success: false,
				message: "上传图片失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/upload-file", async (c) => {
		try {
			const { file } = await c.req.parseBody();
			if (!(file instanceof File)) return c.json({
				success: false,
				message: "没有上传文件"
			}, 400);
			const ext = path$1.extname(file.name);
			const fileName = `${randomUUID()}${ext}`;
			const filePath = path$1.join(uploadDir, fileName);
			await promises.writeFile(filePath, await file.bytes());
			return c.json({
				success: true,
				data: {
					filePath,
					fileName: file.name,
					fileSize: file.size
				}
			});
		} catch (e) {
			ctx.logger.error("上传文件失败:", e);
			return c.json({
				success: false,
				message: "上传文件失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/proxy.ts
function createProxyRoutes(ctx) {
	const router = new Hono();
	router.get("/file-proxy", async (c) => {
		try {
			const filePath = c.req.query("path");
			if (!filePath) return c.json({
				success: false,
				message: "缺少文件路径参数"
			}, 400);
			const normalizedPath = path$1.normalize(filePath);
			if (!existsSync(normalizedPath)) return c.json({
				success: false,
				message: "文件不存在"
			}, 404);
			const contentType = {
				".jpg": "image/jpeg",
				".jpeg": "image/jpeg",
				".png": "image/png",
				".gif": "image/gif",
				".webp": "image/webp",
				".mp4": "video/mp4",
				".webm": "video/webm"
			}[path$1.extname(normalizedPath).toLowerCase()] || "application/octet-stream";
			c.header("Content-Type", contentType);
			c.header("Cache-Control", "public, max-age=86400");
			return c.body(await readFile(normalizedPath));
		} catch (e) {
			ctx.logger.error("文件代理失败:", e);
			return c.json({
				success: false,
				message: "文件代理失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/image-proxy", async (c) => {
		try {
			const urlParam = c.req.query("url");
			if (!urlParam) return c.json({
				success: false,
				message: "缺少图片URL参数"
			}, 400);
			let url = decodeURIComponent(urlParam);
			let parsedUrl;
			try {
				parsedUrl = new URL(url);
			} catch (e) {
				return c.json({
					success: false,
					message: "无效的URL"
				}, 400);
			}
			const allowedHosts = [
				"gchat.qpic.cn",
				"multimedia.nt.qq.com.cn",
				"c2cpicdw.qpic.cn",
				"p.qlogo.cn",
				"q1.qlogo.cn"
			];
			const hostname = parsedUrl.hostname.toLowerCase();
			if (!allowedHosts.some((host) => hostname === host || hostname.endsWith("." + host))) return c.json({
				success: false,
				message: "不允许代理此域名的图片"
			}, 403);
			if (!url.includes("rkey=") && (parsedUrl.hostname.includes("multimedia.nt.qq.com.cn") || parsedUrl.hostname.includes("gchat.qpic.cn"))) try {
				const appid = parsedUrl.searchParams.get("appid");
				if (appid && ["1406", "1407"].includes(appid)) {
					const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey();
					const rkey = appid === "1406" ? rkeyData.private_rkey : rkeyData.group_rkey;
					if (rkey) url = url + rkey;
				}
			} catch (e) {
				ctx.logger.warn("添加 rkey 失败:", e);
			}
			const response = await fetch(url, { headers: {
				"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
				"Accept": "image/webp,image/apng,image/*,*/*;q=0.8",
				"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
			} });
			if (!response.ok) {
				ctx.logger.warn("图片代理请求失败:", response.status, response.statusText);
				return c.json({
					success: false,
					message: `获取图片失败: ${response.statusText}`
				}, response.status);
			}
			const contentType = response.headers.get("content-type") || "image/png";
			c.header("Content-Type", contentType);
			c.header("Cache-Control", "public, max-age=86400");
			c.header("Access-Control-Allow-Origin", "*");
			const buffer = await response.arrayBuffer();
			return c.body(buffer);
		} catch (e) {
			ctx.logger.error("图片代理失败:", e);
			return c.json({
				success: false,
				message: "图片代理失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/rkey", async (c) => {
		try {
			const rkeyData = await ctx.ntFileApi.rkeyManager.getRkey();
			return c.json({
				success: true,
				data: {
					private_rkey: rkeyData.private_rkey || "",
					group_rkey: rkeyData.group_rkey || ""
				}
			});
		} catch (e) {
			ctx.logger.warn("获取 rkey 失败:", e);
			return c.json({
				success: false,
				message: "获取 rkey 失败"
			}, 500);
		}
	});
	router.get("/audio-proxy", async (c) => {
		try {
			const fileUuid = c.req.query("fileUuid");
			const filePath = c.req.query("filePath");
			const isGroup = c.req.query("isGroup") === "true";
			if (!fileUuid && !filePath) return c.json({
				success: false,
				message: "缺少 fileUuid 或 filePath 参数"
			}, 400);
			ctx.logger.info("语音代理请求:", {
				fileUuid,
				filePath,
				isGroup
			});
			let audioFilePath = "";
			if (filePath) {
				const decodedPath = decodeURIComponent(filePath);
				try {
					await access(decodedPath);
					audioFilePath = decodedPath;
					ctx.logger.info("使用本地文件:", audioFilePath);
				} catch {
					ctx.logger.warn("本地文件不存在，尝试从URL获取");
				}
			}
			if (!audioFilePath && fileUuid) {
				const url = await ctx.ntFileApi.getPttUrl(fileUuid, isGroup);
				if (!url) return c.json({
					success: false,
					message: "获取语音URL失败"
				}, 404);
				ctx.logger.info("语音URL:", url);
				const response = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } });
				if (!response.ok) {
					ctx.logger.warn("语音代理请求失败:", response.status, response.statusText);
					return c.json({
						success: false,
						message: `获取语音失败: ${response.statusText}`
					}, response.status);
				}
				const audioBuffer = Buffer.from(await response.arrayBuffer());
				const tempDir = os.tmpdir();
				audioFilePath = path$1.join(tempDir, `ptt_${randomUUID()}.silk`);
				await writeFile(audioFilePath, audioBuffer);
			}
			try {
				const mp3Path = await decodeSilk(ctx, audioFilePath, "mp3");
				const mp3Buffer = await readFile(mp3Path);
				if (audioFilePath.includes(os.tmpdir())) unlink(audioFilePath).catch(() => {});
				unlink(mp3Path).catch(() => {});
				c.header("Content-Type", "audio/mpeg");
				c.header("Cache-Control", "public, max-age=86400");
				c.header("Access-Control-Allow-Origin", "*");
				return c.body(mp3Buffer);
			} catch (decodeError) {
				ctx.logger.error("silk 解码失败:", decodeError);
				return c.json({
					success: false,
					message: "语音解码失败",
					error: String(decodeError)
				}, 500);
			}
		} catch (e) {
			ctx.logger.error("语音代理失败:", e);
			return c.json({
				success: false,
				message: "语音代理失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/members.ts
function createMembersRoutes(ctx) {
	const router = new Hono();
	router.get("/members", async (c) => {
		try {
			const { groupCode } = c.req.query();
			if (!groupCode) return c.json({
				success: false,
				message: "缺少群号参数"
			}, 400);
			const result = await ctx.ntGroupApi.getGroupMembers(+groupCode, false);
			const members = [];
			for (const member of result) {
				const role = member.role === 4 ? "owner" : member.role === 3 ? "admin" : "member";
				members.push({
					uid: member.uid,
					uin: member.uin.toString(),
					nickname: member.nick,
					card: member.cardName || "",
					avatar: `https://q1.qlogo.cn/g?b=qq&nk=${member.uin}&s=640`,
					role,
					level: member.level,
					specialTitle: member.specialTitle
				});
			}
			const roleOrder = {
				owner: 0,
				admin: 1,
				member: 2
			};
			members.sort((a, b) => roleOrder[a.role] - roleOrder[b.role]);
			return c.json({
				success: true,
				data: members
			});
		} catch (e) {
			ctx.logger.error("获取群成员失败:", e);
			return c.json({
				success: false,
				message: "获取群成员失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/user-info", async (c) => {
		try {
			const { uid } = c.req.query();
			if (!uid) return c.json({
				success: false,
				message: "缺少 uid 参数"
			}, 400);
			const userInfo = await ctx.ntUserApi.getUserByUid(uid);
			const uin = await ctx.ntUserApi.getUinByUid(uid);
			return c.json({
				success: true,
				data: {
					uid,
					uin: uin.toString(),
					nickname: userInfo.nick,
					remark: userInfo.remark
				}
			});
		} catch (e) {
			ctx.logger.error("获取用户信息失败:", e);
			return c.json({
				success: false,
				message: "获取用户信息失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/group-member", async (c) => {
		try {
			const { groupCode, uid } = c.req.query();
			if (!groupCode || !uid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const member = await ctx.ntGroupApi.getGroupMemberByUid(+groupCode, uid, false);
			if (!member) return c.json({
				success: true,
				data: null
			});
			return c.json({
				success: true,
				data: serializeResult(member)
			});
		} catch (e) {
			ctx.logger.error("获取群成员详情失败:", e);
			return c.json({
				success: false,
				message: "获取群成员详情失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/group-detail", async (c) => {
		try {
			const { groupCode } = c.req.query();
			if (!groupCode) return c.json({
				success: false,
				message: "缺少 groupCode 参数"
			}, 400);
			const group = await ctx.ntGroupApi.getGroup(+groupCode, false);
			return c.json({
				success: true,
				data: serializeResult(group)
			});
		} catch (e) {
			ctx.logger.error("获取群详情失败:", e);
			return c.json({
				success: false,
				message: "获取群详情失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/uid", async (c) => {
		try {
			const { uin, groupCode } = c.req.query();
			if (!uin) return c.json({
				success: false,
				message: "缺少 uin 参数"
			}, 400);
			const uid = await ctx.ntUserApi.getUidByUin(+uin, groupCode ? +groupCode : void 0);
			return c.json({
				success: true,
				data: uid
			});
		} catch (e) {
			ctx.logger.error("uin → uid 失败:", e);
			return c.json({
				success: false,
				message: "uin → uid 失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/uin", async (c) => {
		try {
			const { uid } = c.req.query();
			if (!uid) return c.json({
				success: false,
				message: "缺少 uid 参数"
			}, 400);
			const uin = await ctx.ntUserApi.getUinByUid(uid);
			return c.json({
				success: true,
				data: uin?.toString() ?? ""
			});
		} catch (e) {
			ctx.logger.error("uid → uin 失败:", e);
			return c.json({
				success: false,
				message: "uid → uin 失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/user", async (c) => {
		try {
			const { uid, uin } = c.req.query();
			if (!uid && !uin) return c.json({
				success: false,
				message: "需要 uid 或 uin 参数之一"
			}, 400);
			const user = uid ? await ctx.ntUserApi.getUserByUid(uid) : await ctx.ntUserApi.getUserByUin(+uin);
			return c.json({
				success: true,
				data: serializeResult(user)
			});
		} catch (e) {
			ctx.logger.error("获取用户详情失败:", e);
			return c.json({
				success: false,
				message: "获取用户详情失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/notifications.ts
function createNotificationRoutes(ctx) {
	const router = new Hono();
	router.get("/notifications/group", async (c) => {
		try {
			const { notifications } = await ctx.ntGroupApi.getGroupNotifications(false, 50);
			const enriched = await Promise.all(notifications.map(async (notify) => {
				const user1Uin = notify.user1.uid ? await ctx.ntUserApi.getUinByUid(notify.user1.uid).catch(() => "") : "";
				const user2Uin = notify.user2?.uid ? await ctx.ntUserApi.getUinByUid(notify.user2.uid).catch(() => "") : "";
				return {
					seq: notify.sequence.toString(),
					notifyType: notify.type,
					status: notify.requestState,
					doubt: false,
					group: {
						groupCode: notify.group.groupCode.toString(),
						groupName: notify.group.groupName
					},
					user1: {
						...notify.user1,
						uin: user1Uin.toString()
					},
					user2: {
						...notify.user2,
						uin: user2Uin.toString()
					},
					postscript: notify.comment ?? "",
					actionTime: notify.time ?? "0",
					flag: encodeGroupRequestFlag(notify.group.groupCode, notify.sequence, notify.type, false)
				};
			}));
			return c.json({
				success: true,
				data: enriched
			});
		} catch (e) {
			ctx.logger.error("获取群通知失败:", e);
			return c.json({
				success: false,
				message: "获取群通知失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/notifications/friend", async (c) => {
		try {
			const buddyReqs = (await ctx.ntFriendApi.getFriendRequests(50)).filter((reqItem) => !reqItem.isInitiator && reqItem.state !== FriendReqType.MeInitiatorWaitPeerConfirm);
			const enriched = await Promise.all(buddyReqs.map(async (reqItem) => {
				const uin = await ctx.ntUserApi.getUinByUid(reqItem.friendUid).catch(() => "");
				const nick = await ctx.ntUserApi.getUserByUid(reqItem.friendUid).then((e) => e.nick).catch(() => "");
				return {
					friendUid: reqItem.friendUid,
					friendUin: uin,
					friendNick: nick,
					reqTime: reqItem.timestamp.toString(),
					extWords: reqItem.comment,
					isDecide: ![FriendReqType.PeerInitiator, FriendReqType.MeInitiatorWaitPeerConfirm].includes(reqItem.state),
					reqType: reqItem.state,
					addSource: reqItem.source,
					flag: reqItem.friendUid
				};
			}));
			return c.json({
				success: true,
				data: enriched
			});
		} catch (e) {
			ctx.logger.error("获取好友申请失败:", e);
			return c.json({
				success: false,
				message: "获取好友申请失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/notifications/friend/doubt", async (c) => {
		try {
			const enriched = (await ctx.ntFriendApi.getDoubtFriendRequests(50)).map((item) => ({
				uid: item.sourceUid,
				nick: item.sourceNickname,
				reqTime: item.timestamp.toString(),
				msg: item.comment,
				source: item.source,
				reason: item.warningInfo,
				groupCode: item.groupCode,
				flag: item.sourceUid
			}));
			return c.json({
				success: true,
				data: enriched
			});
		} catch (e) {
			ctx.logger.error("获取被过滤好友申请失败:", e);
			return c.json({
				success: false,
				message: "获取被过滤好友申请失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/notifications/friend/doubt/approve", async (c) => {
		try {
			const { uid } = await c.req.json();
			if (!uid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntFriendApi.approvalDoubtFriendRequest(uid);
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("处理被过滤好友申请失败:", e);
			return c.json({
				success: false,
				message: "处理被过滤好友申请失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/notifications/group/handle", async (c) => {
		try {
			const { flag, action, reason } = await c.req.json();
			if (!flag || !action) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const decoded = decodeGroupRequestFlag(flag);
			await ctx.ntGroupApi.setGroupRequest(decoded.doubt, decoded.groupCode, decoded.seq, decoded.type, action === "approve", reason);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("处理群通知失败:", e);
			return c.json({
				success: false,
				message: "处理群通知失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/notifications/friend/handle", async (c) => {
		try {
			const { flag, action } = await c.req.json();
			if (!flag || !action) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntFriendApi.approvalFriendRequest(flag, action === "approve");
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("处理好友申请失败:", e);
			return c.json({
				success: false,
				message: "处理好友申请失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/chats.ts
/**
* 列表型查询：好友 / 群组 / 置顶。
* 全部 GET，没有副作用，直接返 NT API 内部 shape（serializeResult 处理 Map）。
*/
function createChatsRoutes(ctx) {
	const router = new Hono();
	router.get("/friends", async (c) => {
		try {
			const result = await ctx.ntFriendApi.getFriends(true);
			return c.json({
				success: true,
				data: serializeResult(result)
			});
		} catch (e) {
			ctx.logger.error("获取好友列表失败:", e);
			return c.json({
				success: false,
				message: "获取好友列表失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/groups", async (c) => {
		try {
			const groups = await ctx.ntGroupApi.getGroups(false);
			return c.json({
				success: true,
				data: serializeResult(groups)
			});
		} catch (e) {
			ctx.logger.error("获取群列表失败:", e);
			return c.json({
				success: false,
				message: "获取群列表失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/pins", async (c) => {
		try {
			const pins = await ctx.ntMsgApi.getPins();
			return c.json({
				success: true,
				data: serializeResult(pins)
			});
		} catch (e) {
			ctx.logger.error("获取置顶列表失败:", e);
			return c.json({
				success: false,
				message: "获取置顶列表失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/actions.ts
/**
* 修改型操作：群管理 / 好友 / 戳一戳。
* 全部 POST，body 是 JSON。webui 端点专用，不暴露任意 NT API 反射。
*
* 设计：
*  - 路由按 group/* 和 friend/* 分组，每个端点一个明确的语义动作
*  - errCode/result 校验放在 BE 端，FE 不再需要重复判断
*/
function createActionsRoutes(ctx) {
	const router = new Hono();
	router.post("/group/kick", async (c) => {
		try {
			const { groupCode, uid, refuseForever } = await c.req.json();
			if (!groupCode || !uid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.kickGroupMember(+groupCode, [uid], refuseForever ?? false, "");
			if (res?.errorCode !== 0) return c.json({
				success: false,
				message: res?.errorMsg || "踢出失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("踢人失败:", e);
			return c.json({
				success: false,
				message: "踢人失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/ban", async (c) => {
		try {
			const { groupCode, uid, duration } = await c.req.json();
			if (!groupCode || !uid || duration === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntGroupApi.muteGroupMember(+groupCode, [{
				uid,
				duration
			}]);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("禁言失败:", e);
			return c.json({
				success: false,
				message: "禁言失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/member-role", async (c) => {
		try {
			const { groupCode, uid, isAdmin } = await c.req.json();
			if (!groupCode || !uid || isAdmin === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntGroupApi.setGroupMemberAdmin(+groupCode, uid, isAdmin);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("设置管理员失败:", e);
			return c.json({
				success: false,
				message: "设置管理员失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/quit", async (c) => {
		try {
			const { groupCode } = await c.req.json();
			if (!groupCode) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntGroupApi.quitGroup(+groupCode);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("退群失败:", e);
			return c.json({
				success: false,
				message: "退群失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/set-top", async (c) => {
		try {
			const { groupCode, isTop } = await c.req.json();
			if (!groupCode || isTop === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntGroupApi.setGroupPin(+groupCode, isTop);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("设置群置顶失败:", e);
			return c.json({
				success: false,
				message: "设置群置顶失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/msg-mask", async (c) => {
		try {
			const { groupCode, msgMask } = await c.req.json();
			if (!groupCode || msgMask === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntGroupApi.setGroupMsgMask(+groupCode, msgMask);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("设置群消息接收方式失败:", e);
			return c.json({
				success: false,
				message: "设置群消息接收方式失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/special-title", async (c) => {
		try {
			const { groupCode, uid, title } = await c.req.json();
			if (!groupCode || !uid || title === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntGroupApi.setGroupMemberSpecialTitle(+groupCode, uid, title);
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("设置群头衔失败:", e);
			return c.json({
				success: false,
				message: "设置群头衔失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group/poke", async (c) => {
		try {
			const { groupCode, uin } = await c.req.json();
			if (!groupCode || !uin) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntGroupApi.sendGroupNudge(+groupCode, +uin);
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("群戳一戳失败:", e);
			return c.json({
				success: false,
				message: "群戳一戳失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/friend/delete", async (c) => {
		try {
			const { uid } = await c.req.json();
			if (!uid) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntFriendApi.deleteFriend(uid);
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("删除好友失败:", e);
			return c.json({
				success: false,
				message: "删除好友失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/friend/set-top", async (c) => {
		try {
			const { uid, isTop } = await c.req.json();
			if (!uid || isTop === void 0) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			await ctx.ntFriendApi.setFriendPin(uid, isTop);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("设置好友置顶失败:", e);
			return c.json({
				success: false,
				message: "设置好友置顶失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/friend/poke", async (c) => {
		try {
			const { uin } = await c.req.json();
			if (!uin) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const result = await ctx.ntFriendApi.sendFriendNudge(+uin, false);
			if (result.errorCode !== 0) return c.json({
				success: false,
				message: result.errorMsg
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("好友戳一戳失败:", e);
			return c.json({
				success: false,
				message: "好友戳一戳失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/groupFiles.ts
/**
* 群文件管理路由 (WebQQ 群文件面板用). 全部薄封装 ctx.ntGroupApi / ctx.ntFileApi,
* 协议层已就绪, 走抽象 ctx.qqProtocol, PMHQ / Direct 两模式通用.
*
* 上传的文件字节复用现成的 POST /upload-file (upload.ts): FE 先传文件拿 filePath,
* 再调本文件的 /group-file/upload 走 highway 上传 + feed 到群.
*/
function createGroupFilesRoutes(ctx) {
	const router = new Hono();
	router.get("/group-files", async (c) => {
		try {
			const { groupCode, folderId } = c.req.query();
			if (!groupCode) return c.json({
				success: false,
				message: "缺少 groupCode 参数"
			}, 400);
			const dir = folderId || "/";
			const items = [];
			let nextIndex;
			while (nextIndex !== 0) {
				const res = await ctx.ntGroupApi.getGroupFileList(+groupCode, dir, nextIndex ?? 0, 100);
				if (res.retCode !== 0) return c.json({
					success: false,
					message: res.clientWording || "获取群文件列表失败"
				}, 500);
				items.push(...res.items);
				nextIndex = res.nextIndex;
			}
			const files = items.filter((i) => i.fileInfo).map((i) => {
				const f = i.fileInfo;
				return {
					fileId: f.fileId,
					fileName: f.fileName,
					fileSize: Number(f.fileSize),
					busId: f.busId,
					uploadTime: f.uploadedTime,
					deadTime: f.expireTime,
					modifyTime: f.modifiedTime,
					downloadTimes: f.downloadedTimes,
					uploaderUin: String(f.uploaderUin),
					uploaderName: f.uploaderName
				};
			});
			const folders = items.filter((i) => i.folderInfo).map((i) => {
				const d = i.folderInfo;
				return {
					folderId: d.folderId,
					folderName: d.folderName,
					createTime: d.createTime,
					creatorUin: String(d.createUin),
					creatorName: d.creatorName,
					fileCount: d.totalFileCount,
					modifyTime: d.modifyTime
				};
			});
			return c.json({
				success: true,
				data: {
					files,
					folders
				}
			});
		} catch (e) {
			ctx.logger.error("获取群文件列表失败:", e);
			return c.json({
				success: false,
				message: "获取群文件列表失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/group-file-space", async (c) => {
		try {
			const { groupCode } = c.req.query();
			if (!groupCode) return c.json({
				success: false,
				message: "缺少 groupCode 参数"
			}, 400);
			const [count, space] = await Promise.all([ctx.ntGroupApi.getGroupFileCount(+groupCode), ctx.ntGroupApi.getGroupFileSpace(+groupCode)]);
			return c.json({
				success: true,
				data: {
					fileCount: count.fileCount,
					limitCount: count.limitCount,
					usedSpace: space.usedSpace,
					totalSpace: space.totalSpace
				}
			});
		} catch (e) {
			ctx.logger.error("获取群文件空间失败:", e);
			return c.json({
				success: false,
				message: "获取群文件空间失败",
				error: e.message
			}, 500);
		}
	});
	router.get("/group-file-url", async (c) => {
		try {
			const { groupCode, fileId } = c.req.query();
			if (!groupCode || !fileId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntFileApi.getFileUrl(fileId, true, +groupCode);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.retMsg || "获取下载链接失败"
			}, 500);
			return c.json({
				success: true,
				data: { url: res.url }
			});
		} catch (e) {
			ctx.logger.error("获取群文件下载链接失败:", e);
			return c.json({
				success: false,
				message: "获取群文件下载链接失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-file/upload", async (c) => {
		try {
			const { groupCode, filePath, fileName, folderId } = await c.req.json();
			if (!groupCode || !filePath || !fileName) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			if (fileName.includes("/") || fileName.includes("\\")) return c.json({
				success: false,
				message: `文件名 ${fileName} 不合法`
			}, 400);
			const info = await ctx.ntFileApi.uploadGroupFile(+groupCode, filePath, fileName, folderId || "/");
			const result = await ctx.ntMsgApi.sendGroupFileMessage(+groupCode, info.fileId, info.busId);
			if (result.retCode !== 0) return c.json({
				success: false,
				message: result.clientWording || "发送群文件失败"
			}, 500);
			return c.json({
				success: true,
				data: { fileId: info.fileId }
			});
		} catch (e) {
			ctx.logger.error("上传群文件失败:", e);
			return c.json({
				success: false,
				message: "上传群文件失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-file/delete", async (c) => {
		try {
			const { groupCode, fileId, busId } = await c.req.json();
			if (!groupCode || !fileId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.deleteGroupFile(+groupCode, fileId, busId ?? 102);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.clientWording || "删除群文件失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("删除群文件失败:", e);
			return c.json({
				success: false,
				message: "删除群文件失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-file/rename", async (c) => {
		try {
			const { groupCode, fileId, parentFolderId, newName } = await c.req.json();
			if (!groupCode || !fileId || !newName) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.renameGroupFile(+groupCode, fileId, parentFolderId || "/", newName);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.clientWording || "重命名群文件失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("重命名群文件失败:", e);
			return c.json({
				success: false,
				message: "重命名群文件失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-folder/create", async (c) => {
		try {
			const { groupCode, folderName } = await c.req.json();
			if (!groupCode || !folderName) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.createGroupFolder(+groupCode, folderName);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.clientWording || "新建文件夹失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("新建群文件夹失败:", e);
			return c.json({
				success: false,
				message: "新建文件夹失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-folder/delete", async (c) => {
		try {
			const { groupCode, folderId } = await c.req.json();
			if (!groupCode || !folderId) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.deleteGroupFolder(+groupCode, folderId);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.clientWording || "删除文件夹失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("删除群文件夹失败:", e);
			return c.json({
				success: false,
				message: "删除文件夹失败",
				error: e.message
			}, 500);
		}
	});
	router.post("/group-folder/rename", async (c) => {
		try {
			const { groupCode, folderId, newName } = await c.req.json();
			if (!groupCode || !folderId || !newName) return c.json({
				success: false,
				message: "缺少必要参数"
			}, 400);
			const res = await ctx.ntGroupApi.renameGroupFolder(+groupCode, folderId, newName);
			if (res.retCode !== 0) return c.json({
				success: false,
				message: res.clientWording || "重命名文件夹失败"
			}, 500);
			return c.json({ success: true });
		} catch (e) {
			ctx.logger.error("重命名群文件夹失败:", e);
			return c.json({
				success: false,
				message: "重命名文件夹失败",
				error: e.message
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/webqq/index.ts
function createWebQQRoutes(ctx, options) {
	const router = new Hono();
	const { uploadDir, sseClients, createPicElement } = options;
	router.route("/", createMessagesRoutes(ctx, createPicElement));
	router.route("/", createUploadRoutes(ctx, uploadDir));
	router.route("/", createProxyRoutes(ctx));
	router.route("/", createMembersRoutes(ctx));
	router.route("/", createNotificationRoutes(ctx));
	router.route("/", createChatsRoutes(ctx));
	router.route("/", createActionsRoutes(ctx));
	router.route("/", createGroupFilesRoutes(ctx));
	router.get("/events", async (c) => {
		return streamSSE(c, async (stream) => {
			stream.writeSSE({
				data: "{}",
				event: "connected"
			});
			sseClients.add(stream);
			stream.onAbort(() => {
				sseClients.delete(stream);
			});
			return new Promise((resolve) => {
				stream.onAbort(resolve);
			});
		});
	});
	return router;
}
//#endregion
//#region src/webui/BE/routes/email.ts
function createEmailRoutes(ctx) {
	const router = new Hono();
	const getEmail = () => ctx.get("emailNotification");
	router.get("/config", async (c) => {
		try {
			const emailService = getEmail();
			if (!emailService) return c.json({
				success: false,
				message: "邮件服务未初始化，请等待登录完成"
			}, 503);
			const config = emailService.getConfigManager().getConfig();
			const maskedConfig = {
				...config,
				smtp: {
					...config.smtp,
					auth: {
						...config.smtp.auth,
						pass: config.smtp.auth.pass ? "********" : ""
					}
				}
			};
			return c.json({
				success: true,
				data: maskedConfig
			});
		} catch (error) {
			ctx.logger?.error("[EmailAPI] Failed to get email config:", error);
			return c.json({
				success: false,
				message: error.message || "获取邮件配置失败"
			}, 500);
		}
	});
	router.post("/config", async (c) => {
		try {
			const emailService = getEmail();
			if (!emailService) return c.json({
				success: false,
				message: "邮件服务未初始化，请等待登录完成"
			}, 503);
			const emailConfig = await c.req.json();
			if (!emailConfig) return c.json({
				success: false,
				message: "邮件配置不能为空"
			}, 400);
			const configManager = emailService.getConfigManager();
			const currentConfig = configManager.getConfig();
			if (emailConfig.smtp.auth.pass === "********" || emailConfig.smtp.auth.pass === "") emailConfig.smtp.auth.pass = currentConfig.smtp.auth.pass;
			const validation = configManager.validateConfig(emailConfig);
			if (!validation.valid) return c.json({
				success: false,
				message: `配置验证失败：${validation.errors.join(", ")}`
			}, 400);
			await configManager.saveConfig(emailConfig);
			ctx.parallel("llbot/email-config-updated", emailConfig);
			return c.json({
				success: true,
				message: "邮件配置保存成功"
			});
		} catch (error) {
			ctx.logger?.error("[EmailAPI] Failed to save email config:", error);
			return c.json({
				success: false,
				message: error.message || "保存邮件配置失败"
			}, 500);
		}
	});
	router.post("/test", async (c) => {
		try {
			const emailService = getEmail();
			if (!emailService) return c.json({
				success: false,
				message: "邮件服务未初始化，请等待登录完成"
			}, 503);
			const { config: testConfig } = await c.req.json();
			let emailConfig;
			if (testConfig) {
				emailConfig = testConfig;
				const currentConfig = emailService.getConfigManager().getConfig();
				if (emailConfig.smtp.auth.pass === "********" || emailConfig.smtp.auth.pass === "") emailConfig.smtp.auth.pass = currentConfig.smtp.auth.pass;
			} else emailConfig = emailService.getConfigManager().getConfig();
			const configManager = emailService.getConfigManager();
			const validation = configManager.validateConfig(emailConfig);
			if (!validation.valid) return c.json({
				success: false,
				message: validation.errors.join(", ")
			}, 400);
			const tempConfigManager = new configManager.constructor("", ctx.logger);
			tempConfigManager["config"] = emailConfig;
			const result = await new (emailService.getEmailService()).constructor(tempConfigManager, ctx.logger).sendTestEmail();
			if (result.success) return c.json({
				success: true,
				message: "测试邮件发送成功",
				messageId: result.messageId
			});
			else return c.json({
				success: false,
				message: result.error || "测试邮件发送失败"
			}, 400);
		} catch (error) {
			ctx.logger?.error("[EmailAPI] Failed to send test email:", error);
			return c.json({
				success: false,
				message: error.message || "测试邮件发送失败"
			}, 500);
		}
	});
	return router;
}
//#endregion
//#region node_modules/@hono/node-server/dist/utils/stream.mjs
var pr54206Applied = () => {
	const [major, minor] = versions.node.split(".").map((component) => parseInt(component));
	return major >= 23 || major === 22 && minor >= 7 || major === 20 && minor >= 18;
};
var useReadableToWeb = pr54206Applied();
var createStreamBody = (stream, useNativeReadableToWeb = useReadableToWeb) => {
	if (useNativeReadableToWeb) return Readable.toWeb(stream);
	let controller;
	let settled = false;
	const cleanup = () => {
		stream.off("data", onData);
		stream.off("error", onError);
		stream.off("end", onTerminate);
		stream.off("close", onTerminate);
	};
	const settle = (callback) => {
		if (settled) return;
		settled = true;
		cleanup();
		callback?.();
	};
	const onData = (chunk) => {
		if (settled || !controller) return;
		controller.enqueue(chunk);
		if ((controller.desiredSize ?? 0) <= 0) stream.pause();
	};
	const onError = (error) => {
		settle(() => {
			controller?.error(error);
		});
	};
	const onTerminate = () => {
		settle(() => {
			controller?.close();
		});
	};
	return new ReadableStream({
		start(streamController) {
			controller = streamController;
			stream.on("data", onData);
			stream.on("error", onError);
			stream.on("end", onTerminate);
			stream.on("close", onTerminate);
			stream.pause();
		},
		pull() {
			if (!settled) stream.resume();
		},
		cancel() {
			settle();
			const ignoreError = () => {};
			stream.on("error", ignoreError);
			stream.once("close", () => stream.off("error", ignoreError));
			stream.destroy();
		}
	});
};
//#endregion
//#region node_modules/hono/dist/utils/mime.js
var getMimeType = (filename, mimes = baseMimes) => {
	const match = filename.match(/\.([a-zA-Z0-9]+?)$/);
	if (!match) return;
	return mimes[match[1].toLowerCase()];
};
var baseMimes = {
	aac: "audio/aac",
	avi: "video/x-msvideo",
	avif: "image/avif",
	av1: "video/av1",
	bin: "application/octet-stream",
	bmp: "image/bmp",
	css: "text/css; charset=utf-8",
	csv: "text/csv; charset=utf-8",
	eot: "application/vnd.ms-fontobject",
	epub: "application/epub+zip",
	gif: "image/gif",
	gz: "application/gzip",
	htm: "text/html; charset=utf-8",
	html: "text/html; charset=utf-8",
	ico: "image/x-icon",
	ics: "text/calendar; charset=utf-8",
	jpeg: "image/jpeg",
	jpg: "image/jpeg",
	js: "text/javascript; charset=utf-8",
	json: "application/json",
	jsonld: "application/ld+json",
	map: "application/json",
	mid: "audio/x-midi",
	midi: "audio/x-midi",
	mjs: "text/javascript; charset=utf-8",
	mp3: "audio/mpeg",
	mp4: "video/mp4",
	mpeg: "video/mpeg",
	oga: "audio/ogg",
	ogv: "video/ogg",
	ogx: "application/ogg",
	opus: "audio/opus",
	otf: "font/otf",
	pdf: "application/pdf",
	png: "image/png",
	rtf: "application/rtf",
	svg: "image/svg+xml; charset=utf-8",
	tif: "image/tiff",
	tiff: "image/tiff",
	ts: "video/mp2t",
	ttf: "font/ttf",
	txt: "text/plain; charset=utf-8",
	wasm: "application/wasm",
	webm: "video/webm",
	weba: "audio/webm",
	webmanifest: "application/manifest+json",
	webp: "image/webp",
	woff: "font/woff",
	woff2: "font/woff2",
	xhtml: "application/xhtml+xml; charset=utf-8",
	xml: "application/xml; charset=utf-8",
	zip: "application/zip",
	"3gp": "video/3gpp",
	"3g2": "video/3gpp2",
	gltf: "model/gltf+json",
	glb: "model/gltf-binary"
};
//#endregion
//#region node_modules/@hono/node-server/dist/serve-static.mjs
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
var ENCODINGS = {
	br: ".br",
	zstd: ".zst",
	gzip: ".gz"
};
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
var getStats = (path) => {
	let stats;
	try {
		stats = statSync(path);
	} catch {}
	return stats;
};
var BYTE_RANGE_PATTERN = /^(?:bytes=)?(?!-$)(\d*)-(\d*)$/;
var parseByteRange = (range) => {
	const match = range.match(BYTE_RANGE_PATTERN);
	if (!match) return;
	const [, start, end] = match;
	if (start === "") return {
		type: "suffix",
		length: Number(end)
	};
	if (end === "") return {
		type: "open-ended",
		start: Number(start)
	};
	return {
		type: "bounded",
		start: Number(start),
		end: Number(end)
	};
};
var resolveByteRange = (spec, size) => {
	if (size === 0) return;
	if (spec.type === "suffix") {
		if (spec.length === 0) return;
		return {
			start: Math.max(size - spec.length, 0),
			end: size - 1
		};
	}
	const end = spec.type === "bounded" ? Math.min(spec.end, size - 1) : size - 1;
	if (spec.start >= size || spec.start > end) return;
	return {
		start: spec.start,
		end
	};
};
var tryDecode = (str, decoder) => {
	try {
		return decoder(str);
	} catch {
		return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
			try {
				return decoder(match);
			} catch {
				return match;
			}
		});
	}
};
var tryDecodeURI = (str) => tryDecode(str, decodeURI);
var serveStatic = (options = { root: "" }) => {
	const root = options.root || "";
	const optionPath = options.path;
	if (root !== "" && !existsSync(root)) console.error(`serveStatic: root path '${root}' is not found, are you sure it's correct?`);
	return async (c, next) => {
		if (c.finalized) return next();
		let filename;
		if (optionPath) filename = optionPath;
		else try {
			filename = tryDecodeURI(c.req.path);
			if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}|\\/.test(filename)) throw new Error();
		} catch {
			await options.onNotFound?.(c.req.path, c);
			return next();
		}
		let path = join(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename, c) : filename);
		let stats = getStats(path);
		if (stats && stats.isDirectory()) {
			const indexFile = options.index ?? "index.html";
			path = join(path, indexFile);
			stats = getStats(path);
		}
		if (!stats) {
			await options.onNotFound?.(path, c);
			return next();
		}
		const mimeType = getMimeType(path);
		c.header("Content-Type", mimeType || "application/octet-stream");
		if (options.precompressed && (!mimeType || mimeType === "application/octet-stream" || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
			const acceptEncodingSet = new Set(c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim()));
			for (const encoding of ENCODINGS_ORDERED_KEYS) {
				if (!acceptEncodingSet.has(encoding)) continue;
				const precompressedStats = getStats(path + ENCODINGS[encoding]);
				if (precompressedStats) {
					c.header("Content-Encoding", encoding);
					c.header("Vary", "Accept-Encoding", { append: true });
					stats = precompressedStats;
					path = path + ENCODINGS[encoding];
					break;
				}
			}
		}
		let result;
		const size = stats.size;
		const range = c.req.header("range") || "";
		c.header("Last-Modified", stats.mtime.toUTCString());
		if (c.req.method == "HEAD" || c.req.method == "OPTIONS") {
			c.header("Content-Length", size.toString());
			c.status(200);
			result = c.body(null);
		} else if (!range) {
			c.header("Content-Length", size.toString());
			result = c.body(createStreamBody(createReadStream(path)), 200);
		} else {
			c.header("Accept-Ranges", "bytes");
			const resolvedRange = resolveByteRange(parseByteRange(range) ?? {
				type: "open-ended",
				start: 0
			}, size);
			if (!resolvedRange) {
				c.header("Content-Range", `bytes */${size}`);
				result = c.body(null, 416);
			} else {
				const { start, end } = resolvedRange;
				const chunkSize = end - start + 1;
				const stream = createReadStream(path, {
					start,
					end
				});
				c.header("Content-Length", chunkSize.toString());
				c.header("Content-Range", `bytes ${start}-${end}/${size}`);
				result = c.body(createStreamBody(stream), 206);
			}
		}
		await options.onFound?.(path, c);
		return result;
	};
};
//#endregion
//#region src/webui/BE/server.ts
var feDistPath = path$1.resolve(import.meta.dirname, "webui/");
var LAZY_SERVICES = /* @__PURE__ */ new Set([
	"ntGroupApi",
	"ntUserApi",
	"ntMsgApi",
	"ntFileApi",
	"ntFriendApi",
	"ntSystemApi",
	"ntWebApi",
	"store",
	"config",
	"app",
	"emailNotification"
]);
function lazyServiceContext(ctx) {
	return new Proxy(ctx, { get(target, prop) {
		if (typeof prop === "string" && LAZY_SERVICES.has(prop)) return target.get(prop);
		const v = Reflect.get(target, prop, target);
		return typeof v === "function" ? v.bind(target) : v;
	} });
}
var WebuiServer = class extends Service {
	config;
	static inject = ["qqProtocol", "ntLoginApi"];
	server = null;
	app = new Hono();
	currentPort;
	port = void 0;
	sseClients = /* @__PURE__ */ new Set();
	uploadDir;
	async [Service.init]() {
		await this.start();
		return noop;
	}
	constructor(ctx, config) {
		super(ctx, "webuiServer");
		this.config = config;
		this.uploadDir = path$1.join(TEMP_DIR, "webqq-uploads");
		if (!existsSync(this.uploadDir)) mkdirSync(this.uploadDir, { recursive: true });
		this.initServer();
		this.setupMessageListener();
		this.setupConfigListener();
	}
	setupConfigListener() {
		this.ctx.on("llob/config-updated", (newConfig) => {
			const oldConfig = { ...this.config };
			this.setConfig(newConfig);
			const forcePort = oldConfig.port === newConfig.webui?.port ? this.currentPort : void 0;
			if (oldConfig.host != newConfig.webui?.host || oldConfig.enable != newConfig.webui?.enable || oldConfig.port != newConfig.webui?.port) {
				this.ctx.logger.info("WebUI 配置已更新:", this.config);
				setTimeout(() => this.restart(forcePort), 1e3);
			}
		});
	}
	initServer() {
		this.app.use("/api/*", authMiddleware);
		const ctx = lazyServiceContext(this.ctx);
		this.app.route("/api", createConfigRoutes(ctx));
		this.app.route("/api", createAuthTokenRoutes());
		this.app.route("/api", createLoginRoutes(ctx));
		this.app.route("/api", createDashboardRoutes(ctx));
		this.app.route("/api", createLogsRoutes(ctx));
		this.app.route("/api/email", createEmailRoutes(ctx));
		this.app.route("/api/webqq", createWebQQRoutes(ctx, {
			uploadDir: this.uploadDir,
			sseClients: this.sseClients,
			createPicElement: this.createPicElement.bind(this)
		}));
		this.app.use("/*", serveStatic({ root: feDistPath }));
		this.app.get("/", async (c) => {
			const filePath = path$1.join(feDistPath, "index.html");
			return c.html((await readFile(filePath)).toString());
		});
	}
	async createPicElement(imagePath) {
		try {
			return await SendElement.pic(this.ctx, imagePath);
		} catch (e) {
			this.ctx.logger.error("创建图片元素失败:", e);
			return null;
		}
	}
	broadcastMessage(event, data) {
		const serializedData = serializeResult(data);
		const message = `event: ${event}\ndata: ${JSON.stringify(serializedData)}\n\n`;
		for (const client of this.sseClients) client.write(message);
	}
	setupMessageListener() {
		this.ctx.on("nt/message-created", async (data) => {
			if (this.sseClients.size === 0) return;
			await this.fillPeerUin(data.message);
			this.broadcastMessage("message", {
				type: "message-created",
				data: data.message
			});
		});
		this.ctx.on("nt/message-sent", async (data) => {
			if (this.sseClients.size === 0) return;
			await this.fillPeerUin(data.message);
			this.broadcastMessage("message", {
				type: "message-sent",
				data: data.message
			});
		});
		this.ctx.on("nt/message-deleted", async (data) => {
			if (this.sseClients.size === 0) return;
			this.broadcastMessage("message", {
				type: "message-deleted",
				data: {
					msgId: data.msgId,
					msgSeq: data.msgSeq.toString(),
					chatType: data.chatType,
					peerUid: data.peerUid,
					peerUin: data.peerUin.toString(),
					operatorUid: data.operatorUid,
					operatorNick: "",
					isSelfOperate: data.senderUin === data.operatorUin,
					wording: data.displaySuffix
				}
			});
		});
		this.ctx.on("nt/group-message-reaction", async (data) => {
			if (this.sseClients.size === 0) return;
			let userName = "";
			try {
				userName = await this.ctx.store.getGroupMemberCardName(data.groupCode, data.operatorUin) || "";
			} catch {}
			this.broadcastMessage("message", {
				type: "emoji-reaction",
				data: {
					groupCode: data.groupCode.toString(),
					msgSeq: data.msgSeq.toString(),
					emojiId: data.faceId.toString(),
					userId: data.operatorUin.toString(),
					userName,
					isAdd: data.isAdd
				}
			});
		});
	}
	async fillPeerUin(message) {
		if (message.chatType === ChatType.C2C && (!message.peerUin || message.peerUin === 0) && message.peerUid) {
			const uin = await this.ctx.get("ntUserApi")?.getUinByUid(message.peerUid);
			if (uin) message.peerUin = uin;
		}
	}
	getHostPort() {
		return {
			host: this.config.host,
			port: this.config.port
		};
	}
	async startServer(forcePort) {
		const { host, port } = this.getHostPort();
		const targetPort = forcePort !== void 0 ? forcePort : await getAvailablePort(port);
		this.server = serve({
			fetch: this.app.fetch,
			port: targetPort,
			hostname: host
		}, () => {
			this.currentPort = targetPort;
			const displayHost = host || "0.0.0.0";
			this.ctx.logger.info(`Webui 服务器已启动 ${displayHost}:${targetPort}`);
		});
		return targetPort;
	}
	stop() {
		return new Promise((resolve) => {
			if (this.server) this.server.close((err) => {
				if (err) this.ctx.logger.error(`Webui 停止时出错:`, err);
				else this.ctx.logger.info(`Webui 服务器已停止`);
				this.server = null;
				resolve();
			});
			else {
				this.ctx.logger.info(`Webui 服务器未运行`);
				resolve();
			}
		});
	}
	async restart(forcePort) {
		await this.stop();
		await new Promise((resolve) => setTimeout(resolve, 1e3));
		await this.startWithPort(forcePort);
	}
	setConfig(newConfig) {
		this.config = newConfig.webui;
	}
	async start() {
		if (!this.config?.enable) return;
		this.port = await this.startServer();
	}
	async startWithPort(forcePort) {
		if (!this.config?.enable) return;
		this.port = await this.startServer(forcePort);
	}
};
//#endregion
//#region node_modules/nodemailer/lib/punycode/index.js
var require_punycode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/** Highest positive signed 32-bit float value */
	var maxInt = 2147483647;
	/** Bootstring parameters */
	var base = 36;
	var tMin = 1;
	var tMax = 26;
	var skew = 38;
	var damp = 700;
	var initialBias = 72;
	var initialN = 128;
	var delimiter = "-";
	/** Regular expressions */
	var regexPunycode = /^xn--/;
	var regexNonASCII = /[^\0-\x7F]/;
	var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g;
	/** Error messages */
	var errors = {
		overflow: "Overflow: input needs wider integers to process",
		"not-basic": "Illegal input >= 0x80 (not a basic code point)",
		"invalid-input": "Invalid input"
	};
	/** Convenience shortcuts */
	var baseMinusTMin = 35;
	var floor = Math.floor;
	var stringFromCharCode = String.fromCharCode;
	/**
	* A generic error utility function.
	* @private
	* @param {String} type The error type.
	* @returns {Error} Throws a `RangeError` with the applicable error message.
	*/
	function error(type) {
		throw new RangeError(errors[type]);
	}
	/**
	* A generic `Array#map` utility function.
	* @private
	* @param {Array} array The array to iterate over.
	* @param {Function} callback The function that gets called for every array
	* item.
	* @returns {Array} A new array of values returned by the callback function.
	*/
	function map(array, callback) {
		const result = [];
		let length = array.length;
		while (length--) result[length] = callback(array[length]);
		return result;
	}
	/**
	* A simple `Array#map`-like wrapper to work with domain name strings or email
	* addresses.
	* @private
	* @param {String} domain The domain name or email address.
	* @param {Function} callback The function that gets called for every
	* character.
	* @returns {String} A new string of characters returned by the callback
	* function.
	*/
	function mapDomain(domain, callback) {
		const parts = domain.split("@");
		let result = "";
		if (parts.length > 1) {
			result = parts[0] + "@";
			domain = parts[1];
		}
		domain = domain.replace(regexSeparators, ".");
		const encoded = map(domain.split("."), callback).join(".");
		return result + encoded;
	}
	/**
	* Creates an array containing the numeric code points of each Unicode
	* character in the string. While JavaScript uses UCS-2 internally,
	* this function will convert a pair of surrogate halves (each of which
	* UCS-2 exposes as separate characters) into a single code point,
	* matching UTF-16.
	* @see `punycode.ucs2.encode`
	* @see <https://mathiasbynens.be/notes/javascript-encoding>
	* @memberOf punycode.ucs2
	* @name decode
	* @param {String} string The Unicode input string (UCS-2).
	* @returns {Array} The new array of code points.
	*/
	function ucs2decode(string) {
		const output = [];
		let counter = 0;
		const length = string.length;
		while (counter < length) {
			const value = string.charCodeAt(counter++);
			if (value >= 55296 && value <= 56319 && counter < length) {
				const extra = string.charCodeAt(counter++);
				if ((extra & 64512) == 56320) output.push(((value & 1023) << 10) + (extra & 1023) + 65536);
				else {
					output.push(value);
					counter--;
				}
			} else output.push(value);
		}
		return output;
	}
	/**
	* Creates a string based on an array of numeric code points.
	* @see `punycode.ucs2.decode`
	* @memberOf punycode.ucs2
	* @name encode
	* @param {Array} codePoints The array of numeric code points.
	* @returns {String} The new Unicode string (UCS-2).
	*/
	var ucs2encode = (codePoints) => String.fromCodePoint(...codePoints);
	/**
	* Converts a basic code point into a digit/integer.
	* @see `digitToBasic()`
	* @private
	* @param {Number} codePoint The basic numeric code point value.
	* @returns {Number} The numeric value of a basic code point (for use in
	* representing integers) in the range `0` to `base - 1`, or `base` if
	* the code point does not represent a value.
	*/
	var basicToDigit = function(codePoint) {
		if (codePoint >= 48 && codePoint < 58) return 26 + (codePoint - 48);
		if (codePoint >= 65 && codePoint < 91) return codePoint - 65;
		if (codePoint >= 97 && codePoint < 123) return codePoint - 97;
		return base;
	};
	/**
	* Converts a digit/integer into a basic code point.
	* @see `basicToDigit()`
	* @private
	* @param {Number} digit The numeric value of a basic code point.
	* @returns {Number} The basic code point whose value (when used for
	* representing integers) is `digit`, which needs to be in the range
	* `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
	* used; else, the lowercase form is used. The behavior is undefined
	* if `flag` is non-zero and `digit` has no uppercase form.
	*/
	var digitToBasic = function(digit, flag) {
		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
	};
	/**
	* Bias adaptation function as per section 3.4 of RFC 3492.
	* https://tools.ietf.org/html/rfc3492#section-3.4
	* @private
	*/
	var adapt = function(delta, numPoints, firstTime) {
		let k = 0;
		delta = firstTime ? floor(delta / damp) : delta >> 1;
		delta += floor(delta / numPoints);
		for (; delta > 455; k += base) delta = floor(delta / baseMinusTMin);
		return floor(k + 36 * delta / (delta + skew));
	};
	/**
	* Converts a Punycode string of ASCII-only symbols to a string of Unicode
	* symbols.
	* @memberOf punycode
	* @param {String} input The Punycode string of ASCII-only symbols.
	* @returns {String} The resulting string of Unicode symbols.
	*/
	var decode = function(input) {
		const output = [];
		const inputLength = input.length;
		let i = 0;
		let n = initialN;
		let bias = initialBias;
		let basic = input.lastIndexOf(delimiter);
		if (basic < 0) basic = 0;
		for (let j = 0; j < basic; ++j) {
			if (input.charCodeAt(j) >= 128) error("not-basic");
			output.push(input.charCodeAt(j));
		}
		for (let index = basic > 0 ? basic + 1 : 0; index < inputLength;) {
			const oldi = i;
			for (let w = 1, k = base;; k += base) {
				if (index >= inputLength) error("invalid-input");
				const digit = basicToDigit(input.charCodeAt(index++));
				if (digit >= base) error("invalid-input");
				if (digit > floor((maxInt - i) / w)) error("overflow");
				i += digit * w;
				const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
				if (digit < t) break;
				const baseMinusT = base - t;
				if (w > floor(maxInt / baseMinusT)) error("overflow");
				w *= baseMinusT;
			}
			const out = output.length + 1;
			bias = adapt(i - oldi, out, oldi == 0);
			if (floor(i / out) > maxInt - n) error("overflow");
			n += floor(i / out);
			i %= out;
			output.splice(i++, 0, n);
		}
		return String.fromCodePoint(...output);
	};
	/**
	* Converts a string of Unicode symbols (e.g. a domain name label) to a
	* Punycode string of ASCII-only symbols.
	* @memberOf punycode
	* @param {String} input The string of Unicode symbols.
	* @returns {String} The resulting Punycode string of ASCII-only symbols.
	*/
	var encode = function(input) {
		const output = [];
		input = ucs2decode(input);
		const inputLength = input.length;
		let n = initialN;
		let delta = 0;
		let bias = initialBias;
		for (const currentValue of input) if (currentValue < 128) output.push(stringFromCharCode(currentValue));
		const basicLength = output.length;
		let handledCPCount = basicLength;
		if (basicLength) output.push(delimiter);
		while (handledCPCount < inputLength) {
			let m = maxInt;
			for (const currentValue of input) if (currentValue >= n && currentValue < m) m = currentValue;
			const handledCPCountPlusOne = handledCPCount + 1;
			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) error("overflow");
			delta += (m - n) * handledCPCountPlusOne;
			n = m;
			for (const currentValue of input) {
				if (currentValue < n && ++delta > maxInt) error("overflow");
				if (currentValue === n) {
					let q = delta;
					for (let k = base;; k += base) {
						const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
						if (q < t) break;
						const qMinusT = q - t;
						const baseMinusT = base - t;
						output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)));
						q = floor(qMinusT / baseMinusT);
					}
					output.push(stringFromCharCode(digitToBasic(q, 0)));
					bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength);
					delta = 0;
					++handledCPCount;
				}
			}
			++delta;
			++n;
		}
		return output.join("");
	};
	/**
	* Converts a Punycode string representing a domain name or an email address
	* to Unicode. Only the Punycoded parts of the input will be converted, i.e.
	* it doesn't matter if you call it on a string that has already been
	* converted to Unicode.
	* @memberOf punycode
	* @param {String} input The Punycoded domain name or email address to
	* convert to Unicode.
	* @returns {String} The Unicode representation of the given Punycode
	* string.
	*/
	var toUnicode = function(input) {
		return mapDomain(input, function(string) {
			return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string;
		});
	};
	/**
	* Converts a Unicode string representing a domain name or an email address to
	* Punycode. Only the non-ASCII parts of the domain name will be converted,
	* i.e. it doesn't matter if you call it with a domain that's already in
	* ASCII.
	* @memberOf punycode
	* @param {String} input The domain name or email address to convert, as a
	* Unicode string.
	* @returns {String} The Punycode representation of the given domain name or
	* email address.
	*/
	var toASCII = function(input) {
		return mapDomain(input, function(string) {
			return regexNonASCII.test(string) ? "xn--" + encode(string) : string;
		});
	};
	module.exports = {
		/**
		* A string representing the current Punycode.js version number.
		* @memberOf punycode
		* @type String
		*/
		version: "2.3.1",
		/**
		* An object of methods to convert from JavaScript's internal character
		* representation (UCS-2) to Unicode code points, and back.
		* @see <https://mathiasbynens.be/notes/javascript-encoding>
		* @memberOf punycode
		* @type Object
		*/
		ucs2: {
			decode: ucs2decode,
			encode: ucs2encode
		},
		decode,
		encode,
		toASCII,
		toUnicode
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/shared/url.js
var require_url = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var urllib = __require("url");
	var punycode = require_punycode();
	var URLImpl = typeof URL !== "undefined" && URL || urllib.URL;
	var SLASHLESS_AUTHORITY = /^([a-zA-Z][a-zA-Z0-9+.-]*:)(?!\/\/)(.+)$/;
	function safeDecode(str) {
		try {
			return decodeURIComponent(str);
		} catch (_err) {
			return str;
		}
	}
	function normalizeHostname(raw) {
		let hostname = raw || "";
		if (!hostname) return "";
		if (hostname.charAt(0) === "[" && hostname.charAt(hostname.length - 1) === "]") return hostname.slice(1, -1);
		return punycode.toASCII(safeDecode(hostname));
	}
	module.exports.parse = (input, parseQueryString) => {
		input = input || "";
		if (!URLImpl) return urllib.parse(input, parseQueryString);
		const slashless = SLASHLESS_AUTHORITY.exec(input);
		const normalized = slashless ? slashless[1] + "//" + slashless[2] : input;
		let u;
		try {
			u = new URLImpl(normalized);
		} catch (_err) {
			return urllib.parse(input, parseQueryString);
		}
		const hostname = normalizeHostname(u.hostname);
		const port = u.port || null;
		const pathname = u.pathname || null;
		const search = u.search || null;
		let auth = null;
		if (u.username || u.password) auth = safeDecode(u.username) + (u.password ? ":" + safeDecode(u.password) : "");
		let query;
		if (parseQueryString) {
			query = Object.create(null);
			u.searchParams.forEach((value, key) => {
				if (Object.prototype.hasOwnProperty.call(query, key)) if (Array.isArray(query[key])) query[key].push(value);
				else query[key] = [query[key], value];
				else query[key] = value;
			});
		} else query = search ? search.slice(1) : null;
		return {
			protocol: u.protocol || null,
			host: u.host || null,
			hostname,
			port,
			pathname,
			search,
			path: (pathname || "") + (search || "") || null,
			href: u.href,
			auth,
			query
		};
	};
	module.exports.resolve = (from, to) => {
		if (!URLImpl) return urllib.resolve(from, to);
		try {
			return new URLImpl(to, from).href;
		} catch (_err) {
			return urllib.resolve(from, to);
		}
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/fetch/cookies.js
var require_cookies = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var urllib = require_url();
	var SESSION_TIMEOUT = 1800;
	/**
	* Creates a biskviit cookie jar for managing cookie values in memory
	*
	* @constructor
	* @param {Object} [options] Optional options object
	*/
	var Cookies = class {
		constructor(options) {
			this.options = options || {};
			this.cookies = [];
		}
		/**
		* Stores a cookie string to the cookie storage
		*
		* @param {String} cookieStr Value from the 'Set-Cookie:' header
		* @param {String} url Current URL
		*/
		set(cookieStr, url) {
			const urlparts = urllib.parse(url || "");
			const cookie = this.parse(cookieStr);
			let domain;
			if (cookie.domain) {
				domain = cookie.domain.replace(/^\./, "");
				if (urlparts.hostname.length < domain.length || ("." + urlparts.hostname).substr(-domain.length + 1) !== "." + domain) cookie.domain = urlparts.hostname;
			} else cookie.domain = urlparts.hostname;
			if (!cookie.path) cookie.path = this.getPath(urlparts.pathname);
			if (!cookie.expires) cookie.expires = new Date(Date.now() + (Number(this.options.sessionTimeout || SESSION_TIMEOUT) || SESSION_TIMEOUT) * 1e3);
			return this.add(cookie);
		}
		/**
		* Returns cookie string for the 'Cookie:' header.
		*
		* @param {String} url URL to check for
		* @returns {String} Cookie header or empty string if no matches were found
		*/
		get(url) {
			return this.list(url).map((cookie) => cookie.name + "=" + cookie.value).join("; ");
		}
		/**
		* Lists all valied cookie objects for the specified URL
		*
		* @param {String} url URL to check for
		* @returns {Array} An array of cookie objects
		*/
		list(url) {
			const result = [];
			for (let i = this.cookies.length - 1; i >= 0; i--) {
				const cookie = this.cookies[i];
				if (this.isExpired(cookie)) {
					this.cookies.splice(i, 1);
					continue;
				}
				if (this.match(cookie, url)) result.unshift(cookie);
			}
			return result;
		}
		/**
		* Parses cookie string from the 'Set-Cookie:' header
		*
		* @param {String} cookieStr String from the 'Set-Cookie:' header
		* @returns {Object} Cookie object
		*/
		parse(cookieStr) {
			const cookie = {};
			(cookieStr || "").toString().split(";").forEach((cookiePart) => {
				const valueParts = cookiePart.split("=");
				const key = valueParts.shift().trim().toLowerCase();
				let value = valueParts.join("=").trim();
				let domain;
				if (!key) return;
				switch (key) {
					case "expires":
						value = new Date(value);
						if (value.toString() !== "Invalid Date") cookie.expires = value;
						break;
					case "path":
						cookie.path = value;
						break;
					case "domain":
						domain = value.toLowerCase();
						if (domain.length && domain.charAt(0) !== ".") domain = "." + domain;
						cookie.domain = domain;
						break;
					case "max-age":
						cookie.expires = new Date(Date.now() + (Number(value) || 0) * 1e3);
						break;
					case "secure":
						cookie.secure = true;
						break;
					case "httponly":
						cookie.httponly = true;
						break;
					default: if (!cookie.name) {
						cookie.name = key;
						cookie.value = value;
					}
				}
			});
			return cookie;
		}
		/**
		* Checks if a cookie object is valid for a specified URL
		*
		* @param {Object} cookie Cookie object
		* @param {String} url URL to check for
		* @returns {Boolean} true if cookie is valid for specifiec URL
		*/
		match(cookie, url) {
			const urlparts = urllib.parse(url || "");
			if (urlparts.hostname !== cookie.domain && (cookie.domain.charAt(0) !== "." || ("." + urlparts.hostname).substr(-cookie.domain.length) !== cookie.domain)) return false;
			if (this.getPath(urlparts.pathname).substr(0, cookie.path.length) !== cookie.path) return false;
			if (cookie.secure && urlparts.protocol !== "https:") return false;
			return true;
		}
		/**
		* Adds (or updates/removes if needed) a cookie object to the cookie storage
		*
		* @param {Object} cookie Cookie value to be stored
		*/
		add(cookie) {
			if (!cookie || !cookie.name) return false;
			for (let i = 0, len = this.cookies.length; i < len; i++) if (this.compare(this.cookies[i], cookie)) {
				if (this.isExpired(cookie)) {
					this.cookies.splice(i, 1);
					return false;
				}
				this.cookies[i] = cookie;
				return true;
			}
			if (!this.isExpired(cookie)) this.cookies.push(cookie);
			return true;
		}
		/**
		* Checks if two cookie objects are the same
		*
		* @param {Object} a Cookie to check against
		* @param {Object} b Cookie to check against
		* @returns {Boolean} True, if the cookies are the same
		*/
		compare(a, b) {
			return a.name === b.name && a.path === b.path && a.domain === b.domain && a.secure === b.secure && a.httponly === b.httponly;
		}
		/**
		* Checks if a cookie is expired
		*
		* @param {Object} cookie Cookie object to check against
		* @returns {Boolean} True, if the cookie is expired
		*/
		isExpired(cookie) {
			return cookie.expires && cookie.expires < /* @__PURE__ */ new Date() || !cookie.value;
		}
		/**
		* Returns normalized cookie path for an URL path argument
		*
		* @param {String} pathname
		* @returns {String} Normalized path
		*/
		getPath(pathname) {
			let path = (pathname || "/").split("/");
			path.pop();
			path = path.join("/").trim();
			if (path.charAt(0) !== "/") path = "/" + path;
			if (path.substr(-1) !== "/") path += "/";
			return path;
		}
	};
	module.exports = Cookies;
}));
//#endregion
//#region node_modules/nodemailer/package.json
var package_exports = /* @__PURE__ */ __exportAll({
	author: () => author,
	bugs: () => bugs,
	default: () => package_default,
	description: () => description,
	devDependencies: () => devDependencies,
	engines: () => engines,
	homepage: () => homepage,
	keywords: () => keywords,
	license: () => license,
	main: () => main,
	name: () => name,
	repository: () => repository,
	scripts: () => scripts,
	version: () => version$1
});
var name, version$1, description, main, scripts, repository, keywords, author, license, bugs, homepage, devDependencies, engines, package_default;
var init_package = __esmMin((() => {
	name = "nodemailer";
	version$1 = "9.0.3";
	description = "Easy as cake e-mail sending from your Node.js applications";
	main = "lib/nodemailer.js";
	scripts = {
		"test": "node --test --test-concurrency=1 $(find test \\( -name '*-test.js' -o -name '*.test.js' \\))",
		"test:coverage": "c8 node --test --test-concurrency=1 $(find test \\( -name '*-test.js' -o -name '*.test.js' \\))",
		"format": "prettier --write \"**/*.{js,json,md}\"",
		"format:check": "prettier --check \"**/*.{js,json,md}\"",
		"lint": "eslint .",
		"lint:fix": "eslint . --fix",
		"update": "rm -rf node_modules/ package-lock.json && ncu -u && npm install",
		"test:syntax": "docker run --rm -v \"$PWD:/app:ro\" -w /app node:6-alpine node test/syntax-compat.js"
	};
	repository = {
		"type": "git",
		"url": "https://github.com/nodemailer/nodemailer.git"
	};
	keywords = ["Nodemailer"];
	author = "Andris Reinman";
	license = "MIT-0";
	bugs = { "url": "https://github.com/nodemailer/nodemailer/issues" };
	homepage = "https://nodemailer.com/";
	devDependencies = {
		"@aws-sdk/client-sesv2": "3.1068.0",
		"bunyan": "1.8.15",
		"c8": "11.0.0",
		"eslint": "10.5.0",
		"eslint-config-prettier": "10.1.8",
		"globals": "17.6.0",
		"libbase64": "1.3.0",
		"libmime": "5.3.8",
		"libqp": "2.1.1",
		"prettier": "3.8.4",
		"proxy": "1.0.2",
		"proxy-test-server": "1.0.0",
		"smtp-server": "3.19.0"
	};
	engines = { "node": ">=6.0.0" };
	package_default = {
		name,
		version: version$1,
		description,
		main,
		scripts,
		repository,
		keywords,
		author,
		license,
		bugs,
		homepage,
		devDependencies,
		engines
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/errors.js
var require_errors = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/**
	* Nodemailer Error Codes
	*
	* Centralized error code definitions for consistent error handling.
	*
	* Usage:
	*   const errors = require('./errors');
	*   let err = new Error('Connection closed');
	*   err.code = errors.ECONNECTION;
	*/
	/**
	* Error code descriptions for documentation and debugging
	*/
	var ERROR_CODES = {
		ECONNECTION: "Connection closed unexpectedly",
		ETIMEDOUT: "Connection or operation timed out",
		ESOCKET: "Socket-level error",
		EDNS: "DNS resolution failed",
		ETLS: "TLS handshake or STARTTLS failed",
		EREQUIRETLS: "REQUIRETLS not supported by server (RFC 8689)",
		EPROTOCOL: "Invalid SMTP server response",
		EENVELOPE: "Invalid mail envelope (sender or recipients)",
		EMESSAGE: "Message delivery error",
		ESTREAM: "Stream processing error",
		EAUTH: "Authentication failed",
		ENOAUTH: "Authentication credentials not provided",
		EOAUTH2: "OAuth2 token generation or refresh error",
		EMAXLIMIT: "Pool resource limit reached (max messages per connection)",
		ESENDMAIL: "Sendmail command error",
		ESES: "AWS SES transport error",
		ECONFIG: "Invalid configuration",
		EPROXY: "Proxy connection error",
		EFILEACCESS: "File access rejected (disableFileAccess is set)",
		EURLACCESS: "URL access rejected (disableUrlAccess is set)",
		EFETCH: "HTTP fetch error"
	};
	module.exports = { ERROR_CODES };
	for (const code of Object.keys(ERROR_CODES)) module.exports[code] = code;
}));
//#endregion
//#region node_modules/nodemailer/lib/fetch/index.js
var require_fetch = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var http$1 = __require("http");
	var https$1 = __require("https");
	var urllib = require_url();
	var zlib$5 = __require("zlib");
	var { PassThrough: PassThrough$3 } = __require("stream");
	var Cookies = require_cookies();
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var net$5 = __require("net");
	var errors = require_errors();
	var MAX_REDIRECTS = 5;
	module.exports = function(url, options) {
		return nmfetch(url, options);
	};
	module.exports.Cookies = Cookies;
	function nmfetch(url, options) {
		options = options || {};
		options.fetchRes = options.fetchRes || new PassThrough$3();
		options.cookies = options.cookies || new Cookies();
		options.redirects = options.redirects || 0;
		options.maxRedirects = isNaN(options.maxRedirects) ? MAX_REDIRECTS : options.maxRedirects;
		if (options.cookie) {
			[].concat(options.cookie || []).forEach((cookie) => {
				options.cookies.set(cookie, url);
			});
			options.cookie = false;
		}
		const fetchRes = options.fetchRes;
		const parsed = urllib.parse(url);
		let method = (options.method || "").toString().trim().toUpperCase() || "GET";
		let finished = false;
		let cookies;
		let body;
		const handler = parsed.protocol === "https:" ? https$1 : http$1;
		const headers = {
			"accept-encoding": "gzip,deflate",
			"user-agent": "nodemailer/" + packageData.version
		};
		Object.keys(options.headers || {}).forEach((key) => {
			headers[key.toLowerCase().trim()] = options.headers[key];
		});
		if (options.userAgent) headers["user-agent"] = options.userAgent;
		if (parsed.auth) headers.Authorization = "Basic " + Buffer.from(parsed.auth).toString("base64");
		if (cookies = options.cookies.get(url)) headers.cookie = cookies;
		if (options.body) {
			if (options.contentType !== false) headers["Content-Type"] = options.contentType || "application/x-www-form-urlencoded";
			if (typeof options.body.pipe === "function") {
				headers["Transfer-Encoding"] = "chunked";
				body = options.body;
				body.on("error", (err) => {
					if (finished) return;
					finished = true;
					err.code = errors.EFETCH;
					err.sourceUrl = url;
					fetchRes.emit("error", err);
				});
			} else {
				if (options.body instanceof Buffer) body = options.body;
				else if (typeof options.body === "object") try {
					body = Buffer.from(Object.keys(options.body).map((key) => {
						const value = options.body[key].toString().trim();
						return encodeURIComponent(key) + "=" + encodeURIComponent(value);
					}).join("&"));
				} catch (E) {
					if (finished) return;
					finished = true;
					E.code = errors.EFETCH;
					E.sourceUrl = url;
					fetchRes.emit("error", E);
					return;
				}
				else body = Buffer.from(options.body.toString().trim());
				headers["Content-Type"] = options.contentType || "application/x-www-form-urlencoded";
				headers["Content-Length"] = body.length;
			}
			method = (options.method || "").toString().trim().toUpperCase() || "POST";
		}
		let req;
		const reqOptions = {
			method,
			host: parsed.hostname,
			path: parsed.path,
			port: parsed.port ? parsed.port : parsed.protocol === "https:" ? 443 : 80,
			headers,
			rejectUnauthorized: true,
			agent: false
		};
		if (options.tls) Object.assign(reqOptions, options.tls);
		if (parsed.protocol === "https:" && parsed.hostname && parsed.hostname !== reqOptions.host && !net$5.isIP(parsed.hostname) && !reqOptions.servername) reqOptions.servername = parsed.hostname;
		try {
			req = handler.request(reqOptions);
		} catch (E) {
			finished = true;
			setImmediate(() => {
				E.code = errors.EFETCH;
				E.sourceUrl = url;
				fetchRes.emit("error", E);
			});
			return fetchRes;
		}
		if (options.timeout) req.setTimeout(options.timeout, () => {
			if (finished) return;
			finished = true;
			req.abort();
			const err = /* @__PURE__ */ new Error("Request Timeout");
			err.code = errors.EFETCH;
			err.sourceUrl = url;
			fetchRes.emit("error", err);
		});
		req.on("error", (err) => {
			if (finished) return;
			finished = true;
			err.code = errors.EFETCH;
			err.sourceUrl = url;
			fetchRes.emit("error", err);
		});
		req.on("response", (res) => {
			let inflate;
			if (finished) return;
			switch (res.headers["content-encoding"]) {
				case "gzip":
				case "deflate": inflate = zlib$5.createUnzip();
			}
			if (res.headers["set-cookie"]) [].concat(res.headers["set-cookie"] || []).forEach((cookie) => {
				options.cookies.set(cookie, url);
			});
			if ([
				301,
				302,
				303,
				307,
				308
			].includes(res.statusCode) && res.headers.location) {
				options.redirects++;
				if (options.redirects > options.maxRedirects) {
					finished = true;
					const err = /* @__PURE__ */ new Error("Maximum redirect count exceeded");
					err.code = errors.EFETCH;
					err.sourceUrl = url;
					fetchRes.emit("error", err);
					req.abort();
					return;
				}
				options.method = "GET";
				options.body = false;
				const redirectUrl = urllib.resolve(url, res.headers.location);
				const redirectParsed = urllib.parse(redirectUrl);
				const crossHost = redirectParsed.hostname !== parsed.hostname;
				const downgrade = parsed.protocol === "https:" && redirectParsed.protocol === "http:";
				if (options.headers && (crossHost || downgrade)) {
					const sensitive = [
						"authorization",
						"cookie",
						"proxy-authorization"
					];
					Object.keys(options.headers).forEach((key) => {
						if (sensitive.includes(key.toLowerCase())) delete options.headers[key];
					});
				}
				return nmfetch(redirectUrl, options);
			}
			fetchRes.statusCode = res.statusCode;
			fetchRes.headers = res.headers;
			if (res.statusCode >= 300 && !options.allowErrorResponse) {
				finished = true;
				const err = /* @__PURE__ */ new Error("Invalid status code " + res.statusCode);
				err.code = errors.EFETCH;
				err.sourceUrl = url;
				fetchRes.emit("error", err);
				req.abort();
				return;
			}
			res.on("error", (err) => {
				if (finished) return;
				finished = true;
				err.code = errors.EFETCH;
				err.sourceUrl = url;
				fetchRes.emit("error", err);
				req.abort();
			});
			if (inflate) {
				res.pipe(inflate).pipe(fetchRes);
				inflate.on("error", (err) => {
					if (finished) return;
					finished = true;
					err.code = errors.EFETCH;
					err.sourceUrl = url;
					fetchRes.emit("error", err);
					req.abort();
				});
			} else res.pipe(fetchRes);
		});
		setImmediate(() => {
			if (body) try {
				if (typeof body.pipe === "function") return body.pipe(req);
				req.write(body);
			} catch (err) {
				finished = true;
				err.code = errors.EFETCH;
				err.sourceUrl = url;
				fetchRes.emit("error", err);
				return;
			}
			req.end();
		});
		return fetchRes;
	}
}));
//#endregion
//#region node_modules/nodemailer/lib/shared/index.js
var require_shared = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var urllib = require_url();
	var util$7 = __require("util");
	var fs$5 = __require("fs");
	var nmfetch = require_fetch();
	var errors = require_errors();
	var dns$1 = __require("dns");
	var net$4 = __require("net");
	var os$2 = __require("os");
	var DNS_TTL = 3e5;
	var CACHE_CLEANUP_INTERVAL = 3e4;
	var MAX_CACHE_SIZE = 1e3;
	var lastCacheCleanup = 0;
	module.exports._lastCacheCleanup = () => lastCacheCleanup;
	module.exports._resetCacheCleanup = () => {
		lastCacheCleanup = 0;
	};
	var networkInterfaces;
	try {
		networkInterfaces = os$2.networkInterfaces();
	} catch (_err) {}
	module.exports.networkInterfaces = networkInterfaces;
	var isFamilySupported = (family, allowInternal) => {
		const ifaces = module.exports.networkInterfaces;
		if (!ifaces) return true;
		return Object.keys(ifaces).map((key) => ifaces[key]).reduce((acc, val) => acc.concat(val), []).filter((i) => !i.internal || allowInternal).some((i) => i.family === "IPv" + family || i.family === family);
	};
	var resolve = (family, hostname, options, callback) => {
		options = options || {};
		if (!isFamilySupported(family, options.allowInternalNetworkInterfaces)) return callback(null, []);
		(dns$1.Resolver ? new dns$1.Resolver(options) : dns$1)["resolve" + family](hostname, (err, addresses) => {
			if (err) {
				switch (err.code) {
					case dns$1.NODATA:
					case dns$1.NOTFOUND:
					case dns$1.NOTIMP:
					case dns$1.SERVFAIL:
					case dns$1.CONNREFUSED:
					case dns$1.REFUSED:
					case "EAI_AGAIN": return callback(null, []);
				}
				return callback(err);
			}
			return callback(null, Array.isArray(addresses) ? addresses : [].concat(addresses || []));
		});
	};
	var dnsCache = module.exports.dnsCache = /* @__PURE__ */ new Map();
	var formatDNSValue = (value, extra) => {
		if (!value) return Object.assign({}, extra || {});
		const addresses = value.addresses || [];
		const host = addresses.length > 0 ? addresses[Math.floor(Math.random() * addresses.length)] : null;
		return Object.assign({
			servername: value.servername,
			host,
			_addresses: addresses
		}, extra || {});
	};
	module.exports.resolveHostname = (options, callback) => {
		options = options || {};
		if (!options.host && options.servername) options.host = options.servername;
		if (!options.host || net$4.isIP(options.host)) return callback(null, formatDNSValue({
			addresses: [options.host],
			servername: options.servername || false
		}, { cached: false }));
		let cached;
		if (dnsCache.has(options.host)) {
			cached = dnsCache.get(options.host);
			const now = Date.now();
			if (now - lastCacheCleanup > CACHE_CLEANUP_INTERVAL) {
				lastCacheCleanup = now;
				for (const [host, entry] of dnsCache.entries()) if (entry.expires && entry.expires < now) dnsCache.delete(host);
				if (dnsCache.size > MAX_CACHE_SIZE) {
					const toDelete = Math.floor(MAX_CACHE_SIZE * .1);
					Array.from(dnsCache.keys()).slice(0, toDelete).forEach((key) => dnsCache.delete(key));
				}
			}
			if (!cached.expires || cached.expires >= now) return callback(null, formatDNSValue(cached.value, { cached: true }));
		}
		let ipv4Addresses = [];
		let ipv6Addresses = [];
		let ipv4Error = null;
		let ipv6Error = null;
		resolve(4, options.host, options, (err, addresses) => {
			if (err) ipv4Error = err;
			else ipv4Addresses = addresses || [];
			resolve(6, options.host, options, (err, addresses) => {
				if (err) ipv6Error = err;
				else ipv6Addresses = addresses || [];
				const allAddresses = ipv4Addresses.concat(ipv6Addresses);
				if (allAddresses.length) {
					const value = {
						addresses: allAddresses,
						servername: options.servername || options.host
					};
					dnsCache.set(options.host, {
						value,
						expires: Date.now() + (options.dnsTtl || DNS_TTL)
					});
					return callback(null, formatDNSValue(value, { cached: false }));
				}
				if (ipv4Error && ipv6Error) {
					if (cached) {
						dnsCache.set(options.host, {
							value: cached.value,
							expires: Date.now() + (options.dnsTtl || DNS_TTL)
						});
						return callback(null, formatDNSValue(cached.value, {
							cached: true,
							error: ipv4Error
						}));
					}
				}
				try {
					dns$1.lookup(options.host, { all: true }, (err, addresses) => {
						if (err) {
							if (cached) {
								dnsCache.set(options.host, {
									value: cached.value,
									expires: Date.now() + (options.dnsTtl || DNS_TTL)
								});
								return callback(null, formatDNSValue(cached.value, {
									cached: true,
									error: err
								}));
							}
							return callback(err);
						}
						const supportedAddresses = addresses ? addresses.filter((addr) => isFamilySupported(addr.family)).map((addr) => addr.address) : [];
						if (addresses && addresses.length && !supportedAddresses.length) console.warn(`Failed to resolve IPv${addresses[0].family} addresses with current network`);
						if (!supportedAddresses.length && cached) return callback(null, formatDNSValue(cached.value, { cached: true }));
						const value = {
							addresses: supportedAddresses.length ? supportedAddresses : [options.host],
							servername: options.servername || options.host
						};
						dnsCache.set(options.host, {
							value,
							expires: Date.now() + (options.dnsTtl || DNS_TTL)
						});
						return callback(null, formatDNSValue(value, { cached: false }));
					});
				} catch (lookupErr) {
					if (cached) {
						dnsCache.set(options.host, {
							value: cached.value,
							expires: Date.now() + (options.dnsTtl || DNS_TTL)
						});
						return callback(null, formatDNSValue(cached.value, {
							cached: true,
							error: lookupErr
						}));
					}
					return callback(ipv4Error || ipv6Error || lookupErr);
				}
			});
		});
	};
	/**
	* Parses connection url to a structured configuration object
	*
	* @param {String} str Connection url
	* @return {Object} Configuration object
	*/
	module.exports.parseConnectionUrl = (str) => {
		str = str || "";
		const options = {};
		const url = urllib.parse(str, true);
		switch (url.protocol) {
			case "smtp:":
				options.secure = false;
				break;
			case "smtps:":
				options.secure = true;
				break;
			case "direct:": options.direct = true;
		}
		if (!isNaN(url.port) && Number(url.port)) options.port = Number(url.port);
		if (url.hostname) options.host = url.hostname;
		if (url.auth) {
			const auth = url.auth.split(":");
			options.auth = {
				user: auth.shift(),
				pass: auth.join(":")
			};
		}
		Object.keys(url.query || {}).forEach((key) => {
			let obj = options;
			let lKey = key;
			let value = url.query[key];
			if (!isNaN(value)) value = Number(value);
			switch (value) {
				case "true":
					value = true;
					break;
				case "false": value = false;
			}
			if (key.indexOf("tls.") === 0) {
				lKey = key.substr(4);
				if (!options.tls) options.tls = {};
				obj = options.tls;
			} else if (key.indexOf(".") >= 0) return;
			if (!(lKey in obj)) obj[lKey] = value;
		});
		return options;
	};
	module.exports._logFunc = (logger, level, defaults, data, message, ...args) => {
		const entry = Object.assign({}, defaults || {}, data || {});
		delete entry.level;
		let logLevel = level;
		if (typeof logger[logLevel] !== "function") logLevel = [
			"info",
			"debug",
			"log",
			"trace",
			"warn",
			"error"
		].find((name) => typeof logger[name] === "function");
		if (logLevel) logger[logLevel](entry, message, ...args);
	};
	/**
	* Returns a bunyan-compatible logger interface. Uses either provided logger or
	* creates a default console logger
	*
	* @param {Object} [options] Options object that might include 'logger' value
	* @return {Object} bunyan compatible logger
	*/
	module.exports.getLogger = (options, defaults) => {
		options = options || {};
		const response = {};
		const levels = [
			"trace",
			"debug",
			"info",
			"warn",
			"error",
			"fatal"
		];
		if (!options.logger) {
			levels.forEach((level) => {
				response[level] = () => false;
			});
			return response;
		}
		const logger = options.logger === true ? createDefaultLogger(levels) : options.logger;
		levels.forEach((level) => {
			response[level] = (data, message, ...args) => {
				module.exports._logFunc(logger, level, defaults, data, message, ...args);
			};
		});
		return response;
	};
	/**
	* Wrapper for creating a callback that either resolves or rejects a promise
	* based on input
	*
	* @param {Function} resolve Function to run if callback is called
	* @param {Function} reject Function to run if callback ends with an error
	*/
	module.exports.callbackPromise = (resolve, reject) => function() {
		const args = Array.from(arguments);
		const err = args.shift();
		if (err) reject(err);
		else resolve(...args);
	};
	module.exports.parseDataURI = (uri) => {
		if (typeof uri !== "string") return null;
		if (!uri.startsWith("data:")) return null;
		const commaPos = uri.indexOf(",");
		if (commaPos === -1) return null;
		const data = uri.substring(commaPos + 1);
		const metaStr = uri.substring(5, commaPos);
		let encoding;
		const metaEntries = metaStr.split(";");
		if (metaEntries.length > 0) {
			const lastEntry = metaEntries[metaEntries.length - 1].toLowerCase().trim();
			if ([
				"base64",
				"utf8",
				"utf-8"
			].includes(lastEntry) && lastEntry.indexOf("=") === -1) {
				encoding = lastEntry;
				metaEntries.pop();
			}
		}
		const contentType = metaEntries.length > 0 ? metaEntries.shift() : "application/octet-stream";
		const params = {};
		for (let i = 0; i < metaEntries.length; i++) {
			const entry = metaEntries[i];
			const sepPos = entry.indexOf("=");
			if (sepPos > 0) {
				const key = entry.substring(0, sepPos).trim();
				const value = entry.substring(sepPos + 1).trim();
				if (key) params[key] = value;
			}
		}
		let bufferData;
		try {
			if (encoding === "base64") bufferData = Buffer.from(data, "base64");
			else try {
				bufferData = Buffer.from(decodeURIComponent(data));
			} catch (_decodeError) {
				bufferData = Buffer.from(data);
			}
		} catch (_bufferError) {
			bufferData = Buffer.alloc(0);
		}
		return {
			data: bufferData,
			encoding: encoding || null,
			contentType: contentType || "application/octet-stream",
			params
		};
	};
	/**
	* Resolves a String or a Buffer value for content value. Useful if the value
	* is a Stream or a file or an URL. If the value is a Stream, overwrites
	* the stream object with the resolved value (you can't stream a value twice).
	*
	* This is useful when you want to create a plugin that needs a content value,
	* for example the `html` or `text` value as a String or a Buffer but not as
	* a file path or an URL.
	*
	* @param {Object} data An object or an Array you want to resolve an element for
	* @param {String|Number} key Property name or an Array index
	* @param {Object} [options] Optional access policy: { disableFileAccess, disableUrlAccess }
	* @param {Function} callback Callback function with (err, value)
	*/
	module.exports.resolveContent = (data, key, options, callback) => {
		if (!callback && typeof options === "function") {
			callback = options;
			options = false;
		}
		options = options || {};
		let promise;
		if (!callback) promise = new Promise((resolve, reject) => {
			callback = module.exports.callbackPromise(resolve, reject);
		});
		resolveContentValue(data, key, options, callback);
		return promise;
	};
	function resolveContentValue(data, key, options, callback) {
		let content = data && data[key] && data[key].content || data[key];
		const encoding = (typeof data[key] === "object" && data[key].encoding || "utf8").toString().toLowerCase().replace(/[-_\s]/g, "");
		if (!content) return callback(null, content);
		if (typeof content === "object") {
			if (typeof content.pipe === "function") return resolveStream(content, (err, value) => {
				if (err) return callback(err);
				if (data[key].content) data[key].content = value;
				else data[key] = value;
				callback(null, value);
			});
			else if (/^https?:\/\//i.test(content.path || content.href)) {
				if (options.disableUrlAccess) return setImmediate(() => {
					const err = /* @__PURE__ */ new Error("Url access rejected for " + (content.path || content.href));
					err.code = errors.EURLACCESS;
					callback(err);
				});
				return resolveStream(nmfetch(content.path || content.href, {
					headers: content.httpHeaders,
					tls: content.tls
				}), callback);
			} else if (/^data:/i.test(content.path || content.href)) {
				const parsedDataUri = module.exports.parseDataURI(content.path || content.href);
				return callback(null, parsedDataUri && parsedDataUri.data ? parsedDataUri.data : Buffer.alloc(0));
			} else if (content.path) {
				if (options.disableFileAccess) return setImmediate(() => {
					const err = /* @__PURE__ */ new Error("File access rejected for " + content.path);
					err.code = errors.EFILEACCESS;
					callback(err);
				});
				return resolveStream(fs$5.createReadStream(content.path), callback);
			}
		}
		if (typeof data[key].content === "string" && ![
			"utf8",
			"usascii",
			"ascii"
		].includes(encoding)) content = Buffer.from(data[key].content, encoding);
		setImmediate(() => callback(null, content));
	}
	/**
	* Copies properties from source objects to target objects
	*/
	module.exports.assign = function() {
		const args = Array.from(arguments);
		const target = args.shift() || {};
		args.forEach((source) => {
			Object.keys(source || {}).forEach((key) => {
				if (["tls", "auth"].includes(key) && source[key] && typeof source[key] === "object") target[key] = Object.assign(target[key] || {}, source[key]);
				else target[key] = source[key];
			});
		});
		return target;
	};
	module.exports.encodeXText = (str) => {
		if (!/[^\x21-\x2A\x2C-\x3C\x3E-\x7E]/.test(str)) return str;
		const buf = Buffer.from(str);
		let result = "";
		for (let i = 0, len = buf.length; i < len; i++) {
			const c = buf[i];
			if (c < 33 || c > 126 || c === 43 || c === 61) result += "+" + (c < 16 ? "0" : "") + c.toString(16).toUpperCase();
			else result += String.fromCharCode(c);
		}
		return result;
	};
	/**
	* Streams a stream value into a Buffer
	*
	* @param {Object} stream Readable stream
	* @param {Function} callback Callback function with (err, value)
	*/
	function resolveStream(stream, callback) {
		let responded = false;
		const chunks = [];
		let chunklen = 0;
		stream.on("error", (err) => {
			if (responded) return;
			responded = true;
			callback(err);
		});
		stream.on("readable", () => {
			let chunk;
			while ((chunk = stream.read()) !== null) {
				chunks.push(chunk);
				chunklen += chunk.length;
			}
		});
		stream.on("end", () => {
			if (responded) return;
			responded = true;
			let value;
			try {
				value = Buffer.concat(chunks, chunklen);
			} catch (E) {
				return callback(E);
			}
			callback(null, value);
		});
	}
	/**
	* Generates a bunyan-like logger that prints to console
	*
	* @returns {Object} Bunyan logger instance
	*/
	function createDefaultLogger(levels) {
		const levelMaxLen = levels.reduce((max, level) => Math.max(max, level.length), 0);
		const levelNames = /* @__PURE__ */ new Map();
		levels.forEach((level) => {
			let levelName = level.toUpperCase();
			if (levelName.length < levelMaxLen) levelName += " ".repeat(levelMaxLen - levelName.length);
			levelNames.set(level, levelName);
		});
		const print = (level, entry, message, ...args) => {
			let prefix = "";
			if (entry) {
				if (entry.tnx === "server") prefix = "S: ";
				else if (entry.tnx === "client") prefix = "C: ";
				if (entry.sid) prefix = "[" + entry.sid + "] " + prefix;
				if (entry.cid) prefix = "[#" + entry.cid + "] " + prefix;
			}
			message = util$7.format(message, ...args);
			message.split(/\r?\n/).forEach((line) => {
				console.log("[%s] %s %s", (/* @__PURE__ */ new Date()).toISOString().substr(0, 19).replace(/T/, " "), levelNames.get(level), prefix + line);
			});
		};
		const logger = {};
		levels.forEach((level) => {
			logger[level] = print.bind(null, level);
		});
		return logger;
	}
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-funcs/mime-types.js
var require_mime_types = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var path$3 = __require("path");
	var defaultMimeType = "application/octet-stream";
	var defaultExtension = "bin";
	var mimeTypes = /* @__PURE__ */ new Map([
		["application/acad", "dwg"],
		["application/applixware", "aw"],
		["application/arj", "arj"],
		["application/atom+xml", "xml"],
		["application/atomcat+xml", "atomcat"],
		["application/atomsvc+xml", "atomsvc"],
		["application/base64", ["mm", "mme"]],
		["application/binhex", "hqx"],
		["application/binhex4", "hqx"],
		["application/book", ["book", "boo"]],
		["application/ccxml+xml,", "ccxml"],
		["application/cdf", "cdf"],
		["application/cdmi-capability", "cdmia"],
		["application/cdmi-container", "cdmic"],
		["application/cdmi-domain", "cdmid"],
		["application/cdmi-object", "cdmio"],
		["application/cdmi-queue", "cdmiq"],
		["application/clariscad", "ccad"],
		["application/commonground", "dp"],
		["application/cu-seeme", "cu"],
		["application/davmount+xml", "davmount"],
		["application/drafting", "drw"],
		["application/dsptype", "tsp"],
		["application/dssc+der", "dssc"],
		["application/dssc+xml", "xdssc"],
		["application/dxf", "dxf"],
		["application/ecmascript", ["js", "es"]],
		["application/emma+xml", "emma"],
		["application/envoy", "evy"],
		["application/epub+zip", "epub"],
		["application/excel", [
			"xls",
			"xl",
			"xla",
			"xlb",
			"xlc",
			"xld",
			"xlk",
			"xll",
			"xlm",
			"xlt",
			"xlv",
			"xlw"
		]],
		["application/exi", "exi"],
		["application/font-tdpfr", "pfr"],
		["application/fractals", "fif"],
		["application/freeloader", "frl"],
		["application/futuresplash", "spl"],
		["application/geo+json", "geojson"],
		["application/gnutar", "tgz"],
		["application/groupwise", "vew"],
		["application/hlp", "hlp"],
		["application/hta", "hta"],
		["application/hyperstudio", "stk"],
		["application/i-deas", "unv"],
		["application/iges", ["iges", "igs"]],
		["application/inf", "inf"],
		["application/internet-property-stream", "acx"],
		["application/ipfix", "ipfix"],
		["application/java", "class"],
		["application/java-archive", "jar"],
		["application/java-byte-code", "class"],
		["application/java-serialized-object", "ser"],
		["application/java-vm", "class"],
		["application/javascript", "js"],
		["application/json", "json"],
		["application/lha", "lha"],
		["application/lzx", "lzx"],
		["application/mac-binary", "bin"],
		["application/mac-binhex", "hqx"],
		["application/mac-binhex40", "hqx"],
		["application/mac-compactpro", "cpt"],
		["application/macbinary", "bin"],
		["application/mads+xml", "mads"],
		["application/marc", "mrc"],
		["application/marcxml+xml", "mrcx"],
		["application/mathematica", "ma"],
		["application/mathml+xml", "mathml"],
		["application/mbedlet", "mbd"],
		["application/mbox", "mbox"],
		["application/mcad", "mcd"],
		["application/mediaservercontrol+xml", "mscml"],
		["application/metalink4+xml", "meta4"],
		["application/mets+xml", "mets"],
		["application/mime", "aps"],
		["application/mods+xml", "mods"],
		["application/mp21", "m21"],
		["application/mp4", "mp4"],
		["application/mspowerpoint", [
			"ppt",
			"pot",
			"pps",
			"ppz"
		]],
		["application/msword", [
			"doc",
			"dot",
			"w6w",
			"wiz",
			"word"
		]],
		["application/mswrite", "wri"],
		["application/mxf", "mxf"],
		["application/netmc", "mcp"],
		["application/octet-stream", ["*"]],
		["application/oda", "oda"],
		["application/oebps-package+xml", "opf"],
		["application/ogg", "ogx"],
		["application/olescript", "axs"],
		["application/onenote", "onetoc"],
		["application/patch-ops-error+xml", "xer"],
		["application/pdf", "pdf"],
		["application/pgp-encrypted", "asc"],
		["application/pgp-signature", "pgp"],
		["application/pics-rules", "prf"],
		["application/pkcs-12", "p12"],
		["application/pkcs-crl", "crl"],
		["application/pkcs10", "p10"],
		["application/pkcs7-mime", ["p7c", "p7m"]],
		["application/pkcs7-signature", "p7s"],
		["application/pkcs8", "p8"],
		["application/pkix-attr-cert", "ac"],
		["application/pkix-cert", ["cer", "crt"]],
		["application/pkix-crl", "crl"],
		["application/pkix-pkipath", "pkipath"],
		["application/pkixcmp", "pki"],
		["application/plain", "text"],
		["application/pls+xml", "pls"],
		["application/postscript", [
			"ps",
			"ai",
			"eps"
		]],
		["application/powerpoint", "ppt"],
		["application/pro_eng", ["part", "prt"]],
		["application/prs.cww", "cww"],
		["application/pskc+xml", "pskcxml"],
		["application/rdf+xml", "rdf"],
		["application/reginfo+xml", "rif"],
		["application/relax-ng-compact-syntax", "rnc"],
		["application/resource-lists+xml", "rl"],
		["application/resource-lists-diff+xml", "rld"],
		["application/ringing-tones", "rng"],
		["application/rls-services+xml", "rs"],
		["application/rsd+xml", "rsd"],
		["application/rss+xml", "xml"],
		["application/rtf", ["rtf", "rtx"]],
		["application/sbml+xml", "sbml"],
		["application/scvp-cv-request", "scq"],
		["application/scvp-cv-response", "scs"],
		["application/scvp-vp-request", "spq"],
		["application/scvp-vp-response", "spp"],
		["application/sdp", "sdp"],
		["application/sea", "sea"],
		["application/set", "set"],
		["application/set-payment-initiation", "setpay"],
		["application/set-registration-initiation", "setreg"],
		["application/shf+xml", "shf"],
		["application/sla", "stl"],
		["application/smil", ["smi", "smil"]],
		["application/smil+xml", "smi"],
		["application/solids", "sol"],
		["application/sounder", "sdr"],
		["application/sparql-query", "rq"],
		["application/sparql-results+xml", "srx"],
		["application/srgs", "gram"],
		["application/srgs+xml", "grxml"],
		["application/sru+xml", "sru"],
		["application/ssml+xml", "ssml"],
		["application/step", ["step", "stp"]],
		["application/streamingmedia", "ssm"],
		["application/tei+xml", "tei"],
		["application/thraud+xml", "tfi"],
		["application/timestamped-data", "tsd"],
		["application/toolbook", "tbk"],
		["application/vda", "vda"],
		["application/vnd.3gpp.pic-bw-large", "plb"],
		["application/vnd.3gpp.pic-bw-small", "psb"],
		["application/vnd.3gpp.pic-bw-var", "pvb"],
		["application/vnd.3gpp2.tcap", "tcap"],
		["application/vnd.3m.post-it-notes", "pwn"],
		["application/vnd.accpac.simply.aso", "aso"],
		["application/vnd.accpac.simply.imp", "imp"],
		["application/vnd.acucobol", "acu"],
		["application/vnd.acucorp", "atc"],
		["application/vnd.adobe.air-application-installer-package+zip", "air"],
		["application/vnd.adobe.fxp", "fxp"],
		["application/vnd.adobe.xdp+xml", "xdp"],
		["application/vnd.adobe.xfdf", "xfdf"],
		["application/vnd.ahead.space", "ahead"],
		["application/vnd.airzip.filesecure.azf", "azf"],
		["application/vnd.airzip.filesecure.azs", "azs"],
		["application/vnd.amazon.ebook", "azw"],
		["application/vnd.americandynamics.acc", "acc"],
		["application/vnd.amiga.ami", "ami"],
		["application/vnd.android.package-archive", "apk"],
		["application/vnd.anser-web-certificate-issue-initiation", "cii"],
		["application/vnd.anser-web-funds-transfer-initiation", "fti"],
		["application/vnd.antix.game-component", "atx"],
		["application/vnd.apple.installer+xml", "mpkg"],
		["application/vnd.apple.mpegurl", "m3u8"],
		["application/vnd.aristanetworks.swi", "swi"],
		["application/vnd.audiograph", "aep"],
		["application/vnd.blueice.multipass", "mpm"],
		["application/vnd.bmi", "bmi"],
		["application/vnd.businessobjects", "rep"],
		["application/vnd.chemdraw+xml", "cdxml"],
		["application/vnd.chipnuts.karaoke-mmd", "mmd"],
		["application/vnd.cinderella", "cdy"],
		["application/vnd.claymore", "cla"],
		["application/vnd.cloanto.rp9", "rp9"],
		["application/vnd.clonk.c4group", "c4g"],
		["application/vnd.cluetrust.cartomobile-config", "c11amc"],
		["application/vnd.cluetrust.cartomobile-config-pkg", "c11amz"],
		["application/vnd.commonspace", "csp"],
		["application/vnd.contact.cmsg", "cdbcmsg"],
		["application/vnd.cosmocaller", "cmc"],
		["application/vnd.crick.clicker", "clkx"],
		["application/vnd.crick.clicker.keyboard", "clkk"],
		["application/vnd.crick.clicker.palette", "clkp"],
		["application/vnd.crick.clicker.template", "clkt"],
		["application/vnd.crick.clicker.wordbank", "clkw"],
		["application/vnd.criticaltools.wbs+xml", "wbs"],
		["application/vnd.ctc-posml", "pml"],
		["application/vnd.cups-ppd", "ppd"],
		["application/vnd.curl.car", "car"],
		["application/vnd.curl.pcurl", "pcurl"],
		["application/vnd.data-vision.rdz", "rdz"],
		["application/vnd.denovo.fcselayout-link", "fe_launch"],
		["application/vnd.dna", "dna"],
		["application/vnd.dolby.mlp", "mlp"],
		["application/vnd.dpgraph", "dpg"],
		["application/vnd.dreamfactory", "dfac"],
		["application/vnd.dvb.ait", "ait"],
		["application/vnd.dvb.service", "svc"],
		["application/vnd.dynageo", "geo"],
		["application/vnd.ecowin.chart", "mag"],
		["application/vnd.enliven", "nml"],
		["application/vnd.epson.esf", "esf"],
		["application/vnd.epson.msf", "msf"],
		["application/vnd.epson.quickanime", "qam"],
		["application/vnd.epson.salt", "slt"],
		["application/vnd.epson.ssf", "ssf"],
		["application/vnd.eszigno3+xml", "es3"],
		["application/vnd.ezpix-album", "ez2"],
		["application/vnd.ezpix-package", "ez3"],
		["application/vnd.fdf", "fdf"],
		["application/vnd.fdsn.seed", "seed"],
		["application/vnd.flographit", "gph"],
		["application/vnd.fluxtime.clip", "ftc"],
		["application/vnd.framemaker", "fm"],
		["application/vnd.frogans.fnc", "fnc"],
		["application/vnd.frogans.ltf", "ltf"],
		["application/vnd.fsc.weblaunch", "fsc"],
		["application/vnd.fujitsu.oasys", "oas"],
		["application/vnd.fujitsu.oasys2", "oa2"],
		["application/vnd.fujitsu.oasys3", "oa3"],
		["application/vnd.fujitsu.oasysgp", "fg5"],
		["application/vnd.fujitsu.oasysprs", "bh2"],
		["application/vnd.fujixerox.ddd", "ddd"],
		["application/vnd.fujixerox.docuworks", "xdw"],
		["application/vnd.fujixerox.docuworks.binder", "xbd"],
		["application/vnd.fuzzysheet", "fzs"],
		["application/vnd.genomatix.tuxedo", "txd"],
		["application/vnd.geogebra.file", "ggb"],
		["application/vnd.geogebra.tool", "ggt"],
		["application/vnd.geometry-explorer", "gex"],
		["application/vnd.geonext", "gxt"],
		["application/vnd.geoplan", "g2w"],
		["application/vnd.geospace", "g3w"],
		["application/vnd.gmx", "gmx"],
		["application/vnd.google-earth.kml+xml", "kml"],
		["application/vnd.google-earth.kmz", "kmz"],
		["application/vnd.grafeq", "gqf"],
		["application/vnd.groove-account", "gac"],
		["application/vnd.groove-help", "ghf"],
		["application/vnd.groove-identity-message", "gim"],
		["application/vnd.groove-injector", "grv"],
		["application/vnd.groove-tool-message", "gtm"],
		["application/vnd.groove-tool-template", "tpl"],
		["application/vnd.groove-vcard", "vcg"],
		["application/vnd.hal+xml", "hal"],
		["application/vnd.handheld-entertainment+xml", "zmm"],
		["application/vnd.hbci", "hbci"],
		["application/vnd.hhe.lesson-player", "les"],
		["application/vnd.hp-hpgl", [
			"hgl",
			"hpg",
			"hpgl"
		]],
		["application/vnd.hp-hpid", "hpid"],
		["application/vnd.hp-hps", "hps"],
		["application/vnd.hp-jlyt", "jlt"],
		["application/vnd.hp-pcl", "pcl"],
		["application/vnd.hp-pclxl", "pclxl"],
		["application/vnd.hydrostatix.sof-data", "sfd-hdstx"],
		["application/vnd.hzn-3d-crossword", "x3d"],
		["application/vnd.ibm.minipay", "mpy"],
		["application/vnd.ibm.modcap", "afp"],
		["application/vnd.ibm.rights-management", "irm"],
		["application/vnd.ibm.secure-container", "sc"],
		["application/vnd.iccprofile", "icc"],
		["application/vnd.igloader", "igl"],
		["application/vnd.immervision-ivp", "ivp"],
		["application/vnd.immervision-ivu", "ivu"],
		["application/vnd.insors.igm", "igm"],
		["application/vnd.intercon.formnet", "xpw"],
		["application/vnd.intergeo", "i2g"],
		["application/vnd.intu.qbo", "qbo"],
		["application/vnd.intu.qfx", "qfx"],
		["application/vnd.ipunplugged.rcprofile", "rcprofile"],
		["application/vnd.irepository.package+xml", "irp"],
		["application/vnd.is-xpr", "xpr"],
		["application/vnd.isac.fcs", "fcs"],
		["application/vnd.jam", "jam"],
		["application/vnd.jcp.javame.midlet-rms", "rms"],
		["application/vnd.jisp", "jisp"],
		["application/vnd.joost.joda-archive", "joda"],
		["application/vnd.kahootz", "ktz"],
		["application/vnd.kde.karbon", "karbon"],
		["application/vnd.kde.kchart", "chrt"],
		["application/vnd.kde.kformula", "kfo"],
		["application/vnd.kde.kivio", "flw"],
		["application/vnd.kde.kontour", "kon"],
		["application/vnd.kde.kpresenter", "kpr"],
		["application/vnd.kde.kspread", "ksp"],
		["application/vnd.kde.kword", "kwd"],
		["application/vnd.kenameaapp", "htke"],
		["application/vnd.kidspiration", "kia"],
		["application/vnd.kinar", "kne"],
		["application/vnd.koan", "skp"],
		["application/vnd.kodak-descriptor", "sse"],
		["application/vnd.las.las+xml", "lasxml"],
		["application/vnd.llamagraphics.life-balance.desktop", "lbd"],
		["application/vnd.llamagraphics.life-balance.exchange+xml", "lbe"],
		["application/vnd.lotus-1-2-3", "123"],
		["application/vnd.lotus-approach", "apr"],
		["application/vnd.lotus-freelance", "pre"],
		["application/vnd.lotus-notes", "nsf"],
		["application/vnd.lotus-organizer", "org"],
		["application/vnd.lotus-screencam", "scm"],
		["application/vnd.lotus-wordpro", "lwp"],
		["application/vnd.macports.portpkg", "portpkg"],
		["application/vnd.mcd", "mcd"],
		["application/vnd.medcalcdata", "mc1"],
		["application/vnd.mediastation.cdkey", "cdkey"],
		["application/vnd.mfer", "mwf"],
		["application/vnd.mfmp", "mfm"],
		["application/vnd.micrografx.flo", "flo"],
		["application/vnd.micrografx.igx", "igx"],
		["application/vnd.mif", "mif"],
		["application/vnd.mobius.daf", "daf"],
		["application/vnd.mobius.dis", "dis"],
		["application/vnd.mobius.mbk", "mbk"],
		["application/vnd.mobius.mqy", "mqy"],
		["application/vnd.mobius.msl", "msl"],
		["application/vnd.mobius.plc", "plc"],
		["application/vnd.mobius.txf", "txf"],
		["application/vnd.mophun.application", "mpn"],
		["application/vnd.mophun.certificate", "mpc"],
		["application/vnd.mozilla.xul+xml", "xul"],
		["application/vnd.ms-artgalry", "cil"],
		["application/vnd.ms-cab-compressed", "cab"],
		["application/vnd.ms-excel", [
			"xls",
			"xla",
			"xlc",
			"xlm",
			"xlt",
			"xlw",
			"xlb",
			"xll"
		]],
		["application/vnd.ms-excel.addin.macroenabled.12", "xlam"],
		["application/vnd.ms-excel.sheet.binary.macroenabled.12", "xlsb"],
		["application/vnd.ms-excel.sheet.macroenabled.12", "xlsm"],
		["application/vnd.ms-excel.template.macroenabled.12", "xltm"],
		["application/vnd.ms-fontobject", "eot"],
		["application/vnd.ms-htmlhelp", "chm"],
		["application/vnd.ms-ims", "ims"],
		["application/vnd.ms-lrm", "lrm"],
		["application/vnd.ms-officetheme", "thmx"],
		["application/vnd.ms-outlook", "msg"],
		["application/vnd.ms-pki.certstore", "sst"],
		["application/vnd.ms-pki.pko", "pko"],
		["application/vnd.ms-pki.seccat", "cat"],
		["application/vnd.ms-pki.stl", "stl"],
		["application/vnd.ms-pkicertstore", "sst"],
		["application/vnd.ms-pkiseccat", "cat"],
		["application/vnd.ms-pkistl", "stl"],
		["application/vnd.ms-powerpoint", [
			"ppt",
			"pot",
			"pps",
			"ppa",
			"pwz"
		]],
		["application/vnd.ms-powerpoint.addin.macroenabled.12", "ppam"],
		["application/vnd.ms-powerpoint.presentation.macroenabled.12", "pptm"],
		["application/vnd.ms-powerpoint.slide.macroenabled.12", "sldm"],
		["application/vnd.ms-powerpoint.slideshow.macroenabled.12", "ppsm"],
		["application/vnd.ms-powerpoint.template.macroenabled.12", "potm"],
		["application/vnd.ms-project", "mpp"],
		["application/vnd.ms-word.document.macroenabled.12", "docm"],
		["application/vnd.ms-word.template.macroenabled.12", "dotm"],
		["application/vnd.ms-works", [
			"wks",
			"wcm",
			"wdb",
			"wps"
		]],
		["application/vnd.ms-wpl", "wpl"],
		["application/vnd.ms-xpsdocument", "xps"],
		["application/vnd.mseq", "mseq"],
		["application/vnd.musician", "mus"],
		["application/vnd.muvee.style", "msty"],
		["application/vnd.neurolanguage.nlu", "nlu"],
		["application/vnd.noblenet-directory", "nnd"],
		["application/vnd.noblenet-sealer", "nns"],
		["application/vnd.noblenet-web", "nnw"],
		["application/vnd.nokia.configuration-message", "ncm"],
		["application/vnd.nokia.n-gage.data", "ngdat"],
		["application/vnd.nokia.n-gage.symbian.install", "n-gage"],
		["application/vnd.nokia.radio-preset", "rpst"],
		["application/vnd.nokia.radio-presets", "rpss"],
		["application/vnd.nokia.ringing-tone", "rng"],
		["application/vnd.novadigm.edm", "edm"],
		["application/vnd.novadigm.edx", "edx"],
		["application/vnd.novadigm.ext", "ext"],
		["application/vnd.oasis.opendocument.chart", "odc"],
		["application/vnd.oasis.opendocument.chart-template", "otc"],
		["application/vnd.oasis.opendocument.database", "odb"],
		["application/vnd.oasis.opendocument.formula", "odf"],
		["application/vnd.oasis.opendocument.formula-template", "odft"],
		["application/vnd.oasis.opendocument.graphics", "odg"],
		["application/vnd.oasis.opendocument.graphics-template", "otg"],
		["application/vnd.oasis.opendocument.image", "odi"],
		["application/vnd.oasis.opendocument.image-template", "oti"],
		["application/vnd.oasis.opendocument.presentation", "odp"],
		["application/vnd.oasis.opendocument.presentation-template", "otp"],
		["application/vnd.oasis.opendocument.spreadsheet", "ods"],
		["application/vnd.oasis.opendocument.spreadsheet-template", "ots"],
		["application/vnd.oasis.opendocument.text", "odt"],
		["application/vnd.oasis.opendocument.text-master", "odm"],
		["application/vnd.oasis.opendocument.text-template", "ott"],
		["application/vnd.oasis.opendocument.text-web", "oth"],
		["application/vnd.olpc-sugar", "xo"],
		["application/vnd.oma.dd2+xml", "dd2"],
		["application/vnd.openofficeorg.extension", "oxt"],
		["application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"],
		["application/vnd.openxmlformats-officedocument.presentationml.slide", "sldx"],
		["application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx"],
		["application/vnd.openxmlformats-officedocument.presentationml.template", "potx"],
		["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"],
		["application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx"],
		["application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"],
		["application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx"],
		["application/vnd.osgeo.mapguide.package", "mgp"],
		["application/vnd.osgi.dp", "dp"],
		["application/vnd.palm", "pdb"],
		["application/vnd.pawaafile", "paw"],
		["application/vnd.pg.format", "str"],
		["application/vnd.pg.osasli", "ei6"],
		["application/vnd.picsel", "efif"],
		["application/vnd.pmi.widget", "wg"],
		["application/vnd.pocketlearn", "plf"],
		["application/vnd.powerbuilder6", "pbd"],
		["application/vnd.previewsystems.box", "box"],
		["application/vnd.proteus.magazine", "mgz"],
		["application/vnd.publishare-delta-tree", "qps"],
		["application/vnd.pvi.ptid1", "ptid"],
		["application/vnd.quark.quarkxpress", "qxd"],
		["application/vnd.realvnc.bed", "bed"],
		["application/vnd.recordare.musicxml", "mxl"],
		["application/vnd.recordare.musicxml+xml", "musicxml"],
		["application/vnd.rig.cryptonote", "cryptonote"],
		["application/vnd.rim.cod", "cod"],
		["application/vnd.rn-realmedia", "rm"],
		["application/vnd.rn-realplayer", "rnx"],
		["application/vnd.route66.link66+xml", "link66"],
		["application/vnd.sailingtracker.track", "st"],
		["application/vnd.seemail", "see"],
		["application/vnd.sema", "sema"],
		["application/vnd.semd", "semd"],
		["application/vnd.semf", "semf"],
		["application/vnd.shana.informed.formdata", "ifm"],
		["application/vnd.shana.informed.formtemplate", "itp"],
		["application/vnd.shana.informed.interchange", "iif"],
		["application/vnd.shana.informed.package", "ipk"],
		["application/vnd.simtech-mindmapper", "twd"],
		["application/vnd.smaf", "mmf"],
		["application/vnd.smart.teacher", "teacher"],
		["application/vnd.solent.sdkm+xml", "sdkm"],
		["application/vnd.spotfire.dxp", "dxp"],
		["application/vnd.spotfire.sfs", "sfs"],
		["application/vnd.stardivision.calc", "sdc"],
		["application/vnd.stardivision.draw", "sda"],
		["application/vnd.stardivision.impress", "sdd"],
		["application/vnd.stardivision.math", "smf"],
		["application/vnd.stardivision.writer", "sdw"],
		["application/vnd.stardivision.writer-global", "sgl"],
		["application/vnd.stepmania.stepchart", "sm"],
		["application/vnd.sun.xml.calc", "sxc"],
		["application/vnd.sun.xml.calc.template", "stc"],
		["application/vnd.sun.xml.draw", "sxd"],
		["application/vnd.sun.xml.draw.template", "std"],
		["application/vnd.sun.xml.impress", "sxi"],
		["application/vnd.sun.xml.impress.template", "sti"],
		["application/vnd.sun.xml.math", "sxm"],
		["application/vnd.sun.xml.writer", "sxw"],
		["application/vnd.sun.xml.writer.global", "sxg"],
		["application/vnd.sun.xml.writer.template", "stw"],
		["application/vnd.sus-calendar", "sus"],
		["application/vnd.svd", "svd"],
		["application/vnd.symbian.install", "sis"],
		["application/vnd.syncml+xml", "xsm"],
		["application/vnd.syncml.dm+wbxml", "bdm"],
		["application/vnd.syncml.dm+xml", "xdm"],
		["application/vnd.tao.intent-module-archive", "tao"],
		["application/vnd.tmobile-livetv", "tmo"],
		["application/vnd.trid.tpt", "tpt"],
		["application/vnd.triscape.mxs", "mxs"],
		["application/vnd.trueapp", "tra"],
		["application/vnd.ufdl", "ufd"],
		["application/vnd.uiq.theme", "utz"],
		["application/vnd.umajin", "umj"],
		["application/vnd.unity", "unityweb"],
		["application/vnd.uoml+xml", "uoml"],
		["application/vnd.vcx", "vcx"],
		["application/vnd.visio", "vsd"],
		["application/vnd.visionary", "vis"],
		["application/vnd.vsf", "vsf"],
		["application/vnd.wap.wbxml", "wbxml"],
		["application/vnd.wap.wmlc", "wmlc"],
		["application/vnd.wap.wmlscriptc", "wmlsc"],
		["application/vnd.webturbo", "wtb"],
		["application/vnd.wolfram.player", "nbp"],
		["application/vnd.wordperfect", "wpd"],
		["application/vnd.wqd", "wqd"],
		["application/vnd.wt.stf", "stf"],
		["application/vnd.xara", ["web", "xar"]],
		["application/vnd.xfdl", "xfdl"],
		["application/vnd.yamaha.hv-dic", "hvd"],
		["application/vnd.yamaha.hv-script", "hvs"],
		["application/vnd.yamaha.hv-voice", "hvp"],
		["application/vnd.yamaha.openscoreformat", "osf"],
		["application/vnd.yamaha.openscoreformat.osfpvg+xml", "osfpvg"],
		["application/vnd.yamaha.smaf-audio", "saf"],
		["application/vnd.yamaha.smaf-phrase", "spf"],
		["application/vnd.yellowriver-custom-menu", "cmp"],
		["application/vnd.zul", "zir"],
		["application/vnd.zzazz.deck+xml", "zaz"],
		["application/vocaltec-media-desc", "vmd"],
		["application/vocaltec-media-file", "vmf"],
		["application/voicexml+xml", "vxml"],
		["application/widget", "wgt"],
		["application/winhlp", "hlp"],
		["application/wordperfect", [
			"wp",
			"wp5",
			"wp6",
			"wpd"
		]],
		["application/wordperfect6.0", ["w60", "wp5"]],
		["application/wordperfect6.1", "w61"],
		["application/wsdl+xml", "wsdl"],
		["application/wspolicy+xml", "wspolicy"],
		["application/x-123", "wk1"],
		["application/x-7z-compressed", "7z"],
		["application/x-abiword", "abw"],
		["application/x-ace-compressed", "ace"],
		["application/x-aim", "aim"],
		["application/x-authorware-bin", "aab"],
		["application/x-authorware-map", "aam"],
		["application/x-authorware-seg", "aas"],
		["application/x-bcpio", "bcpio"],
		["application/x-binary", "bin"],
		["application/x-binhex40", "hqx"],
		["application/x-bittorrent", "torrent"],
		["application/x-bsh", [
			"bsh",
			"sh",
			"shar"
		]],
		["application/x-bytecode.elisp", "elc"],
		["application/x-bytecode.python", "pyc"],
		["application/x-bzip", "bz"],
		["application/x-bzip2", ["boz", "bz2"]],
		["application/x-cdf", "cdf"],
		["application/x-cdlink", "vcd"],
		["application/x-chat", ["cha", "chat"]],
		["application/x-chess-pgn", "pgn"],
		["application/x-cmu-raster", "ras"],
		["application/x-cocoa", "cco"],
		["application/x-compactpro", "cpt"],
		["application/x-compress", "z"],
		["application/x-compressed", [
			"tgz",
			"gz",
			"z",
			"zip"
		]],
		["application/x-conference", "nsc"],
		["application/x-cpio", "cpio"],
		["application/x-cpt", "cpt"],
		["application/x-csh", "csh"],
		["application/x-debian-package", "deb"],
		["application/x-deepv", "deepv"],
		["application/x-director", [
			"dir",
			"dcr",
			"dxr"
		]],
		["application/x-doom", "wad"],
		["application/x-dtbncx+xml", "ncx"],
		["application/x-dtbook+xml", "dtb"],
		["application/x-dtbresource+xml", "res"],
		["application/x-dvi", "dvi"],
		["application/x-elc", "elc"],
		["application/x-envoy", ["env", "evy"]],
		["application/x-esrehber", "es"],
		["application/x-excel", [
			"xls",
			"xla",
			"xlb",
			"xlc",
			"xld",
			"xlk",
			"xll",
			"xlm",
			"xlt",
			"xlv",
			"xlw"
		]],
		["application/x-font-bdf", "bdf"],
		["application/x-font-ghostscript", "gsf"],
		["application/x-font-linux-psf", "psf"],
		["application/x-font-otf", "otf"],
		["application/x-font-pcf", "pcf"],
		["application/x-font-snf", "snf"],
		["application/x-font-ttf", "ttf"],
		["application/x-font-type1", "pfa"],
		["application/x-font-woff", "woff"],
		["application/x-frame", "mif"],
		["application/x-freelance", "pre"],
		["application/x-futuresplash", "spl"],
		["application/x-gnumeric", "gnumeric"],
		["application/x-gsp", "gsp"],
		["application/x-gss", "gss"],
		["application/x-gtar", "gtar"],
		["application/x-gzip", ["gz", "gzip"]],
		["application/x-hdf", "hdf"],
		["application/x-helpfile", ["help", "hlp"]],
		["application/x-httpd-imap", "imap"],
		["application/x-ima", "ima"],
		["application/x-internet-signup", ["ins", "isp"]],
		["application/x-internett-signup", "ins"],
		["application/x-inventor", "iv"],
		["application/x-ip2", "ip"],
		["application/x-iphone", "iii"],
		["application/x-java-class", "class"],
		["application/x-java-commerce", "jcm"],
		["application/x-java-jnlp-file", "jnlp"],
		["application/x-javascript", "js"],
		["application/x-koan", [
			"skd",
			"skm",
			"skp",
			"skt"
		]],
		["application/x-ksh", "ksh"],
		["application/x-latex", ["latex", "ltx"]],
		["application/x-lha", "lha"],
		["application/x-lisp", "lsp"],
		["application/x-livescreen", "ivy"],
		["application/x-lotus", "wq1"],
		["application/x-lotusscreencam", "scm"],
		["application/x-lzh", "lzh"],
		["application/x-lzx", "lzx"],
		["application/x-mac-binhex40", "hqx"],
		["application/x-macbinary", "bin"],
		["application/x-magic-cap-package-1.0", "mc$"],
		["application/x-mathcad", "mcd"],
		["application/x-meme", "mm"],
		["application/x-midi", ["mid", "midi"]],
		["application/x-mif", "mif"],
		["application/x-mix-transfer", "nix"],
		["application/x-mobipocket-ebook", "prc"],
		["application/x-mplayer2", "asx"],
		["application/x-ms-application", "application"],
		["application/x-ms-wmd", "wmd"],
		["application/x-ms-wmz", "wmz"],
		["application/x-ms-xbap", "xbap"],
		["application/x-msaccess", "mdb"],
		["application/x-msbinder", "obd"],
		["application/x-mscardfile", "crd"],
		["application/x-msclip", "clp"],
		["application/x-msdownload", ["exe", "dll"]],
		["application/x-msexcel", [
			"xls",
			"xla",
			"xlw"
		]],
		["application/x-msmediaview", [
			"mvb",
			"m13",
			"m14"
		]],
		["application/x-msmetafile", "wmf"],
		["application/x-msmoney", "mny"],
		["application/x-mspowerpoint", "ppt"],
		["application/x-mspublisher", "pub"],
		["application/x-msschedule", "scd"],
		["application/x-msterminal", "trm"],
		["application/x-mswrite", "wri"],
		["application/x-navi-animation", "ani"],
		["application/x-navidoc", "nvd"],
		["application/x-navimap", "map"],
		["application/x-navistyle", "stl"],
		["application/x-netcdf", ["cdf", "nc"]],
		["application/x-newton-compatible-pkg", "pkg"],
		["application/x-nokia-9000-communicator-add-on-software", "aos"],
		["application/x-omc", "omc"],
		["application/x-omcdatamaker", "omcd"],
		["application/x-omcregerator", "omcr"],
		["application/x-pagemaker", ["pm4", "pm5"]],
		["application/x-pcl", "pcl"],
		["application/x-perfmon", [
			"pma",
			"pmc",
			"pml",
			"pmr",
			"pmw"
		]],
		["application/x-pixclscript", "plx"],
		["application/x-pkcs10", "p10"],
		["application/x-pkcs12", ["p12", "pfx"]],
		["application/x-pkcs7-certificates", ["p7b", "spc"]],
		["application/x-pkcs7-certreqresp", "p7r"],
		["application/x-pkcs7-mime", ["p7m", "p7c"]],
		["application/x-pkcs7-signature", ["p7s", "p7a"]],
		["application/x-pointplus", "css"],
		["application/x-portable-anymap", "pnm"],
		["application/x-project", [
			"mpc",
			"mpt",
			"mpv",
			"mpx"
		]],
		["application/x-qpro", "wb1"],
		["application/x-rar-compressed", "rar"],
		["application/x-rtf", "rtf"],
		["application/x-sdp", "sdp"],
		["application/x-sea", "sea"],
		["application/x-seelogo", "sl"],
		["application/x-sh", "sh"],
		["application/x-shar", ["shar", "sh"]],
		["application/x-shockwave-flash", "swf"],
		["application/x-silverlight-app", "xap"],
		["application/x-sit", "sit"],
		["application/x-sprite", ["spr", "sprite"]],
		["application/x-stuffit", "sit"],
		["application/x-stuffitx", "sitx"],
		["application/x-sv4cpio", "sv4cpio"],
		["application/x-sv4crc", "sv4crc"],
		["application/x-tar", "tar"],
		["application/x-tbook", ["sbk", "tbk"]],
		["application/x-tcl", "tcl"],
		["application/x-tex", "tex"],
		["application/x-tex-tfm", "tfm"],
		["application/x-texinfo", ["texi", "texinfo"]],
		["application/x-troff", [
			"roff",
			"t",
			"tr"
		]],
		["application/x-troff-man", "man"],
		["application/x-troff-me", "me"],
		["application/x-troff-ms", "ms"],
		["application/x-troff-msvideo", "avi"],
		["application/x-ustar", "ustar"],
		["application/x-visio", [
			"vsd",
			"vst",
			"vsw"
		]],
		["application/x-vnd.audioexplosion.mzz", "mzz"],
		["application/x-vnd.ls-xpix", "xpix"],
		["application/x-vrml", "vrml"],
		["application/x-wais-source", ["src", "wsrc"]],
		["application/x-winhelp", "hlp"],
		["application/x-wintalk", "wtk"],
		["application/x-world", ["wrl", "svr"]],
		["application/x-wpwin", "wpd"],
		["application/x-wri", "wri"],
		["application/x-x509-ca-cert", [
			"cer",
			"crt",
			"der"
		]],
		["application/x-x509-user-cert", "crt"],
		["application/x-xfig", "fig"],
		["application/x-xpinstall", "xpi"],
		["application/x-zip-compressed", "zip"],
		["application/xcap-diff+xml", "xdf"],
		["application/xenc+xml", "xenc"],
		["application/xhtml+xml", "xhtml"],
		["application/xml", "xml"],
		["application/xml-dtd", "dtd"],
		["application/xop+xml", "xop"],
		["application/xslt+xml", "xslt"],
		["application/xspf+xml", "xspf"],
		["application/xv+xml", "mxml"],
		["application/yang", "yang"],
		["application/yin+xml", "yin"],
		["application/ynd.ms-pkipko", "pko"],
		["application/zip", "zip"],
		["audio/adpcm", "adp"],
		["audio/aiff", [
			"aiff",
			"aif",
			"aifc"
		]],
		["audio/basic", ["snd", "au"]],
		["audio/it", "it"],
		["audio/make", [
			"funk",
			"my",
			"pfunk"
		]],
		["audio/make.my.funk", "pfunk"],
		["audio/mid", ["mid", "rmi"]],
		["audio/midi", [
			"midi",
			"kar",
			"mid"
		]],
		["audio/mod", "mod"],
		["audio/mp4", "mp4a"],
		["audio/mpeg", [
			"mpga",
			"mp3",
			"m2a",
			"mp2",
			"mpa",
			"mpg"
		]],
		["audio/mpeg3", "mp3"],
		["audio/nspaudio", ["la", "lma"]],
		["audio/ogg", "oga"],
		["audio/s3m", "s3m"],
		["audio/tsp-audio", "tsi"],
		["audio/tsplayer", "tsp"],
		["audio/vnd.dece.audio", "uva"],
		["audio/vnd.digital-winds", "eol"],
		["audio/vnd.dra", "dra"],
		["audio/vnd.dts", "dts"],
		["audio/vnd.dts.hd", "dtshd"],
		["audio/vnd.lucent.voice", "lvp"],
		["audio/vnd.ms-playready.media.pya", "pya"],
		["audio/vnd.nuera.ecelp4800", "ecelp4800"],
		["audio/vnd.nuera.ecelp7470", "ecelp7470"],
		["audio/vnd.nuera.ecelp9600", "ecelp9600"],
		["audio/vnd.qcelp", "qcp"],
		["audio/vnd.rip", "rip"],
		["audio/voc", "voc"],
		["audio/voxware", "vox"],
		["audio/wav", "wav"],
		["audio/webm", "weba"],
		["audio/x-aac", "aac"],
		["audio/x-adpcm", "snd"],
		["audio/x-aiff", [
			"aiff",
			"aif",
			"aifc"
		]],
		["audio/x-au", "au"],
		["audio/x-gsm", ["gsd", "gsm"]],
		["audio/x-jam", "jam"],
		["audio/x-liveaudio", "lam"],
		["audio/x-mid", ["mid", "midi"]],
		["audio/x-midi", ["midi", "mid"]],
		["audio/x-mod", "mod"],
		["audio/x-mpeg", "mp2"],
		["audio/x-mpeg-3", "mp3"],
		["audio/x-mpegurl", "m3u"],
		["audio/x-mpequrl", "m3u"],
		["audio/x-ms-wax", "wax"],
		["audio/x-ms-wma", "wma"],
		["audio/x-nspaudio", ["la", "lma"]],
		["audio/x-pn-realaudio", [
			"ra",
			"ram",
			"rm",
			"rmm",
			"rmp"
		]],
		["audio/x-pn-realaudio-plugin", [
			"ra",
			"rmp",
			"rpm"
		]],
		["audio/x-psid", "sid"],
		["audio/x-realaudio", "ra"],
		["audio/x-twinvq", "vqf"],
		["audio/x-twinvq-plugin", ["vqe", "vql"]],
		["audio/x-vnd.audioexplosion.mjuicemediafile", "mjf"],
		["audio/x-voc", "voc"],
		["audio/x-wav", "wav"],
		["audio/xm", "xm"],
		["chemical/x-cdx", "cdx"],
		["chemical/x-cif", "cif"],
		["chemical/x-cmdf", "cmdf"],
		["chemical/x-cml", "cml"],
		["chemical/x-csml", "csml"],
		["chemical/x-pdb", ["pdb", "xyz"]],
		["chemical/x-xyz", "xyz"],
		["drawing/x-dwf", "dwf"],
		["i-world/i-vrml", "ivr"],
		["image/bmp", ["bmp", "bm"]],
		["image/cgm", "cgm"],
		["image/cis-cod", "cod"],
		["image/cmu-raster", ["ras", "rast"]],
		["image/fif", "fif"],
		["image/florian", ["flo", "turbot"]],
		["image/g3fax", "g3"],
		["image/gif", "gif"],
		["image/ief", ["ief", "iefs"]],
		["image/jpeg", [
			"jpeg",
			"jpe",
			"jpg",
			"jfif",
			"jfif-tbnl"
		]],
		["image/jutvision", "jut"],
		["image/ktx", "ktx"],
		["image/naplps", ["nap", "naplps"]],
		["image/pict", ["pic", "pict"]],
		["image/pipeg", "jfif"],
		["image/pjpeg", [
			"jfif",
			"jpe",
			"jpeg",
			"jpg"
		]],
		["image/png", ["png", "x-png"]],
		["image/prs.btif", "btif"],
		["image/svg+xml", "svg"],
		["image/tiff", ["tif", "tiff"]],
		["image/vasa", "mcf"],
		["image/vnd.adobe.photoshop", "psd"],
		["image/vnd.dece.graphic", "uvi"],
		["image/vnd.djvu", "djvu"],
		["image/vnd.dvb.subtitle", "sub"],
		["image/vnd.dwg", [
			"dwg",
			"dxf",
			"svf"
		]],
		["image/vnd.dxf", "dxf"],
		["image/vnd.fastbidsheet", "fbs"],
		["image/vnd.fpx", "fpx"],
		["image/vnd.fst", "fst"],
		["image/vnd.fujixerox.edmics-mmr", "mmr"],
		["image/vnd.fujixerox.edmics-rlc", "rlc"],
		["image/vnd.ms-modi", "mdi"],
		["image/vnd.net-fpx", ["fpx", "npx"]],
		["image/vnd.rn-realflash", "rf"],
		["image/vnd.rn-realpix", "rp"],
		["image/vnd.wap.wbmp", "wbmp"],
		["image/vnd.xiff", "xif"],
		["image/webp", "webp"],
		["image/x-cmu-raster", "ras"],
		["image/x-cmx", "cmx"],
		["image/x-dwg", [
			"dwg",
			"dxf",
			"svf"
		]],
		["image/x-freehand", "fh"],
		["image/x-icon", "ico"],
		["image/x-jg", "art"],
		["image/x-jps", "jps"],
		["image/x-niff", ["niff", "nif"]],
		["image/x-pcx", "pcx"],
		["image/x-pict", ["pct", "pic"]],
		["image/x-portable-anymap", "pnm"],
		["image/x-portable-bitmap", "pbm"],
		["image/x-portable-graymap", "pgm"],
		["image/x-portable-greymap", "pgm"],
		["image/x-portable-pixmap", "ppm"],
		["image/x-quicktime", [
			"qif",
			"qti",
			"qtif"
		]],
		["image/x-rgb", "rgb"],
		["image/x-tiff", ["tif", "tiff"]],
		["image/x-windows-bmp", "bmp"],
		["image/x-xbitmap", "xbm"],
		["image/x-xbm", "xbm"],
		["image/x-xpixmap", ["xpm", "pm"]],
		["image/x-xwd", "xwd"],
		["image/x-xwindowdump", "xwd"],
		["image/xbm", "xbm"],
		["image/xpm", "xpm"],
		["message/rfc822", [
			"eml",
			"mht",
			"mhtml",
			"nws",
			"mime"
		]],
		["model/iges", ["iges", "igs"]],
		["model/mesh", "msh"],
		["model/vnd.collada+xml", "dae"],
		["model/vnd.dwf", "dwf"],
		["model/vnd.gdl", "gdl"],
		["model/vnd.gtw", "gtw"],
		["model/vnd.mts", "mts"],
		["model/vnd.vtu", "vtu"],
		["model/vrml", [
			"vrml",
			"wrl",
			"wrz"
		]],
		["model/x-pov", "pov"],
		["multipart/x-gzip", "gzip"],
		["multipart/x-ustar", "ustar"],
		["multipart/x-zip", "zip"],
		["music/crescendo", ["mid", "midi"]],
		["music/x-karaoke", "kar"],
		["paleovu/x-pv", "pvu"],
		["text/asp", "asp"],
		["text/calendar", "ics"],
		["text/css", "css"],
		["text/csv", "csv"],
		["text/ecmascript", "js"],
		["text/h323", "323"],
		["text/html", [
			"html",
			"htm",
			"stm",
			"acgi",
			"htmls",
			"htx",
			"shtml"
		]],
		["text/iuls", "uls"],
		["text/javascript", "js"],
		["text/mcf", "mcf"],
		["text/n3", "n3"],
		["text/pascal", "pas"],
		["text/plain", [
			"txt",
			"bas",
			"c",
			"h",
			"c++",
			"cc",
			"com",
			"conf",
			"cxx",
			"def",
			"f",
			"f90",
			"for",
			"g",
			"hh",
			"idc",
			"jav",
			"java",
			"list",
			"log",
			"lst",
			"m",
			"mar",
			"pl",
			"sdml",
			"text"
		]],
		["text/plain-bas", "par"],
		["text/prs.lines.tag", "dsc"],
		["text/richtext", [
			"rtx",
			"rt",
			"rtf"
		]],
		["text/scriplet", "wsc"],
		["text/scriptlet", "sct"],
		["text/sgml", ["sgm", "sgml"]],
		["text/tab-separated-values", "tsv"],
		["text/troff", "t"],
		["text/turtle", "ttl"],
		["text/uri-list", [
			"uni",
			"unis",
			"uri",
			"uris"
		]],
		["text/vnd.abc", "abc"],
		["text/vnd.curl", "curl"],
		["text/vnd.curl.dcurl", "dcurl"],
		["text/vnd.curl.mcurl", "mcurl"],
		["text/vnd.curl.scurl", "scurl"],
		["text/vnd.fly", "fly"],
		["text/vnd.fmi.flexstor", "flx"],
		["text/vnd.graphviz", "gv"],
		["text/vnd.in3d.3dml", "3dml"],
		["text/vnd.in3d.spot", "spot"],
		["text/vnd.rn-realtext", "rt"],
		["text/vnd.sun.j2me.app-descriptor", "jad"],
		["text/vnd.wap.wml", "wml"],
		["text/vnd.wap.wmlscript", "wmls"],
		["text/webviewhtml", "htt"],
		["text/x-asm", ["asm", "s"]],
		["text/x-audiosoft-intra", "aip"],
		["text/x-c", [
			"c",
			"cc",
			"cpp"
		]],
		["text/x-component", "htc"],
		["text/x-fortran", [
			"for",
			"f",
			"f77",
			"f90"
		]],
		["text/x-h", ["h", "hh"]],
		["text/x-java-source", ["java", "jav"]],
		["text/x-java-source,java", "java"],
		["text/x-la-asf", "lsx"],
		["text/x-m", "m"],
		["text/x-pascal", "p"],
		["text/x-script", "hlb"],
		["text/x-script.csh", "csh"],
		["text/x-script.elisp", "el"],
		["text/x-script.guile", "scm"],
		["text/x-script.ksh", "ksh"],
		["text/x-script.lisp", "lsp"],
		["text/x-script.perl", "pl"],
		["text/x-script.perl-module", "pm"],
		["text/x-script.phyton", "py"],
		["text/x-script.rexx", "rexx"],
		["text/x-script.scheme", "scm"],
		["text/x-script.sh", "sh"],
		["text/x-script.tcl", "tcl"],
		["text/x-script.tcsh", "tcsh"],
		["text/x-script.zsh", "zsh"],
		["text/x-server-parsed-html", ["shtml", "ssi"]],
		["text/x-setext", "etx"],
		["text/x-sgml", ["sgm", "sgml"]],
		["text/x-speech", ["spc", "talk"]],
		["text/x-uil", "uil"],
		["text/x-uuencode", ["uu", "uue"]],
		["text/x-vcalendar", "vcs"],
		["text/x-vcard", "vcf"],
		["text/xml", "xml"],
		["video/3gpp", "3gp"],
		["video/3gpp2", "3g2"],
		["video/animaflex", "afl"],
		["video/avi", "avi"],
		["video/avs-video", "avs"],
		["video/dl", "dl"],
		["video/fli", "fli"],
		["video/gl", "gl"],
		["video/h261", "h261"],
		["video/h263", "h263"],
		["video/h264", "h264"],
		["video/jpeg", "jpgv"],
		["video/jpm", "jpm"],
		["video/mj2", "mj2"],
		["video/mp4", "mp4"],
		["video/mpeg", [
			"mpeg",
			"mp2",
			"mpa",
			"mpe",
			"mpg",
			"mpv2",
			"m1v",
			"m2v",
			"mp3"
		]],
		["video/msvideo", "avi"],
		["video/ogg", "ogv"],
		["video/quicktime", [
			"mov",
			"qt",
			"moov"
		]],
		["video/vdo", "vdo"],
		["video/vivo", ["viv", "vivo"]],
		["video/vnd.dece.hd", "uvh"],
		["video/vnd.dece.mobile", "uvm"],
		["video/vnd.dece.pd", "uvp"],
		["video/vnd.dece.sd", "uvs"],
		["video/vnd.dece.video", "uvv"],
		["video/vnd.fvt", "fvt"],
		["video/vnd.mpegurl", "mxu"],
		["video/vnd.ms-playready.media.pyv", "pyv"],
		["video/vnd.rn-realvideo", "rv"],
		["video/vnd.uvvu.mp4", "uvu"],
		["video/vnd.vivo", ["viv", "vivo"]],
		["video/vosaic", "vos"],
		["video/webm", "webm"],
		["video/x-amt-demorun", "xdr"],
		["video/x-amt-showrun", "xsr"],
		["video/x-atomic3d-feature", "fmf"],
		["video/x-dl", "dl"],
		["video/x-dv", ["dif", "dv"]],
		["video/x-f4v", "f4v"],
		["video/x-fli", "fli"],
		["video/x-flv", "flv"],
		["video/x-gl", "gl"],
		["video/x-isvideo", "isu"],
		["video/x-la-asf", ["lsf", "lsx"]],
		["video/x-m4v", "m4v"],
		["video/x-motion-jpeg", "mjpg"],
		["video/x-mpeg", ["mp3", "mp2"]],
		["video/x-mpeq2a", "mp2"],
		["video/x-ms-asf", [
			"asf",
			"asr",
			"asx"
		]],
		["video/x-ms-asf-plugin", "asx"],
		["video/x-ms-wm", "wm"],
		["video/x-ms-wmv", "wmv"],
		["video/x-ms-wmx", "wmx"],
		["video/x-ms-wvx", "wvx"],
		["video/x-msvideo", "avi"],
		["video/x-qtc", "qtc"],
		["video/x-scm", "scm"],
		["video/x-sgi-movie", ["movie", "mv"]],
		["windows/metafile", "wmf"],
		["www/mime", "mime"],
		["x-conference/x-cooltalk", "ice"],
		["x-music/x-midi", ["mid", "midi"]],
		["x-world/x-3dmf", [
			"3dm",
			"3dmf",
			"qd3",
			"qd3d"
		]],
		["x-world/x-svr", "svr"],
		["x-world/x-vrml", [
			"flr",
			"vrml",
			"wrl",
			"wrz",
			"xaf",
			"xof"
		]],
		["x-world/x-vrt", "vrt"],
		["xgl/drawing", "xgz"],
		["xgl/movie", "xmz"]
	]);
	var extensions = /* @__PURE__ */ new Map([
		["123", "application/vnd.lotus-1-2-3"],
		["323", "text/h323"],
		["*", "application/octet-stream"],
		["3dm", "x-world/x-3dmf"],
		["3dmf", "x-world/x-3dmf"],
		["3dml", "text/vnd.in3d.3dml"],
		["3g2", "video/3gpp2"],
		["3gp", "video/3gpp"],
		["7z", "application/x-7z-compressed"],
		["a", "application/octet-stream"],
		["aab", "application/x-authorware-bin"],
		["aac", "audio/x-aac"],
		["aam", "application/x-authorware-map"],
		["aas", "application/x-authorware-seg"],
		["abc", "text/vnd.abc"],
		["abw", "application/x-abiword"],
		["ac", "application/pkix-attr-cert"],
		["acc", "application/vnd.americandynamics.acc"],
		["ace", "application/x-ace-compressed"],
		["acgi", "text/html"],
		["acu", "application/vnd.acucobol"],
		["acx", "application/internet-property-stream"],
		["adp", "audio/adpcm"],
		["aep", "application/vnd.audiograph"],
		["afl", "video/animaflex"],
		["afp", "application/vnd.ibm.modcap"],
		["ahead", "application/vnd.ahead.space"],
		["ai", "application/postscript"],
		["aif", ["audio/aiff", "audio/x-aiff"]],
		["aifc", ["audio/aiff", "audio/x-aiff"]],
		["aiff", ["audio/aiff", "audio/x-aiff"]],
		["aim", "application/x-aim"],
		["aip", "text/x-audiosoft-intra"],
		["air", "application/vnd.adobe.air-application-installer-package+zip"],
		["ait", "application/vnd.dvb.ait"],
		["ami", "application/vnd.amiga.ami"],
		["ani", "application/x-navi-animation"],
		["aos", "application/x-nokia-9000-communicator-add-on-software"],
		["apk", "application/vnd.android.package-archive"],
		["application", "application/x-ms-application"],
		["apr", "application/vnd.lotus-approach"],
		["aps", "application/mime"],
		["arc", "application/octet-stream"],
		["arj", ["application/arj", "application/octet-stream"]],
		["art", "image/x-jg"],
		["asf", "video/x-ms-asf"],
		["asm", "text/x-asm"],
		["aso", "application/vnd.accpac.simply.aso"],
		["asp", "text/asp"],
		["asr", "video/x-ms-asf"],
		["asx", [
			"video/x-ms-asf",
			"application/x-mplayer2",
			"video/x-ms-asf-plugin"
		]],
		["atc", "application/vnd.acucorp"],
		["atomcat", "application/atomcat+xml"],
		["atomsvc", "application/atomsvc+xml"],
		["atx", "application/vnd.antix.game-component"],
		["au", ["audio/basic", "audio/x-au"]],
		["avi", [
			"video/avi",
			"video/msvideo",
			"application/x-troff-msvideo",
			"video/x-msvideo"
		]],
		["avs", "video/avs-video"],
		["aw", "application/applixware"],
		["axs", "application/olescript"],
		["azf", "application/vnd.airzip.filesecure.azf"],
		["azs", "application/vnd.airzip.filesecure.azs"],
		["azw", "application/vnd.amazon.ebook"],
		["bas", "text/plain"],
		["bcpio", "application/x-bcpio"],
		["bdf", "application/x-font-bdf"],
		["bdm", "application/vnd.syncml.dm+wbxml"],
		["bed", "application/vnd.realvnc.bed"],
		["bh2", "application/vnd.fujitsu.oasysprs"],
		["bin", [
			"application/octet-stream",
			"application/mac-binary",
			"application/macbinary",
			"application/x-macbinary",
			"application/x-binary"
		]],
		["bm", "image/bmp"],
		["bmi", "application/vnd.bmi"],
		["bmp", ["image/bmp", "image/x-windows-bmp"]],
		["boo", "application/book"],
		["book", "application/book"],
		["box", "application/vnd.previewsystems.box"],
		["boz", "application/x-bzip2"],
		["bsh", "application/x-bsh"],
		["btif", "image/prs.btif"],
		["bz", "application/x-bzip"],
		["bz2", "application/x-bzip2"],
		["c", ["text/plain", "text/x-c"]],
		["c++", "text/plain"],
		["c11amc", "application/vnd.cluetrust.cartomobile-config"],
		["c11amz", "application/vnd.cluetrust.cartomobile-config-pkg"],
		["c4g", "application/vnd.clonk.c4group"],
		["cab", "application/vnd.ms-cab-compressed"],
		["car", "application/vnd.curl.car"],
		["cat", ["application/vnd.ms-pkiseccat", "application/vnd.ms-pki.seccat"]],
		["cc", ["text/plain", "text/x-c"]],
		["ccad", "application/clariscad"],
		["cco", "application/x-cocoa"],
		["ccxml", "application/ccxml+xml,"],
		["cdbcmsg", "application/vnd.contact.cmsg"],
		["cdf", [
			"application/cdf",
			"application/x-cdf",
			"application/x-netcdf"
		]],
		["cdkey", "application/vnd.mediastation.cdkey"],
		["cdmia", "application/cdmi-capability"],
		["cdmic", "application/cdmi-container"],
		["cdmid", "application/cdmi-domain"],
		["cdmio", "application/cdmi-object"],
		["cdmiq", "application/cdmi-queue"],
		["cdx", "chemical/x-cdx"],
		["cdxml", "application/vnd.chemdraw+xml"],
		["cdy", "application/vnd.cinderella"],
		["cer", ["application/pkix-cert", "application/x-x509-ca-cert"]],
		["cgm", "image/cgm"],
		["cha", "application/x-chat"],
		["chat", "application/x-chat"],
		["chm", "application/vnd.ms-htmlhelp"],
		["chrt", "application/vnd.kde.kchart"],
		["cif", "chemical/x-cif"],
		["cii", "application/vnd.anser-web-certificate-issue-initiation"],
		["cil", "application/vnd.ms-artgalry"],
		["cla", "application/vnd.claymore"],
		["class", [
			"application/octet-stream",
			"application/java",
			"application/java-byte-code",
			"application/java-vm",
			"application/x-java-class"
		]],
		["clkk", "application/vnd.crick.clicker.keyboard"],
		["clkp", "application/vnd.crick.clicker.palette"],
		["clkt", "application/vnd.crick.clicker.template"],
		["clkw", "application/vnd.crick.clicker.wordbank"],
		["clkx", "application/vnd.crick.clicker"],
		["clp", "application/x-msclip"],
		["cmc", "application/vnd.cosmocaller"],
		["cmdf", "chemical/x-cmdf"],
		["cml", "chemical/x-cml"],
		["cmp", "application/vnd.yellowriver-custom-menu"],
		["cmx", "image/x-cmx"],
		["cod", ["image/cis-cod", "application/vnd.rim.cod"]],
		["com", ["application/octet-stream", "text/plain"]],
		["conf", "text/plain"],
		["cpio", "application/x-cpio"],
		["cpp", "text/x-c"],
		["cpt", [
			"application/mac-compactpro",
			"application/x-compactpro",
			"application/x-cpt"
		]],
		["crd", "application/x-mscardfile"],
		["crl", ["application/pkix-crl", "application/pkcs-crl"]],
		["crt", [
			"application/pkix-cert",
			"application/x-x509-user-cert",
			"application/x-x509-ca-cert"
		]],
		["cryptonote", "application/vnd.rig.cryptonote"],
		["csh", ["text/x-script.csh", "application/x-csh"]],
		["csml", "chemical/x-csml"],
		["csp", "application/vnd.commonspace"],
		["css", ["text/css", "application/x-pointplus"]],
		["csv", "text/csv"],
		["cu", "application/cu-seeme"],
		["curl", "text/vnd.curl"],
		["cww", "application/prs.cww"],
		["cxx", "text/plain"],
		["dae", "model/vnd.collada+xml"],
		["daf", "application/vnd.mobius.daf"],
		["davmount", "application/davmount+xml"],
		["dcr", "application/x-director"],
		["dcurl", "text/vnd.curl.dcurl"],
		["dd2", "application/vnd.oma.dd2+xml"],
		["ddd", "application/vnd.fujixerox.ddd"],
		["deb", "application/x-debian-package"],
		["deepv", "application/x-deepv"],
		["def", "text/plain"],
		["der", "application/x-x509-ca-cert"],
		["dfac", "application/vnd.dreamfactory"],
		["dif", "video/x-dv"],
		["dir", "application/x-director"],
		["dis", "application/vnd.mobius.dis"],
		["djvu", "image/vnd.djvu"],
		["dl", ["video/dl", "video/x-dl"]],
		["dll", "application/x-msdownload"],
		["dms", "application/octet-stream"],
		["dna", "application/vnd.dna"],
		["doc", "application/msword"],
		["docm", "application/vnd.ms-word.document.macroenabled.12"],
		["docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
		["dot", "application/msword"],
		["dotm", "application/vnd.ms-word.template.macroenabled.12"],
		["dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"],
		["dp", ["application/commonground", "application/vnd.osgi.dp"]],
		["dpg", "application/vnd.dpgraph"],
		["dra", "audio/vnd.dra"],
		["drw", "application/drafting"],
		["dsc", "text/prs.lines.tag"],
		["dssc", "application/dssc+der"],
		["dtb", "application/x-dtbook+xml"],
		["dtd", "application/xml-dtd"],
		["dts", "audio/vnd.dts"],
		["dtshd", "audio/vnd.dts.hd"],
		["dump", "application/octet-stream"],
		["dv", "video/x-dv"],
		["dvi", "application/x-dvi"],
		["dwf", ["model/vnd.dwf", "drawing/x-dwf"]],
		["dwg", [
			"application/acad",
			"image/vnd.dwg",
			"image/x-dwg"
		]],
		["dxf", [
			"application/dxf",
			"image/vnd.dwg",
			"image/vnd.dxf",
			"image/x-dwg"
		]],
		["dxp", "application/vnd.spotfire.dxp"],
		["dxr", "application/x-director"],
		["ecelp4800", "audio/vnd.nuera.ecelp4800"],
		["ecelp7470", "audio/vnd.nuera.ecelp7470"],
		["ecelp9600", "audio/vnd.nuera.ecelp9600"],
		["edm", "application/vnd.novadigm.edm"],
		["edx", "application/vnd.novadigm.edx"],
		["efif", "application/vnd.picsel"],
		["ei6", "application/vnd.pg.osasli"],
		["el", "text/x-script.elisp"],
		["elc", ["application/x-elc", "application/x-bytecode.elisp"]],
		["eml", "message/rfc822"],
		["emma", "application/emma+xml"],
		["env", "application/x-envoy"],
		["eol", "audio/vnd.digital-winds"],
		["eot", "application/vnd.ms-fontobject"],
		["eps", "application/postscript"],
		["epub", "application/epub+zip"],
		["es", ["application/ecmascript", "application/x-esrehber"]],
		["es3", "application/vnd.eszigno3+xml"],
		["esf", "application/vnd.epson.esf"],
		["etx", "text/x-setext"],
		["evy", ["application/envoy", "application/x-envoy"]],
		["exe", ["application/octet-stream", "application/x-msdownload"]],
		["exi", "application/exi"],
		["ext", "application/vnd.novadigm.ext"],
		["ez2", "application/vnd.ezpix-album"],
		["ez3", "application/vnd.ezpix-package"],
		["f", ["text/plain", "text/x-fortran"]],
		["f4v", "video/x-f4v"],
		["f77", "text/x-fortran"],
		["f90", ["text/plain", "text/x-fortran"]],
		["fbs", "image/vnd.fastbidsheet"],
		["fcs", "application/vnd.isac.fcs"],
		["fdf", "application/vnd.fdf"],
		["fe_launch", "application/vnd.denovo.fcselayout-link"],
		["fg5", "application/vnd.fujitsu.oasysgp"],
		["fh", "image/x-freehand"],
		["fif", ["application/fractals", "image/fif"]],
		["fig", "application/x-xfig"],
		["fli", ["video/fli", "video/x-fli"]],
		["flo", ["image/florian", "application/vnd.micrografx.flo"]],
		["flr", "x-world/x-vrml"],
		["flv", "video/x-flv"],
		["flw", "application/vnd.kde.kivio"],
		["flx", "text/vnd.fmi.flexstor"],
		["fly", "text/vnd.fly"],
		["fm", "application/vnd.framemaker"],
		["fmf", "video/x-atomic3d-feature"],
		["fnc", "application/vnd.frogans.fnc"],
		["for", ["text/plain", "text/x-fortran"]],
		["fpx", ["image/vnd.fpx", "image/vnd.net-fpx"]],
		["frl", "application/freeloader"],
		["fsc", "application/vnd.fsc.weblaunch"],
		["fst", "image/vnd.fst"],
		["ftc", "application/vnd.fluxtime.clip"],
		["fti", "application/vnd.anser-web-funds-transfer-initiation"],
		["funk", "audio/make"],
		["fvt", "video/vnd.fvt"],
		["fxp", "application/vnd.adobe.fxp"],
		["fzs", "application/vnd.fuzzysheet"],
		["g", "text/plain"],
		["g2w", "application/vnd.geoplan"],
		["g3", "image/g3fax"],
		["g3w", "application/vnd.geospace"],
		["gac", "application/vnd.groove-account"],
		["gdl", "model/vnd.gdl"],
		["geo", "application/vnd.dynageo"],
		["geojson", "application/geo+json"],
		["gex", "application/vnd.geometry-explorer"],
		["ggb", "application/vnd.geogebra.file"],
		["ggt", "application/vnd.geogebra.tool"],
		["ghf", "application/vnd.groove-help"],
		["gif", "image/gif"],
		["gim", "application/vnd.groove-identity-message"],
		["gl", ["video/gl", "video/x-gl"]],
		["gmx", "application/vnd.gmx"],
		["gnumeric", "application/x-gnumeric"],
		["gph", "application/vnd.flographit"],
		["gqf", "application/vnd.grafeq"],
		["gram", "application/srgs"],
		["grv", "application/vnd.groove-injector"],
		["grxml", "application/srgs+xml"],
		["gsd", "audio/x-gsm"],
		["gsf", "application/x-font-ghostscript"],
		["gsm", "audio/x-gsm"],
		["gsp", "application/x-gsp"],
		["gss", "application/x-gss"],
		["gtar", "application/x-gtar"],
		["gtm", "application/vnd.groove-tool-message"],
		["gtw", "model/vnd.gtw"],
		["gv", "text/vnd.graphviz"],
		["gxt", "application/vnd.geonext"],
		["gz", ["application/x-gzip", "application/x-compressed"]],
		["gzip", ["multipart/x-gzip", "application/x-gzip"]],
		["h", ["text/plain", "text/x-h"]],
		["h261", "video/h261"],
		["h263", "video/h263"],
		["h264", "video/h264"],
		["hal", "application/vnd.hal+xml"],
		["hbci", "application/vnd.hbci"],
		["hdf", "application/x-hdf"],
		["help", "application/x-helpfile"],
		["hgl", "application/vnd.hp-hpgl"],
		["hh", ["text/plain", "text/x-h"]],
		["hlb", "text/x-script"],
		["hlp", [
			"application/winhlp",
			"application/hlp",
			"application/x-helpfile",
			"application/x-winhelp"
		]],
		["hpg", "application/vnd.hp-hpgl"],
		["hpgl", "application/vnd.hp-hpgl"],
		["hpid", "application/vnd.hp-hpid"],
		["hps", "application/vnd.hp-hps"],
		["hqx", [
			"application/mac-binhex40",
			"application/binhex",
			"application/binhex4",
			"application/mac-binhex",
			"application/x-binhex40",
			"application/x-mac-binhex40"
		]],
		["hta", "application/hta"],
		["htc", "text/x-component"],
		["htke", "application/vnd.kenameaapp"],
		["htm", "text/html"],
		["html", "text/html"],
		["htmls", "text/html"],
		["htt", "text/webviewhtml"],
		["htx", "text/html"],
		["hvd", "application/vnd.yamaha.hv-dic"],
		["hvp", "application/vnd.yamaha.hv-voice"],
		["hvs", "application/vnd.yamaha.hv-script"],
		["i2g", "application/vnd.intergeo"],
		["icc", "application/vnd.iccprofile"],
		["ice", "x-conference/x-cooltalk"],
		["ico", "image/x-icon"],
		["ics", "text/calendar"],
		["idc", "text/plain"],
		["ief", "image/ief"],
		["iefs", "image/ief"],
		["ifm", "application/vnd.shana.informed.formdata"],
		["iges", ["application/iges", "model/iges"]],
		["igl", "application/vnd.igloader"],
		["igm", "application/vnd.insors.igm"],
		["igs", ["application/iges", "model/iges"]],
		["igx", "application/vnd.micrografx.igx"],
		["iif", "application/vnd.shana.informed.interchange"],
		["iii", "application/x-iphone"],
		["ima", "application/x-ima"],
		["imap", "application/x-httpd-imap"],
		["imp", "application/vnd.accpac.simply.imp"],
		["ims", "application/vnd.ms-ims"],
		["inf", "application/inf"],
		["ins", ["application/x-internet-signup", "application/x-internett-signup"]],
		["ip", "application/x-ip2"],
		["ipfix", "application/ipfix"],
		["ipk", "application/vnd.shana.informed.package"],
		["irm", "application/vnd.ibm.rights-management"],
		["irp", "application/vnd.irepository.package+xml"],
		["isp", "application/x-internet-signup"],
		["isu", "video/x-isvideo"],
		["it", "audio/it"],
		["itp", "application/vnd.shana.informed.formtemplate"],
		["iv", "application/x-inventor"],
		["ivp", "application/vnd.immervision-ivp"],
		["ivr", "i-world/i-vrml"],
		["ivu", "application/vnd.immervision-ivu"],
		["ivy", "application/x-livescreen"],
		["jad", "text/vnd.sun.j2me.app-descriptor"],
		["jam", ["application/vnd.jam", "audio/x-jam"]],
		["jar", "application/java-archive"],
		["jav", ["text/plain", "text/x-java-source"]],
		["java", [
			"text/plain",
			"text/x-java-source,java",
			"text/x-java-source"
		]],
		["jcm", "application/x-java-commerce"],
		["jfif", [
			"image/pipeg",
			"image/jpeg",
			"image/pjpeg"
		]],
		["jfif-tbnl", "image/jpeg"],
		["jisp", "application/vnd.jisp"],
		["jlt", "application/vnd.hp-jlyt"],
		["jnlp", "application/x-java-jnlp-file"],
		["joda", "application/vnd.joost.joda-archive"],
		["jpe", ["image/jpeg", "image/pjpeg"]],
		["jpeg", ["image/jpeg", "image/pjpeg"]],
		["jpg", ["image/jpeg", "image/pjpeg"]],
		["jpgv", "video/jpeg"],
		["jpm", "video/jpm"],
		["jps", "image/x-jps"],
		["js", [
			"application/javascript",
			"application/ecmascript",
			"text/javascript",
			"text/ecmascript",
			"application/x-javascript"
		]],
		["json", "application/json"],
		["jut", "image/jutvision"],
		["kar", ["audio/midi", "music/x-karaoke"]],
		["karbon", "application/vnd.kde.karbon"],
		["kfo", "application/vnd.kde.kformula"],
		["kia", "application/vnd.kidspiration"],
		["kml", "application/vnd.google-earth.kml+xml"],
		["kmz", "application/vnd.google-earth.kmz"],
		["kne", "application/vnd.kinar"],
		["kon", "application/vnd.kde.kontour"],
		["kpr", "application/vnd.kde.kpresenter"],
		["ksh", ["application/x-ksh", "text/x-script.ksh"]],
		["ksp", "application/vnd.kde.kspread"],
		["ktx", "image/ktx"],
		["ktz", "application/vnd.kahootz"],
		["kwd", "application/vnd.kde.kword"],
		["la", ["audio/nspaudio", "audio/x-nspaudio"]],
		["lam", "audio/x-liveaudio"],
		["lasxml", "application/vnd.las.las+xml"],
		["latex", "application/x-latex"],
		["lbd", "application/vnd.llamagraphics.life-balance.desktop"],
		["lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"],
		["les", "application/vnd.hhe.lesson-player"],
		["lha", [
			"application/octet-stream",
			"application/lha",
			"application/x-lha"
		]],
		["lhx", "application/octet-stream"],
		["link66", "application/vnd.route66.link66+xml"],
		["list", "text/plain"],
		["lma", ["audio/nspaudio", "audio/x-nspaudio"]],
		["log", "text/plain"],
		["lrm", "application/vnd.ms-lrm"],
		["lsf", "video/x-la-asf"],
		["lsp", ["application/x-lisp", "text/x-script.lisp"]],
		["lst", "text/plain"],
		["lsx", ["video/x-la-asf", "text/x-la-asf"]],
		["ltf", "application/vnd.frogans.ltf"],
		["ltx", "application/x-latex"],
		["lvp", "audio/vnd.lucent.voice"],
		["lwp", "application/vnd.lotus-wordpro"],
		["lzh", ["application/octet-stream", "application/x-lzh"]],
		["lzx", [
			"application/lzx",
			"application/octet-stream",
			"application/x-lzx"
		]],
		["m", ["text/plain", "text/x-m"]],
		["m13", "application/x-msmediaview"],
		["m14", "application/x-msmediaview"],
		["m1v", "video/mpeg"],
		["m21", "application/mp21"],
		["m2a", "audio/mpeg"],
		["m2v", "video/mpeg"],
		["m3u", ["audio/x-mpegurl", "audio/x-mpequrl"]],
		["m3u8", "application/vnd.apple.mpegurl"],
		["m4v", "video/x-m4v"],
		["ma", "application/mathematica"],
		["mads", "application/mads+xml"],
		["mag", "application/vnd.ecowin.chart"],
		["man", "application/x-troff-man"],
		["map", "application/x-navimap"],
		["mar", "text/plain"],
		["mathml", "application/mathml+xml"],
		["mbd", "application/mbedlet"],
		["mbk", "application/vnd.mobius.mbk"],
		["mbox", "application/mbox"],
		["mc$", "application/x-magic-cap-package-1.0"],
		["mc1", "application/vnd.medcalcdata"],
		["mcd", [
			"application/mcad",
			"application/vnd.mcd",
			"application/x-mathcad"
		]],
		["mcf", ["image/vasa", "text/mcf"]],
		["mcp", "application/netmc"],
		["mcurl", "text/vnd.curl.mcurl"],
		["mdb", "application/x-msaccess"],
		["mdi", "image/vnd.ms-modi"],
		["me", "application/x-troff-me"],
		["meta4", "application/metalink4+xml"],
		["mets", "application/mets+xml"],
		["mfm", "application/vnd.mfmp"],
		["mgp", "application/vnd.osgeo.mapguide.package"],
		["mgz", "application/vnd.proteus.magazine"],
		["mht", "message/rfc822"],
		["mhtml", "message/rfc822"],
		["mid", [
			"audio/mid",
			"audio/midi",
			"music/crescendo",
			"x-music/x-midi",
			"audio/x-midi",
			"application/x-midi",
			"audio/x-mid"
		]],
		["midi", [
			"audio/midi",
			"music/crescendo",
			"x-music/x-midi",
			"audio/x-midi",
			"application/x-midi",
			"audio/x-mid"
		]],
		["mif", [
			"application/vnd.mif",
			"application/x-mif",
			"application/x-frame"
		]],
		["mime", ["message/rfc822", "www/mime"]],
		["mj2", "video/mj2"],
		["mjf", "audio/x-vnd.audioexplosion.mjuicemediafile"],
		["mjpg", "video/x-motion-jpeg"],
		["mlp", "application/vnd.dolby.mlp"],
		["mm", ["application/base64", "application/x-meme"]],
		["mmd", "application/vnd.chipnuts.karaoke-mmd"],
		["mme", "application/base64"],
		["mmf", "application/vnd.smaf"],
		["mmr", "image/vnd.fujixerox.edmics-mmr"],
		["mny", "application/x-msmoney"],
		["mod", ["audio/mod", "audio/x-mod"]],
		["mods", "application/mods+xml"],
		["moov", "video/quicktime"],
		["mov", "video/quicktime"],
		["movie", "video/x-sgi-movie"],
		["mp2", [
			"video/mpeg",
			"audio/mpeg",
			"video/x-mpeg",
			"audio/x-mpeg",
			"video/x-mpeq2a"
		]],
		["mp3", [
			"audio/mpeg",
			"audio/mpeg3",
			"video/mpeg",
			"audio/x-mpeg-3",
			"video/x-mpeg"
		]],
		["mp4", ["video/mp4", "application/mp4"]],
		["mp4a", "audio/mp4"],
		["mpa", ["video/mpeg", "audio/mpeg"]],
		["mpc", ["application/vnd.mophun.certificate", "application/x-project"]],
		["mpe", "video/mpeg"],
		["mpeg", "video/mpeg"],
		["mpg", ["video/mpeg", "audio/mpeg"]],
		["mpga", "audio/mpeg"],
		["mpkg", "application/vnd.apple.installer+xml"],
		["mpm", "application/vnd.blueice.multipass"],
		["mpn", "application/vnd.mophun.application"],
		["mpp", "application/vnd.ms-project"],
		["mpt", "application/x-project"],
		["mpv", "application/x-project"],
		["mpv2", "video/mpeg"],
		["mpx", "application/x-project"],
		["mpy", "application/vnd.ibm.minipay"],
		["mqy", "application/vnd.mobius.mqy"],
		["mrc", "application/marc"],
		["mrcx", "application/marcxml+xml"],
		["ms", "application/x-troff-ms"],
		["mscml", "application/mediaservercontrol+xml"],
		["mseq", "application/vnd.mseq"],
		["msf", "application/vnd.epson.msf"],
		["msg", "application/vnd.ms-outlook"],
		["msh", "model/mesh"],
		["msl", "application/vnd.mobius.msl"],
		["msty", "application/vnd.muvee.style"],
		["mts", "model/vnd.mts"],
		["mus", "application/vnd.musician"],
		["musicxml", "application/vnd.recordare.musicxml+xml"],
		["mv", "video/x-sgi-movie"],
		["mvb", "application/x-msmediaview"],
		["mwf", "application/vnd.mfer"],
		["mxf", "application/mxf"],
		["mxl", "application/vnd.recordare.musicxml"],
		["mxml", "application/xv+xml"],
		["mxs", "application/vnd.triscape.mxs"],
		["mxu", "video/vnd.mpegurl"],
		["my", "audio/make"],
		["mzz", "application/x-vnd.audioexplosion.mzz"],
		["n-gage", "application/vnd.nokia.n-gage.symbian.install"],
		["n3", "text/n3"],
		["nap", "image/naplps"],
		["naplps", "image/naplps"],
		["nbp", "application/vnd.wolfram.player"],
		["nc", "application/x-netcdf"],
		["ncm", "application/vnd.nokia.configuration-message"],
		["ncx", "application/x-dtbncx+xml"],
		["ngdat", "application/vnd.nokia.n-gage.data"],
		["nif", "image/x-niff"],
		["niff", "image/x-niff"],
		["nix", "application/x-mix-transfer"],
		["nlu", "application/vnd.neurolanguage.nlu"],
		["nml", "application/vnd.enliven"],
		["nnd", "application/vnd.noblenet-directory"],
		["nns", "application/vnd.noblenet-sealer"],
		["nnw", "application/vnd.noblenet-web"],
		["npx", "image/vnd.net-fpx"],
		["nsc", "application/x-conference"],
		["nsf", "application/vnd.lotus-notes"],
		["nvd", "application/x-navidoc"],
		["nws", "message/rfc822"],
		["o", "application/octet-stream"],
		["oa2", "application/vnd.fujitsu.oasys2"],
		["oa3", "application/vnd.fujitsu.oasys3"],
		["oas", "application/vnd.fujitsu.oasys"],
		["obd", "application/x-msbinder"],
		["oda", "application/oda"],
		["odb", "application/vnd.oasis.opendocument.database"],
		["odc", "application/vnd.oasis.opendocument.chart"],
		["odf", "application/vnd.oasis.opendocument.formula"],
		["odft", "application/vnd.oasis.opendocument.formula-template"],
		["odg", "application/vnd.oasis.opendocument.graphics"],
		["odi", "application/vnd.oasis.opendocument.image"],
		["odm", "application/vnd.oasis.opendocument.text-master"],
		["odp", "application/vnd.oasis.opendocument.presentation"],
		["ods", "application/vnd.oasis.opendocument.spreadsheet"],
		["odt", "application/vnd.oasis.opendocument.text"],
		["oga", "audio/ogg"],
		["ogv", "video/ogg"],
		["ogx", "application/ogg"],
		["omc", "application/x-omc"],
		["omcd", "application/x-omcdatamaker"],
		["omcr", "application/x-omcregerator"],
		["onetoc", "application/onenote"],
		["opf", "application/oebps-package+xml"],
		["org", "application/vnd.lotus-organizer"],
		["osf", "application/vnd.yamaha.openscoreformat"],
		["osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"],
		["otc", "application/vnd.oasis.opendocument.chart-template"],
		["otf", "application/x-font-otf"],
		["otg", "application/vnd.oasis.opendocument.graphics-template"],
		["oth", "application/vnd.oasis.opendocument.text-web"],
		["oti", "application/vnd.oasis.opendocument.image-template"],
		["otp", "application/vnd.oasis.opendocument.presentation-template"],
		["ots", "application/vnd.oasis.opendocument.spreadsheet-template"],
		["ott", "application/vnd.oasis.opendocument.text-template"],
		["oxt", "application/vnd.openofficeorg.extension"],
		["p", "text/x-pascal"],
		["p10", ["application/pkcs10", "application/x-pkcs10"]],
		["p12", ["application/pkcs-12", "application/x-pkcs12"]],
		["p7a", "application/x-pkcs7-signature"],
		["p7b", "application/x-pkcs7-certificates"],
		["p7c", ["application/pkcs7-mime", "application/x-pkcs7-mime"]],
		["p7m", ["application/pkcs7-mime", "application/x-pkcs7-mime"]],
		["p7r", "application/x-pkcs7-certreqresp"],
		["p7s", ["application/pkcs7-signature", "application/x-pkcs7-signature"]],
		["p8", "application/pkcs8"],
		["par", "text/plain-bas"],
		["part", "application/pro_eng"],
		["pas", "text/pascal"],
		["paw", "application/vnd.pawaafile"],
		["pbd", "application/vnd.powerbuilder6"],
		["pbm", "image/x-portable-bitmap"],
		["pcf", "application/x-font-pcf"],
		["pcl", ["application/vnd.hp-pcl", "application/x-pcl"]],
		["pclxl", "application/vnd.hp-pclxl"],
		["pct", "image/x-pict"],
		["pcurl", "application/vnd.curl.pcurl"],
		["pcx", "image/x-pcx"],
		["pdb", ["application/vnd.palm", "chemical/x-pdb"]],
		["pdf", "application/pdf"],
		["pfa", "application/x-font-type1"],
		["pfr", "application/font-tdpfr"],
		["pfunk", ["audio/make", "audio/make.my.funk"]],
		["pfx", "application/x-pkcs12"],
		["pgm", ["image/x-portable-graymap", "image/x-portable-greymap"]],
		["pgn", "application/x-chess-pgn"],
		["pgp", "application/pgp-signature"],
		["pic", ["image/pict", "image/x-pict"]],
		["pict", "image/pict"],
		["pkg", "application/x-newton-compatible-pkg"],
		["pki", "application/pkixcmp"],
		["pkipath", "application/pkix-pkipath"],
		["pko", ["application/ynd.ms-pkipko", "application/vnd.ms-pki.pko"]],
		["pl", ["text/plain", "text/x-script.perl"]],
		["plb", "application/vnd.3gpp.pic-bw-large"],
		["plc", "application/vnd.mobius.plc"],
		["plf", "application/vnd.pocketlearn"],
		["pls", "application/pls+xml"],
		["plx", "application/x-pixclscript"],
		["pm", ["text/x-script.perl-module", "image/x-xpixmap"]],
		["pm4", "application/x-pagemaker"],
		["pm5", "application/x-pagemaker"],
		["pma", "application/x-perfmon"],
		["pmc", "application/x-perfmon"],
		["pml", ["application/vnd.ctc-posml", "application/x-perfmon"]],
		["pmr", "application/x-perfmon"],
		["pmw", "application/x-perfmon"],
		["png", "image/png"],
		["pnm", ["application/x-portable-anymap", "image/x-portable-anymap"]],
		["portpkg", "application/vnd.macports.portpkg"],
		["pot", ["application/vnd.ms-powerpoint", "application/mspowerpoint"]],
		["potm", "application/vnd.ms-powerpoint.template.macroenabled.12"],
		["potx", "application/vnd.openxmlformats-officedocument.presentationml.template"],
		["pov", "model/x-pov"],
		["ppa", "application/vnd.ms-powerpoint"],
		["ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"],
		["ppd", "application/vnd.cups-ppd"],
		["ppm", "image/x-portable-pixmap"],
		["pps", ["application/vnd.ms-powerpoint", "application/mspowerpoint"]],
		["ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"],
		["ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"],
		["ppt", [
			"application/vnd.ms-powerpoint",
			"application/mspowerpoint",
			"application/powerpoint",
			"application/x-mspowerpoint"
		]],
		["pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"],
		["pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"],
		["ppz", "application/mspowerpoint"],
		["prc", "application/x-mobipocket-ebook"],
		["pre", ["application/vnd.lotus-freelance", "application/x-freelance"]],
		["prf", "application/pics-rules"],
		["prt", "application/pro_eng"],
		["ps", "application/postscript"],
		["psb", "application/vnd.3gpp.pic-bw-small"],
		["psd", ["application/octet-stream", "image/vnd.adobe.photoshop"]],
		["psf", "application/x-font-linux-psf"],
		["pskcxml", "application/pskc+xml"],
		["ptid", "application/vnd.pvi.ptid1"],
		["pub", "application/x-mspublisher"],
		["pvb", "application/vnd.3gpp.pic-bw-var"],
		["pvu", "paleovu/x-pv"],
		["pwn", "application/vnd.3m.post-it-notes"],
		["pwz", "application/vnd.ms-powerpoint"],
		["py", "text/x-script.phyton"],
		["pya", "audio/vnd.ms-playready.media.pya"],
		["pyc", "application/x-bytecode.python"],
		["pyv", "video/vnd.ms-playready.media.pyv"],
		["qam", "application/vnd.epson.quickanime"],
		["qbo", "application/vnd.intu.qbo"],
		["qcp", "audio/vnd.qcelp"],
		["qd3", "x-world/x-3dmf"],
		["qd3d", "x-world/x-3dmf"],
		["qfx", "application/vnd.intu.qfx"],
		["qif", "image/x-quicktime"],
		["qps", "application/vnd.publishare-delta-tree"],
		["qt", "video/quicktime"],
		["qtc", "video/x-qtc"],
		["qti", "image/x-quicktime"],
		["qtif", "image/x-quicktime"],
		["qxd", "application/vnd.quark.quarkxpress"],
		["ra", [
			"audio/x-realaudio",
			"audio/x-pn-realaudio",
			"audio/x-pn-realaudio-plugin"
		]],
		["ram", "audio/x-pn-realaudio"],
		["rar", "application/x-rar-compressed"],
		["ras", [
			"image/cmu-raster",
			"application/x-cmu-raster",
			"image/x-cmu-raster"
		]],
		["rast", "image/cmu-raster"],
		["rcprofile", "application/vnd.ipunplugged.rcprofile"],
		["rdf", "application/rdf+xml"],
		["rdz", "application/vnd.data-vision.rdz"],
		["rep", "application/vnd.businessobjects"],
		["res", "application/x-dtbresource+xml"],
		["rexx", "text/x-script.rexx"],
		["rf", "image/vnd.rn-realflash"],
		["rgb", "image/x-rgb"],
		["rif", "application/reginfo+xml"],
		["rip", "audio/vnd.rip"],
		["rl", "application/resource-lists+xml"],
		["rlc", "image/vnd.fujixerox.edmics-rlc"],
		["rld", "application/resource-lists-diff+xml"],
		["rm", ["application/vnd.rn-realmedia", "audio/x-pn-realaudio"]],
		["rmi", "audio/mid"],
		["rmm", "audio/x-pn-realaudio"],
		["rmp", ["audio/x-pn-realaudio-plugin", "audio/x-pn-realaudio"]],
		["rms", "application/vnd.jcp.javame.midlet-rms"],
		["rnc", "application/relax-ng-compact-syntax"],
		["rng", ["application/ringing-tones", "application/vnd.nokia.ringing-tone"]],
		["rnx", "application/vnd.rn-realplayer"],
		["roff", "application/x-troff"],
		["rp", "image/vnd.rn-realpix"],
		["rp9", "application/vnd.cloanto.rp9"],
		["rpm", "audio/x-pn-realaudio-plugin"],
		["rpss", "application/vnd.nokia.radio-presets"],
		["rpst", "application/vnd.nokia.radio-preset"],
		["rq", "application/sparql-query"],
		["rs", "application/rls-services+xml"],
		["rsd", "application/rsd+xml"],
		["rt", ["text/richtext", "text/vnd.rn-realtext"]],
		["rtf", [
			"application/rtf",
			"text/richtext",
			"application/x-rtf"
		]],
		["rtx", ["text/richtext", "application/rtf"]],
		["rv", "video/vnd.rn-realvideo"],
		["s", "text/x-asm"],
		["s3m", "audio/s3m"],
		["saf", "application/vnd.yamaha.smaf-audio"],
		["saveme", "application/octet-stream"],
		["sbk", "application/x-tbook"],
		["sbml", "application/sbml+xml"],
		["sc", "application/vnd.ibm.secure-container"],
		["scd", "application/x-msschedule"],
		["scm", [
			"application/vnd.lotus-screencam",
			"video/x-scm",
			"text/x-script.guile",
			"application/x-lotusscreencam",
			"text/x-script.scheme"
		]],
		["scq", "application/scvp-cv-request"],
		["scs", "application/scvp-cv-response"],
		["sct", "text/scriptlet"],
		["scurl", "text/vnd.curl.scurl"],
		["sda", "application/vnd.stardivision.draw"],
		["sdc", "application/vnd.stardivision.calc"],
		["sdd", "application/vnd.stardivision.impress"],
		["sdkm", "application/vnd.solent.sdkm+xml"],
		["sdml", "text/plain"],
		["sdp", ["application/sdp", "application/x-sdp"]],
		["sdr", "application/sounder"],
		["sdw", "application/vnd.stardivision.writer"],
		["sea", ["application/sea", "application/x-sea"]],
		["see", "application/vnd.seemail"],
		["seed", "application/vnd.fdsn.seed"],
		["sema", "application/vnd.sema"],
		["semd", "application/vnd.semd"],
		["semf", "application/vnd.semf"],
		["ser", "application/java-serialized-object"],
		["set", "application/set"],
		["setpay", "application/set-payment-initiation"],
		["setreg", "application/set-registration-initiation"],
		["sfd-hdstx", "application/vnd.hydrostatix.sof-data"],
		["sfs", "application/vnd.spotfire.sfs"],
		["sgl", "application/vnd.stardivision.writer-global"],
		["sgm", ["text/sgml", "text/x-sgml"]],
		["sgml", ["text/sgml", "text/x-sgml"]],
		["sh", [
			"application/x-shar",
			"application/x-bsh",
			"application/x-sh",
			"text/x-script.sh"
		]],
		["shar", ["application/x-bsh", "application/x-shar"]],
		["shf", "application/shf+xml"],
		["shtml", ["text/html", "text/x-server-parsed-html"]],
		["sid", "audio/x-psid"],
		["sis", "application/vnd.symbian.install"],
		["sit", ["application/x-stuffit", "application/x-sit"]],
		["sitx", "application/x-stuffitx"],
		["skd", "application/x-koan"],
		["skm", "application/x-koan"],
		["skp", ["application/vnd.koan", "application/x-koan"]],
		["skt", "application/x-koan"],
		["sl", "application/x-seelogo"],
		["sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"],
		["sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"],
		["slt", "application/vnd.epson.salt"],
		["sm", "application/vnd.stepmania.stepchart"],
		["smf", "application/vnd.stardivision.math"],
		["smi", ["application/smil", "application/smil+xml"]],
		["smil", "application/smil"],
		["snd", ["audio/basic", "audio/x-adpcm"]],
		["snf", "application/x-font-snf"],
		["sol", "application/solids"],
		["spc", ["text/x-speech", "application/x-pkcs7-certificates"]],
		["spf", "application/vnd.yamaha.smaf-phrase"],
		["spl", ["application/futuresplash", "application/x-futuresplash"]],
		["spot", "text/vnd.in3d.spot"],
		["spp", "application/scvp-vp-response"],
		["spq", "application/scvp-vp-request"],
		["spr", "application/x-sprite"],
		["sprite", "application/x-sprite"],
		["src", "application/x-wais-source"],
		["sru", "application/sru+xml"],
		["srx", "application/sparql-results+xml"],
		["sse", "application/vnd.kodak-descriptor"],
		["ssf", "application/vnd.epson.ssf"],
		["ssi", "text/x-server-parsed-html"],
		["ssm", "application/streamingmedia"],
		["ssml", "application/ssml+xml"],
		["sst", ["application/vnd.ms-pkicertstore", "application/vnd.ms-pki.certstore"]],
		["st", "application/vnd.sailingtracker.track"],
		["stc", "application/vnd.sun.xml.calc.template"],
		["std", "application/vnd.sun.xml.draw.template"],
		["step", "application/step"],
		["stf", "application/vnd.wt.stf"],
		["sti", "application/vnd.sun.xml.impress.template"],
		["stk", "application/hyperstudio"],
		["stl", [
			"application/vnd.ms-pkistl",
			"application/sla",
			"application/vnd.ms-pki.stl",
			"application/x-navistyle"
		]],
		["stm", "text/html"],
		["stp", "application/step"],
		["str", "application/vnd.pg.format"],
		["stw", "application/vnd.sun.xml.writer.template"],
		["sub", "image/vnd.dvb.subtitle"],
		["sus", "application/vnd.sus-calendar"],
		["sv4cpio", "application/x-sv4cpio"],
		["sv4crc", "application/x-sv4crc"],
		["svc", "application/vnd.dvb.service"],
		["svd", "application/vnd.svd"],
		["svf", ["image/vnd.dwg", "image/x-dwg"]],
		["svg", "image/svg+xml"],
		["svr", ["x-world/x-svr", "application/x-world"]],
		["swf", "application/x-shockwave-flash"],
		["swi", "application/vnd.aristanetworks.swi"],
		["sxc", "application/vnd.sun.xml.calc"],
		["sxd", "application/vnd.sun.xml.draw"],
		["sxg", "application/vnd.sun.xml.writer.global"],
		["sxi", "application/vnd.sun.xml.impress"],
		["sxm", "application/vnd.sun.xml.math"],
		["sxw", "application/vnd.sun.xml.writer"],
		["t", ["text/troff", "application/x-troff"]],
		["talk", "text/x-speech"],
		["tao", "application/vnd.tao.intent-module-archive"],
		["tar", "application/x-tar"],
		["tbk", ["application/toolbook", "application/x-tbook"]],
		["tcap", "application/vnd.3gpp2.tcap"],
		["tcl", ["text/x-script.tcl", "application/x-tcl"]],
		["tcsh", "text/x-script.tcsh"],
		["teacher", "application/vnd.smart.teacher"],
		["tei", "application/tei+xml"],
		["tex", "application/x-tex"],
		["texi", "application/x-texinfo"],
		["texinfo", "application/x-texinfo"],
		["text", ["application/plain", "text/plain"]],
		["tfi", "application/thraud+xml"],
		["tfm", "application/x-tex-tfm"],
		["tgz", ["application/gnutar", "application/x-compressed"]],
		["thmx", "application/vnd.ms-officetheme"],
		["tif", ["image/tiff", "image/x-tiff"]],
		["tiff", ["image/tiff", "image/x-tiff"]],
		["tmo", "application/vnd.tmobile-livetv"],
		["torrent", "application/x-bittorrent"],
		["tpl", "application/vnd.groove-tool-template"],
		["tpt", "application/vnd.trid.tpt"],
		["tr", "application/x-troff"],
		["tra", "application/vnd.trueapp"],
		["trm", "application/x-msterminal"],
		["tsd", "application/timestamped-data"],
		["tsi", "audio/tsp-audio"],
		["tsp", ["application/dsptype", "audio/tsplayer"]],
		["tsv", "text/tab-separated-values"],
		["ttf", "application/x-font-ttf"],
		["ttl", "text/turtle"],
		["turbot", "image/florian"],
		["twd", "application/vnd.simtech-mindmapper"],
		["txd", "application/vnd.genomatix.tuxedo"],
		["txf", "application/vnd.mobius.txf"],
		["txt", "text/plain"],
		["ufd", "application/vnd.ufdl"],
		["uil", "text/x-uil"],
		["uls", "text/iuls"],
		["umj", "application/vnd.umajin"],
		["uni", "text/uri-list"],
		["unis", "text/uri-list"],
		["unityweb", "application/vnd.unity"],
		["unv", "application/i-deas"],
		["uoml", "application/vnd.uoml+xml"],
		["uri", "text/uri-list"],
		["uris", "text/uri-list"],
		["ustar", ["application/x-ustar", "multipart/x-ustar"]],
		["utz", "application/vnd.uiq.theme"],
		["uu", ["application/octet-stream", "text/x-uuencode"]],
		["uue", "text/x-uuencode"],
		["uva", "audio/vnd.dece.audio"],
		["uvh", "video/vnd.dece.hd"],
		["uvi", "image/vnd.dece.graphic"],
		["uvm", "video/vnd.dece.mobile"],
		["uvp", "video/vnd.dece.pd"],
		["uvs", "video/vnd.dece.sd"],
		["uvu", "video/vnd.uvvu.mp4"],
		["uvv", "video/vnd.dece.video"],
		["vcd", "application/x-cdlink"],
		["vcf", "text/x-vcard"],
		["vcg", "application/vnd.groove-vcard"],
		["vcs", "text/x-vcalendar"],
		["vcx", "application/vnd.vcx"],
		["vda", "application/vda"],
		["vdo", "video/vdo"],
		["vew", "application/groupwise"],
		["vis", "application/vnd.visionary"],
		["viv", ["video/vivo", "video/vnd.vivo"]],
		["vivo", ["video/vivo", "video/vnd.vivo"]],
		["vmd", "application/vocaltec-media-desc"],
		["vmf", "application/vocaltec-media-file"],
		["voc", ["audio/voc", "audio/x-voc"]],
		["vos", "video/vosaic"],
		["vox", "audio/voxware"],
		["vqe", "audio/x-twinvq-plugin"],
		["vqf", "audio/x-twinvq"],
		["vql", "audio/x-twinvq-plugin"],
		["vrml", [
			"model/vrml",
			"x-world/x-vrml",
			"application/x-vrml"
		]],
		["vrt", "x-world/x-vrt"],
		["vsd", ["application/vnd.visio", "application/x-visio"]],
		["vsf", "application/vnd.vsf"],
		["vst", "application/x-visio"],
		["vsw", "application/x-visio"],
		["vtu", "model/vnd.vtu"],
		["vxml", "application/voicexml+xml"],
		["w60", "application/wordperfect6.0"],
		["w61", "application/wordperfect6.1"],
		["w6w", "application/msword"],
		["wad", "application/x-doom"],
		["wav", ["audio/wav", "audio/x-wav"]],
		["wax", "audio/x-ms-wax"],
		["wb1", "application/x-qpro"],
		["wbmp", "image/vnd.wap.wbmp"],
		["wbs", "application/vnd.criticaltools.wbs+xml"],
		["wbxml", "application/vnd.wap.wbxml"],
		["wcm", "application/vnd.ms-works"],
		["wdb", "application/vnd.ms-works"],
		["web", "application/vnd.xara"],
		["weba", "audio/webm"],
		["webm", "video/webm"],
		["webp", "image/webp"],
		["wg", "application/vnd.pmi.widget"],
		["wgt", "application/widget"],
		["wiz", "application/msword"],
		["wk1", "application/x-123"],
		["wks", "application/vnd.ms-works"],
		["wm", "video/x-ms-wm"],
		["wma", "audio/x-ms-wma"],
		["wmd", "application/x-ms-wmd"],
		["wmf", ["windows/metafile", "application/x-msmetafile"]],
		["wml", "text/vnd.wap.wml"],
		["wmlc", "application/vnd.wap.wmlc"],
		["wmls", "text/vnd.wap.wmlscript"],
		["wmlsc", "application/vnd.wap.wmlscriptc"],
		["wmv", "video/x-ms-wmv"],
		["wmx", "video/x-ms-wmx"],
		["wmz", "application/x-ms-wmz"],
		["woff", "application/x-font-woff"],
		["word", "application/msword"],
		["wp", "application/wordperfect"],
		["wp5", ["application/wordperfect", "application/wordperfect6.0"]],
		["wp6", "application/wordperfect"],
		["wpd", [
			"application/wordperfect",
			"application/vnd.wordperfect",
			"application/x-wpwin"
		]],
		["wpl", "application/vnd.ms-wpl"],
		["wps", "application/vnd.ms-works"],
		["wq1", "application/x-lotus"],
		["wqd", "application/vnd.wqd"],
		["wri", [
			"application/mswrite",
			"application/x-wri",
			"application/x-mswrite"
		]],
		["wrl", [
			"model/vrml",
			"x-world/x-vrml",
			"application/x-world"
		]],
		["wrz", ["model/vrml", "x-world/x-vrml"]],
		["wsc", "text/scriplet"],
		["wsdl", "application/wsdl+xml"],
		["wspolicy", "application/wspolicy+xml"],
		["wsrc", "application/x-wais-source"],
		["wtb", "application/vnd.webturbo"],
		["wtk", "application/x-wintalk"],
		["wvx", "video/x-ms-wvx"],
		["x-png", "image/png"],
		["x3d", "application/vnd.hzn-3d-crossword"],
		["xaf", "x-world/x-vrml"],
		["xap", "application/x-silverlight-app"],
		["xar", "application/vnd.xara"],
		["xbap", "application/x-ms-xbap"],
		["xbd", "application/vnd.fujixerox.docuworks.binder"],
		["xbm", [
			"image/xbm",
			"image/x-xbm",
			"image/x-xbitmap"
		]],
		["xdf", "application/xcap-diff+xml"],
		["xdm", "application/vnd.syncml.dm+xml"],
		["xdp", "application/vnd.adobe.xdp+xml"],
		["xdr", "video/x-amt-demorun"],
		["xdssc", "application/dssc+xml"],
		["xdw", "application/vnd.fujixerox.docuworks"],
		["xenc", "application/xenc+xml"],
		["xer", "application/patch-ops-error+xml"],
		["xfdf", "application/vnd.adobe.xfdf"],
		["xfdl", "application/vnd.xfdl"],
		["xgz", "xgl/drawing"],
		["xhtml", "application/xhtml+xml"],
		["xif", "image/vnd.xiff"],
		["xl", "application/excel"],
		["xla", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-msexcel",
			"application/x-excel"
		]],
		["xlam", "application/vnd.ms-excel.addin.macroenabled.12"],
		["xlb", [
			"application/excel",
			"application/vnd.ms-excel",
			"application/x-excel"
		]],
		["xlc", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-excel"
		]],
		["xld", ["application/excel", "application/x-excel"]],
		["xlk", ["application/excel", "application/x-excel"]],
		["xll", [
			"application/excel",
			"application/vnd.ms-excel",
			"application/x-excel"
		]],
		["xlm", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-excel"
		]],
		["xls", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-msexcel",
			"application/x-excel"
		]],
		["xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"],
		["xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"],
		["xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
		["xlt", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-excel"
		]],
		["xltm", "application/vnd.ms-excel.template.macroenabled.12"],
		["xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"],
		["xlv", ["application/excel", "application/x-excel"]],
		["xlw", [
			"application/vnd.ms-excel",
			"application/excel",
			"application/x-msexcel",
			"application/x-excel"
		]],
		["xm", "audio/xm"],
		["xml", [
			"application/xml",
			"text/xml",
			"application/atom+xml",
			"application/rss+xml"
		]],
		["xmz", "xgl/movie"],
		["xo", "application/vnd.olpc-sugar"],
		["xof", "x-world/x-vrml"],
		["xop", "application/xop+xml"],
		["xpi", "application/x-xpinstall"],
		["xpix", "application/x-vnd.ls-xpix"],
		["xpm", ["image/xpm", "image/x-xpixmap"]],
		["xpr", "application/vnd.is-xpr"],
		["xps", "application/vnd.ms-xpsdocument"],
		["xpw", "application/vnd.intercon.formnet"],
		["xslt", "application/xslt+xml"],
		["xsm", "application/vnd.syncml+xml"],
		["xspf", "application/xspf+xml"],
		["xsr", "video/x-amt-showrun"],
		["xul", "application/vnd.mozilla.xul+xml"],
		["xwd", ["image/x-xwd", "image/x-xwindowdump"]],
		["xyz", ["chemical/x-xyz", "chemical/x-pdb"]],
		["yang", "application/yang"],
		["yin", "application/yin+xml"],
		["z", ["application/x-compressed", "application/x-compress"]],
		["zaz", "application/vnd.zzazz.deck+xml"],
		["zip", [
			"application/zip",
			"multipart/x-zip",
			"application/x-zip-compressed",
			"application/x-compressed"
		]],
		["zir", "application/vnd.zul"],
		["zmm", "application/vnd.handheld-entertainment+xml"],
		["zoo", "application/octet-stream"],
		["zsh", "text/x-script.zsh"]
	]);
	module.exports = {
		detectMimeType(filename) {
			if (!filename) return defaultMimeType;
			const parsed = path$3.parse(filename);
			const extension = (parsed.ext.substr(1) || parsed.name || "").split("?").shift().trim().toLowerCase();
			const value = extensions.has(extension) ? extensions.get(extension) : defaultMimeType;
			if (Array.isArray(value)) return value[0];
			return value;
		},
		detectExtension(mimeType) {
			if (!mimeType) return defaultExtension;
			const parts = mimeType.toLowerCase().trim().split("/");
			const rootType = parts.shift().trim();
			const subType = parts.join("/").trim();
			if (mimeTypes.has(rootType + "/" + subType)) {
				const value = mimeTypes.get(rootType + "/" + subType);
				if (Array.isArray(value)) return value[0];
				return value;
			}
			switch (rootType) {
				case "text": return "txt";
				default: return "bin";
			}
		}
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/base64/index.js
var require_base64 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$7 } = __require("stream");
	/**
	* Encodes a Buffer into a base64 encoded string
	*
	* @param {Buffer} buffer Buffer to convert
	* @returns {String} base64 encoded string
	*/
	function encode(buffer) {
		if (typeof buffer === "string") buffer = Buffer.from(buffer, "utf-8");
		return buffer.toString("base64");
	}
	/**
	* Adds soft line breaks to a base64 string
	*
	* @param {String} str base64 encoded string that might need line wrapping
	* @param {Number} [lineLength=76] Maximum allowed length for a line
	* @returns {String} Soft-wrapped base64 encoded string
	*/
	function wrap(str, lineLength) {
		str = (str || "").toString();
		lineLength = lineLength || 76;
		if (str.length <= lineLength) return str;
		const result = [];
		let pos = 0;
		const chunkLength = lineLength * 1024;
		const wrapRegex = new RegExp(".{" + lineLength + "}", "g");
		while (pos < str.length) {
			const wrappedLines = str.substr(pos, chunkLength).replace(wrapRegex, "$&\r\n").trim();
			result.push(wrappedLines);
			pos += chunkLength;
		}
		return result.join("\r\n").trim();
	}
	/**
	* Creates a transform stream for encoding data to base64 encoding
	*
	* @constructor
	* @param {Object} options Stream options
	* @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
	*/
	var Encoder = class extends Transform$7 {
		constructor(options) {
			super();
			this.options = options || {};
			if (this.options.lineLength !== false) this.options.lineLength = this.options.lineLength || 76;
			this._curLine = "";
			this._remainingBytes = false;
			this.inputBytes = 0;
			this.outputBytes = 0;
		}
		_transform(chunk, encoding, done) {
			if (encoding !== "buffer") chunk = Buffer.from(chunk, encoding);
			if (!chunk || !chunk.length) return setImmediate(done);
			this.inputBytes += chunk.length;
			if (this._remainingBytes && this._remainingBytes.length) {
				chunk = Buffer.concat([this._remainingBytes, chunk], this._remainingBytes.length + chunk.length);
				this._remainingBytes = false;
			}
			if (chunk.length % 3) {
				this._remainingBytes = chunk.slice(chunk.length - chunk.length % 3);
				chunk = chunk.slice(0, chunk.length - chunk.length % 3);
			} else this._remainingBytes = false;
			let b64 = this._curLine + encode(chunk);
			if (this.options.lineLength) {
				b64 = wrap(b64, this.options.lineLength);
				const lastLF = b64.lastIndexOf("\n");
				if (lastLF < 0) {
					this._curLine = b64;
					b64 = "";
				} else if (lastLF === b64.length - 1) this._curLine = "";
				else {
					this._curLine = b64.substring(lastLF + 1);
					b64 = b64.substring(0, lastLF + 1);
				}
			}
			if (b64) {
				this.outputBytes += b64.length;
				this.push(Buffer.from(b64, "ascii"));
			}
			setImmediate(done);
		}
		_flush(done) {
			if (this._remainingBytes && this._remainingBytes.length) this._curLine += encode(this._remainingBytes);
			if (this._curLine) {
				this._curLine = wrap(this._curLine, this.options.lineLength);
				this.outputBytes += this._curLine.length;
				this.push(Buffer.from(this._curLine, "ascii"));
				this._curLine = "";
			}
			done();
		}
	};
	module.exports = {
		encode,
		wrap,
		Encoder
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/qp/index.js
var require_qp = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$6 } = __require("stream");
	/**
	* Encodes a Buffer into a Quoted-Printable encoded string
	*
	* @param {Buffer} buffer Buffer to convert
	* @returns {String} Quoted-Printable encoded string
	*/
	var QP_RANGES = [
		[9],
		[10],
		[13],
		[32, 60],
		[62, 126]
	];
	function encode(buffer) {
		if (typeof buffer === "string") buffer = Buffer.from(buffer, "utf-8");
		let result = "";
		let ord;
		for (let i = 0, len = buffer.length; i < len; i++) {
			ord = buffer[i];
			if (checkRanges(ord, QP_RANGES) && !((ord === 32 || ord === 9) && (i === len - 1 || buffer[i + 1] === 10 || buffer[i + 1] === 13))) {
				result += String.fromCharCode(ord);
				continue;
			}
			result += "=" + (ord < 16 ? "0" : "") + ord.toString(16).toUpperCase();
		}
		return result;
	}
	/**
	* Adds soft line breaks to a Quoted-Printable string
	*
	* @param {String} str Quoted-Printable encoded string that might need line wrapping
	* @param {Number} [lineLength=76] Maximum allowed length for a line
	* @returns {String} Soft-wrapped Quoted-Printable encoded string
	*/
	function wrap(str, lineLength) {
		str = (str || "").toString();
		lineLength = lineLength || 76;
		if (str.length <= lineLength) return str;
		let pos = 0;
		const len = str.length;
		let match, code, line;
		const lineMargin = Math.floor(lineLength / 3);
		let result = "";
		while (pos < len) {
			line = str.substr(pos, lineLength);
			if (match = line.match(/\r\n/)) {
				line = line.substr(0, match.index + match[0].length);
				result += line;
				pos += line.length;
				continue;
			}
			if (line.substr(-1) === "\n") {
				result += line;
				pos += line.length;
				continue;
			}
			if (match = line.substr(-lineMargin).match(/\n.*?$/)) {
				line = line.substr(0, line.length - (match[0].length - 1));
				result += line;
				pos += line.length;
				continue;
			}
			if (line.length > lineLength - lineMargin && (match = line.substr(-lineMargin).match(/[ \t.,!?][^ \t.,!?]*$/))) line = line.substr(0, line.length - (match[0].length - 1));
			else if (line.match(/[=][\da-f]{0,2}$/i)) {
				if (match = line.match(/[=][\da-f]{0,1}$/i)) line = line.substr(0, line.length - match[0].length);
				while (line.length > 3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/[=][\da-f]{2}$/gi))) {
					code = parseInt(match[0].substr(1, 2), 16);
					if (code < 128) break;
					line = line.substr(0, line.length - 3);
					if (code >= 192) break;
				}
			}
			if (pos + line.length < len && line.substr(-1) !== "\n") {
				if (line.length === lineLength && line.match(/[=][\da-f]{2}$/i)) line = line.substr(0, line.length - 3);
				else if (line.length === lineLength) line = line.substr(0, line.length - 1);
				pos += line.length;
				line += "=\r\n";
			} else pos += line.length;
			result += line;
		}
		return result;
	}
	/**
	* Helper function to check if a number is inside provided ranges
	*
	* @param {Number} nr Number to check for
	* @param {Array} ranges An Array of allowed values
	* @returns {Boolean} True if the value was found inside allowed ranges, false otherwise
	*/
	function checkRanges(nr, ranges) {
		for (let i = ranges.length - 1; i >= 0; i--) {
			const range = ranges[i];
			if (!range.length) continue;
			if (range.length === 1 && nr === range[0]) return true;
			if (range.length === 2 && nr >= range[0] && nr <= range[1]) return true;
		}
		return false;
	}
	/**
	* Creates a transform stream for encoding data to Quoted-Printable encoding
	*
	* @constructor
	* @param {Object} options Stream options
	* @param {Number} [options.lineLength=76] Maximum length for lines, set to false to disable wrapping
	*/
	var Encoder = class extends Transform$6 {
		constructor(options) {
			super();
			this.options = options || {};
			if (this.options.lineLength !== false) this.options.lineLength = this.options.lineLength || 76;
			this._curLine = "";
			this.inputBytes = 0;
			this.outputBytes = 0;
		}
		_transform(chunk, encoding, done) {
			let qp;
			if (encoding !== "buffer") chunk = Buffer.from(chunk, encoding);
			if (!chunk || !chunk.length) return done();
			this.inputBytes += chunk.length;
			if (this.options.lineLength) {
				qp = this._curLine + encode(chunk);
				qp = wrap(qp, this.options.lineLength);
				qp = qp.replace(/(^|\n)([^\n]*)$/, (match, lineBreak, lastLine) => {
					this._curLine = lastLine;
					return lineBreak;
				});
				if (qp) {
					this.outputBytes += qp.length;
					this.push(qp);
				}
			} else {
				qp = encode(chunk);
				this.outputBytes += qp.length;
				this.push(qp, "ascii");
			}
			done();
		}
		_flush(done) {
			if (this._curLine) {
				this.outputBytes += this._curLine.length;
				this.push(this._curLine, "ascii");
			}
			done();
		}
	};
	module.exports = {
		encode,
		wrap,
		Encoder
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-funcs/index.js
var require_mime_funcs = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var base64 = require_base64();
	var qp = require_qp();
	var mimeTypes = require_mime_types();
	module.exports = {
		/**
		* Checks if a value is plaintext string (uses only printable 7bit chars)
		*
		* @param {String} value String to be tested
		* @returns {Boolean} true if it is a plaintext string
		*/
		isPlainText(value, isParam) {
			return typeof value === "string" && !(isParam ? /[\x00-\x08\x0b\x0c\x0e-\x1f"\u0080-\uFFFF]/ : /[\x00-\x08\x0b\x0c\x0e-\x1f\u0080-\uFFFF]/).test(value);
		},
		/**
		* Checks if a multi line string containes lines longer than the selected value.
		*
		* Useful when detecting if a mail message needs any processing at all –
		* if only plaintext characters are used and lines are short, then there is
		* no need to encode the values in any way. If the value is plaintext but has
		* longer lines then allowed, then use format=flowed
		*
		* @param {Number} lineLength Max line length to check for
		* @returns {Boolean} Returns true if there is at least one line longer than lineLength chars
		*/
		hasLongerLines(str, lineLength) {
			if (str.length > 131072) return true;
			return new RegExp("^.{" + (lineLength + 1) + ",}", "m").test(str);
		},
		/**
		* Encodes a string or an Buffer to an UTF-8 MIME Word (rfc2047)
		*
		* @param {String|Buffer} data String to be encoded
		* @param {String} mimeWordEncoding='Q' Encoding for the mime word, either Q or B
		* @param {Number} [maxLength=0] If set, split mime words into several chunks if needed
		* @return {String} Single or several mime words joined together
		*/
		encodeWord(data, mimeWordEncoding, maxLength) {
			mimeWordEncoding = (mimeWordEncoding || "Q").toString().toUpperCase().trim().charAt(0);
			maxLength = maxLength || 0;
			let encodedStr;
			if (maxLength && maxLength > 12) maxLength -= 12;
			if (mimeWordEncoding === "Q") encodedStr = qp.encode(data).replace(/[^a-z0-9!*+\-/=]/gi, (chr) => {
				const ord = chr.charCodeAt(0).toString(16).toUpperCase();
				if (chr === " ") return "_";
				return "=" + (ord.length === 1 ? "0" + ord : ord);
			});
			else if (mimeWordEncoding === "B") {
				encodedStr = typeof data === "string" ? data : base64.encode(data);
				maxLength = maxLength ? Math.max(3, (maxLength - maxLength % 4) / 4 * 3) : 0;
			}
			if (maxLength && (mimeWordEncoding !== "B" ? encodedStr : base64.encode(data)).length > maxLength) if (mimeWordEncoding === "Q") encodedStr = this.splitMimeEncodedString(encodedStr, maxLength).join("?= =?UTF-8?" + mimeWordEncoding + "?");
			else {
				const parts = [];
				let lpart = "";
				for (let i = 0, len = encodedStr.length; i < len; i++) {
					let chr = encodedStr.charAt(i);
					if (/[\ud83c\ud83d\ud83e]/.test(chr) && i < len - 1) chr += encodedStr.charAt(++i);
					if (Buffer.byteLength(lpart + chr) <= maxLength || i === 0) lpart += chr;
					else {
						parts.push(base64.encode(lpart));
						lpart = chr;
					}
				}
				if (lpart) parts.push(base64.encode(lpart));
				if (parts.length > 1) encodedStr = parts.join("?= =?UTF-8?" + mimeWordEncoding + "?");
				else encodedStr = parts.join("");
			}
			else if (mimeWordEncoding === "B") encodedStr = base64.encode(data);
			return "=?UTF-8?" + mimeWordEncoding + "?" + encodedStr + (encodedStr.substr(-2) === "?=" ? "" : "?=");
		},
		/**
		* Finds word sequences with non ascii text and converts these to mime words
		*
		* @param {String} value String to be encoded
		* @param {String} mimeWordEncoding='Q' Encoding for the mime word, either Q or B
		* @param {Number} [maxLength=0] If set, split mime words into several chunks if needed
		* @param {Boolean} [encodeAll=false] If true and the value needs encoding then encodes entire string, not just the smallest match
		* @return {String} String with possible mime words
		*/
		encodeWords(value, mimeWordEncoding, maxLength, encodeAll) {
			maxLength = maxLength || 0;
			const firstMatch = value.match(/(?:^|\s)([^\s]*["\u0080-\uFFFF])/);
			if (!firstMatch) return value;
			if (encodeAll) return this.encodeWord(value, mimeWordEncoding, maxLength);
			const lastMatch = value.match(/(["\u0080-\uFFFF][^\s]*)[^"\u0080-\uFFFF]*$/);
			if (!lastMatch) return value;
			const startIndex = firstMatch.index + (firstMatch[0].match(/[^\s]/) || { index: 0 }).index;
			const endIndex = lastMatch.index + (lastMatch[1] || "").length;
			return (startIndex ? value.substr(0, startIndex) : "") + this.encodeWord(value.substring(startIndex, endIndex), mimeWordEncoding || "Q", maxLength) + (endIndex < value.length ? value.substr(endIndex) : "");
		},
		/**
		* Joins parsed header value together as 'value; param1=value1; param2=value2'
		* PS: We are following RFC 822 for the list of special characters that we need to keep in quotes.
		*      Refer: https://www.w3.org/Protocols/rfc1341/4_Content-Type.html
		* @param {Object} structured Parsed header value
		* @return {String} joined header value
		*/
		buildHeaderValue(structured) {
			const paramsArray = [];
			Object.keys(structured.params || {}).forEach((param) => {
				const value = structured.params[param];
				if (!this.isPlainText(value, true) || value.length >= 75) this.buildHeaderParam(param, value, 50).forEach((encodedParam) => {
					if (!/[\s"\\;:/=(),<>@[\]?]|^[-']|'$/.test(encodedParam.value) || encodedParam.key.substr(-1) === "*") paramsArray.push(encodedParam.key + "=" + encodedParam.value);
					else paramsArray.push(encodedParam.key + "=" + JSON.stringify(encodedParam.value));
				});
				else if (/[\s'"\\;:/=(),<>@[\]?]|^-/.test(value)) paramsArray.push(param + "=" + JSON.stringify(value));
				else paramsArray.push(param + "=" + value);
			});
			return structured.value + (paramsArray.length ? "; " + paramsArray.join("; ") : "");
		},
		/**
		* Encodes a string or an Buffer to an UTF-8 Parameter Value Continuation encoding (rfc2231)
		* Useful for splitting long parameter values.
		*
		* For example
		*      title="unicode string"
		* becomes
		*     title*0*=utf-8''unicode
		*     title*1*=%20string
		*
		* @param {String|Buffer} data String to be encoded
		* @param {Number} [maxLength=50] Max length for generated chunks
		* @param {String} [fromCharset='UTF-8'] Source sharacter set
		* @return {Array} A list of encoded keys and headers
		*/
		buildHeaderParam(key, data, maxLength) {
			const list = [];
			let encodedStr = typeof data === "string" ? data : (data || "").toString();
			let chr, ord;
			let line;
			let startPos = 0;
			let i, len;
			maxLength = maxLength || 50;
			if (this.isPlainText(data, true)) {
				if (encodedStr.length <= maxLength) return [{
					key,
					value: encodedStr
				}];
				encodedStr = encodedStr.replace(new RegExp(".{" + maxLength + "}", "g"), (str) => {
					list.push({ line: str });
					return "";
				});
				if (encodedStr) list.push({ line: encodedStr });
			} else {
				if (/[\uD800-\uDBFF]/.test(encodedStr)) {
					const encodedStrArr = [];
					for (i = 0, len = encodedStr.length; i < len; i++) {
						chr = encodedStr.charAt(i);
						ord = chr.charCodeAt(0);
						if (ord >= 55296 && ord <= 56319 && i < len - 1) {
							chr += encodedStr.charAt(i + 1);
							encodedStrArr.push(chr);
							i++;
						} else encodedStrArr.push(chr);
					}
					encodedStr = encodedStrArr;
				}
				line = "utf-8''";
				let encoded = true;
				startPos = 0;
				for (i = 0, len = encodedStr.length; i < len; i++) {
					chr = encodedStr[i];
					if (encoded) chr = this.safeEncodeURIComponent(chr);
					else {
						chr = chr === " " ? chr : this.safeEncodeURIComponent(chr);
						if (chr !== encodedStr[i]) if ((this.safeEncodeURIComponent(line) + chr).length >= maxLength) {
							list.push({
								line,
								encoded
							});
							line = "";
							startPos = i - 1;
						} else {
							encoded = true;
							i = startPos;
							line = "";
							continue;
						}
					}
					if ((line + chr).length >= maxLength) {
						list.push({
							line,
							encoded
						});
						line = chr = encodedStr[i] === " " ? " " : this.safeEncodeURIComponent(encodedStr[i]);
						if (chr === encodedStr[i]) {
							encoded = false;
							startPos = i - 1;
						} else encoded = true;
					} else line += chr;
				}
				if (line) list.push({
					line,
					encoded
				});
			}
			return list.map((item, i) => ({
				key: key + "*" + i + (item.encoded ? "*" : ""),
				value: item.line
			}));
		},
		/**
		* Parses a header value with key=value arguments into a structured
		* object.
		*
		*   parseHeaderValue('content-type: text/plain; CHARSET='UTF-8'') ->
		*   {
		*     'value': 'text/plain',
		*     'params': {
		*       'charset': 'UTF-8'
		*     }
		*   }
		*
		* @param {String} str Header value
		* @return {Object} Header value as a parsed structure
		*/
		parseHeaderValue(str) {
			const response = {
				value: false,
				params: {}
			};
			let key = false;
			let value = "";
			let type = "value";
			let quote = false;
			let escaped = false;
			let chr;
			for (let i = 0, len = str.length; i < len; i++) {
				chr = str.charAt(i);
				if (type === "key") {
					if (chr === "=") {
						key = value.trim().toLowerCase();
						type = "value";
						value = "";
						continue;
					}
					value += chr;
				} else {
					if (escaped) value += chr;
					else if (chr === "\\") {
						escaped = true;
						continue;
					} else if (quote && chr === quote) quote = false;
					else if (!quote && chr === "\"") quote = chr;
					else if (!quote && chr === ";") {
						if (key === false) response.value = value.trim();
						else response.params[key] = value.trim();
						type = "key";
						value = "";
					} else value += chr;
					escaped = false;
				}
			}
			if (type === "value") if (key === false) response.value = value.trim();
			else response.params[key] = value.trim();
			else if (value.trim()) response.params[value.trim().toLowerCase()] = "";
			Object.keys(response.params).forEach((key) => {
				let actualKey, nr, match, value;
				if (match = key.match(/(\*(\d+)|\*(\d+)\*|\*)$/)) {
					actualKey = key.substr(0, match.index);
					nr = Number(match[2] || match[3]) || 0;
					if (!response.params[actualKey] || typeof response.params[actualKey] !== "object") response.params[actualKey] = {
						charset: false,
						values: []
					};
					value = response.params[key];
					if (nr === 0 && match[0].substr(-1) === "*" && (match = value.match(/^([^']*)'[^']*'(.*)$/))) {
						response.params[actualKey].charset = match[1] || "iso-8859-1";
						value = match[2];
					}
					response.params[actualKey].values[nr] = value;
					delete response.params[key];
				}
			});
			Object.keys(response.params).forEach((key) => {
				let value;
				if (response.params[key] && Array.isArray(response.params[key].values)) {
					value = response.params[key].values.map((val) => val || "").join("");
					if (response.params[key].charset) response.params[key] = "=?" + response.params[key].charset + "?Q?" + value.replace(/[=?_\s]/g, (s) => {
						const c = s.charCodeAt(0).toString(16);
						if (s === " ") return "_";
						return "%" + (c.length < 2 ? "0" : "") + c;
					}).replace(/%/g, "=") + "?=";
					else response.params[key] = value;
				}
			});
			return response;
		},
		/**
		* Returns file extension for a content type string. If no suitable extensions
		* are found, 'bin' is used as the default extension
		*
		* @param {String} mimeType Content type to be checked for
		* @return {String} File extension
		*/
		detectExtension: (mimeType) => mimeTypes.detectExtension(mimeType),
		/**
		* Returns content type for a file extension. If no suitable content types
		* are found, 'application/octet-stream' is used as the default content type
		*
		* @param {String} extension Extension to be checked for
		* @return {String} File extension
		*/
		detectMimeType: (extension) => mimeTypes.detectMimeType(extension),
		/**
		* Folds long lines, useful for folding header lines (afterSpace=false) and
		* flowed text (afterSpace=true)
		*
		* @param {String} str String to be folded
		* @param {Number} [lineLength=76] Maximum length of a line
		* @param {Boolean} afterSpace If true, leave a space in th end of a line
		* @return {String} String with folded lines
		*/
		foldLines(str, lineLength, afterSpace) {
			str = (str || "").toString();
			lineLength = lineLength || 76;
			let pos = 0;
			const len = str.length;
			let result = "";
			let line, match;
			while (pos < len) {
				line = str.substr(pos, lineLength);
				if (line.length < lineLength) {
					result += line;
					break;
				}
				if (match = line.match(/^[^\n\r]*(\r?\n|\r)/)) {
					line = match[0];
					result += line;
					pos += line.length;
					continue;
				} else if ((match = line.match(/(\s+)[^\s]*$/)) && match[0].length - (afterSpace ? (match[1] || "").length : 0) < line.length) line = line.substr(0, line.length - (match[0].length - (afterSpace ? (match[1] || "").length : 0)));
				else if (match = str.substr(pos + line.length).match(/^[^\s]+(\s*)/)) line = line + match[0].substr(0, match[0].length - (!afterSpace ? (match[1] || "").length : 0));
				result += line;
				pos += line.length;
				if (pos < len) result += "\r\n";
			}
			return result;
		},
		/**
		* Splits a mime encoded string. Needed for dividing mime words into smaller chunks
		*
		* @param {String} str Mime encoded string to be split up
		* @param {Number} maxlen Maximum length of characters for one part (minimum 12)
		* @return {Array} Split string
		*/
		splitMimeEncodedString: (str, maxlen) => {
			const lines = [];
			let curLine, match, chr, done;
			maxlen = Math.max(maxlen || 0, 12);
			while (str.length) {
				curLine = str.substr(0, maxlen);
				if (match = curLine.match(/[=][0-9A-F]?$/i)) curLine = curLine.substr(0, match.index);
				done = false;
				while (!done) {
					done = true;
					if (match = str.substr(curLine.length).match(/^[=]([0-9A-F]{2})/i)) {
						chr = parseInt(match[1], 16);
						if (chr < 194 && chr > 127) {
							curLine = curLine.substr(0, curLine.length - 3);
							done = false;
						}
					}
				}
				if (curLine.length) lines.push(curLine);
				str = str.substr(curLine.length);
			}
			return lines;
		},
		encodeURICharComponent: (chr) => {
			let res = "";
			let ord = chr.charCodeAt(0).toString(16).toUpperCase();
			if (ord.length % 2) ord = "0" + ord;
			if (ord.length > 2) for (let i = 0, len = ord.length / 2; i < len; i++) res += "%" + ord.substr(i, 2);
			else res += "%" + ord;
			return res;
		},
		safeEncodeURIComponent(str) {
			str = (str || "").toString();
			try {
				str = encodeURIComponent(str);
			} catch (_E) {
				return str.replace(/[^\x00-\x1F *'()<>@,;:\\"[\]?=\u007F-\uFFFF]+/g, "");
			}
			return str.replace(/[\x00-\x1F *'()<>@,;:\\"[\]?=\u007F-\uFFFF]/g, (chr) => this.encodeURICharComponent(chr));
		}
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/addressparser/index.js
var require_addressparser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/**
	* Converts tokens for a single address into an address object
	*
	* @param {Array} tokens Tokens object
	* @param {Number} depth Current recursion depth for nested group protection
	* @return {Object} Address object
	*/
	function _handleAddress(tokens, depth) {
		let isGroup = false;
		let state = "text";
		const addresses = [];
		const data = {
			address: [],
			comment: [],
			group: [],
			text: [],
			textWasQuoted: []
		};
		let insideQuotes = false;
		for (let i = 0, len = tokens.length; i < len; i++) {
			const token = tokens[i];
			const prevToken = i ? tokens[i - 1] : null;
			if (token.type === "operator") switch (token.value) {
				case "<":
					state = "address";
					insideQuotes = false;
					break;
				case "(":
					state = "comment";
					insideQuotes = false;
					break;
				case ":":
					state = "group";
					isGroup = true;
					insideQuotes = false;
					break;
				case "\"":
					insideQuotes = !insideQuotes;
					state = "text";
					break;
				default:
					state = "text";
					insideQuotes = false;
			}
			else if (token.value) {
				if (state === "address") token.value = token.value.replace(/^[^<]*<\s*/, "");
				if (prevToken && prevToken.noBreak && data[state].length) {
					data[state][data[state].length - 1] += token.value;
					if (state === "text" && insideQuotes) data.textWasQuoted[data.textWasQuoted.length - 1] = true;
				} else {
					data[state].push(token.value);
					if (state === "text") data.textWasQuoted.push(insideQuotes);
				}
			}
		}
		if (!data.text.length && data.comment.length) {
			data.text = data.comment;
			data.comment = [];
		}
		if (isGroup) {
			data.text = data.text.join(" ");
			let groupMembers = [];
			if (data.group.length) addressparser(data.group.join(","), { _depth: depth + 1 }).forEach((member) => {
				if (member.group) groupMembers = groupMembers.concat(member.group);
				else groupMembers.push(member);
			});
			addresses.push({
				name: data.text || "",
				group: groupMembers
			});
		} else {
			if (!data.address.length && data.text.length) {
				for (let i = data.text.length - 1; i >= 0; i--) if (!data.textWasQuoted[i] && /^[^@\s]+@[^@\s]+$/.test(data.text[i])) {
					data.address = data.text.splice(i, 1);
					data.textWasQuoted.splice(i, 1);
					break;
				}
				if (!data.address.length) {
					let extracted = false;
					for (let i = data.text.length - 1; i >= 0; i--) if (!data.textWasQuoted[i]) {
						data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^\s]+\b\s*/, (match) => {
							if (!extracted) {
								data.address = [match.trim()];
								extracted = true;
								return " ";
							}
							return match;
						}).trim();
						if (extracted) break;
					}
				}
			}
			if (!data.text.length && data.comment.length) {
				data.text = data.comment;
				data.comment = [];
			}
			if (data.address.length > 1) data.text = data.text.concat(data.address.splice(1));
			data.text = data.text.join(" ");
			data.address = data.address.join(" ");
			const address = {
				address: data.address || data.text || "",
				name: data.text || data.address || ""
			};
			if (address.address === address.name) if (/@/.test(address.address || "")) address.name = "";
			else address.address = "";
			addresses.push(address);
		}
		return addresses;
	}
	/**
	* Creates a Tokenizer object for tokenizing address field strings
	*
	* @constructor
	* @param {String} str Address field string
	*/
	var Tokenizer = class {
		constructor(str) {
			this.str = (str || "").toString();
			this.operatorCurrent = "";
			this.operatorExpecting = "";
			this.node = null;
			this.escaped = false;
			this.inDomainLiteral = false;
			this.list = [];
			/**
			* Operator tokens and which tokens are expected to end the sequence
			*/
			this.operators = {
				"\"": "\"",
				"(": ")",
				"<": ">",
				",": "",
				":": ";",
				";": ""
			};
		}
		/**
		* Tokenizes the original input string
		*
		* @return {Array} An array of operator|text tokens
		*/
		tokenize() {
			const list = [];
			for (let i = 0, len = this.str.length; i < len; i++) {
				const chr = this.str.charAt(i);
				const nextChr = i < len - 1 ? this.str.charAt(i + 1) : null;
				this.checkChar(chr, nextChr);
			}
			this.list.forEach((node) => {
				node.value = (node.value || "").toString().trim();
				if (node.value) list.push(node);
			});
			return list;
		}
		/**
		* Checks if a character is an operator or text and acts accordingly
		*
		* @param {String} chr Character from the address field
		*/
		checkChar(chr, nextChr) {
			if (!this.escaped && !this.operatorExpecting) {
				if (!this.inDomainLiteral && chr === "[") this.inDomainLiteral = true;
				else if (this.inDomainLiteral && (chr === "]" || chr === "," || chr === ";")) this.inDomainLiteral = false;
			}
			if (this.escaped) {} else if (chr === this.operatorExpecting) {
				this.node = {
					type: "operator",
					value: chr
				};
				if (nextChr && ![
					" ",
					"	",
					"\r",
					"\n",
					",",
					";"
				].includes(nextChr)) this.node.noBreak = true;
				this.list.push(this.node);
				this.node = null;
				this.operatorExpecting = "";
				this.escaped = false;
				return;
			} else if (!this.operatorExpecting && !this.inDomainLiteral && chr in this.operators) {
				this.node = {
					type: "operator",
					value: chr
				};
				this.list.push(this.node);
				this.node = null;
				this.operatorExpecting = this.operators[chr];
				this.escaped = false;
				return;
			} else if (["\"", "'"].includes(this.operatorExpecting) && chr === "\\") {
				this.escaped = true;
				return;
			}
			if (!this.node) {
				this.node = {
					type: "text",
					value: ""
				};
				this.list.push(this.node);
			}
			if (chr === "\n") chr = " ";
			if (chr.charCodeAt(0) >= 33 || [" ", "	"].includes(chr)) this.node.value += chr;
			this.escaped = false;
		}
	};
	/**
	* Maximum recursion depth for parsing nested groups.
	* RFC 5322 doesn't allow nested groups, so this is a safeguard against
	* malicious input that could cause stack overflow.
	*/
	var MAX_NESTED_GROUP_DEPTH = 50;
	/**
	* Parses structured e-mail addresses from an address field
	*
	* Example:
	*
	*    'Name <address@domain>'
	*
	* will be converted to
	*
	*     [{name: 'Name', address: 'address@domain'}]
	*
	* @param {String} str Address field
	* @param {Object} options Optional options object
	* @param {Number} options._depth Internal recursion depth counter (do not set manually)
	* @return {Array} An array of address objects
	*/
	function addressparser(str, options) {
		options = options || {};
		const depth = options._depth || 0;
		if (depth > MAX_NESTED_GROUP_DEPTH) return [];
		const tokens = new Tokenizer(str).tokenize();
		const addresses = [];
		let address = [];
		let parsedAddresses = [];
		tokens.forEach((token) => {
			if (token.type === "operator" && (token.value === "," || token.value === ";")) {
				if (address.length) addresses.push(address);
				address = [];
			} else address.push(token);
		});
		if (address.length) addresses.push(address);
		addresses.forEach((addr) => {
			const handled = _handleAddress(addr, depth);
			if (handled.length) parsedAddresses = parsedAddresses.concat(handled);
		});
		for (let i = parsedAddresses.length - 2; i >= 0; i--) {
			const current = parsedAddresses[i];
			const next = parsedAddresses[i + 1];
			if (current.address === "" && current.name && !current.group && next.address && next.name) {
				next.name = current.name + ", " + next.name;
				parsedAddresses.splice(i, 1);
			}
		}
		if (options.flatten) {
			const flatAddresses = [];
			const walkAddressList = (list) => {
				list.forEach((entry) => {
					if (entry.group) return walkAddressList(entry.group);
					flatAddresses.push(entry);
				});
			};
			walkAddressList(parsedAddresses);
			return flatAddresses;
		}
		return parsedAddresses;
	}
	module.exports = addressparser;
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-node/last-newline.js
var require_last_newline = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$5 } = __require("stream");
	var LastNewline = class extends Transform$5 {
		constructor() {
			super();
			this.lastByte = false;
		}
		_transform(chunk, encoding, done) {
			if (chunk.length) this.lastByte = chunk[chunk.length - 1];
			this.push(chunk);
			done();
		}
		_flush(done) {
			if (this.lastByte === 10) return done();
			if (this.lastByte === 13) {
				this.push(Buffer.from("\n"));
				return done();
			}
			this.push(Buffer.from("\r\n"));
			return done();
		}
	};
	module.exports = LastNewline;
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-node/le-windows.js
var require_le_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$4 } = __require("stream");
	/**
	* Ensures that only <CR><LF> sequences are used for linebreaks
	*
	* @param {Object} options Stream options
	*/
	var LeWindows = class extends Transform$4 {
		constructor(options) {
			super(options);
			this.lastByte = false;
		}
		/**
		* Escapes dots
		*/
		_transform(chunk, encoding, done) {
			let buf;
			let lastPos = 0;
			for (let i = 0, len = chunk.length; i < len; i++) if (chunk[i] === 10) {
				if (i && chunk[i - 1] !== 13 || !i && this.lastByte !== 13) {
					if (i > lastPos) {
						buf = chunk.slice(lastPos, i);
						this.push(buf);
					}
					this.push(Buffer.from("\r\n"));
					lastPos = i + 1;
				}
			}
			if (lastPos && lastPos < chunk.length) {
				buf = chunk.slice(lastPos);
				this.push(buf);
			} else if (!lastPos) this.push(chunk);
			this.lastByte = chunk[chunk.length - 1];
			done();
		}
	};
	module.exports = LeWindows;
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-node/le-unix.js
var require_le_unix = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$3 } = __require("stream");
	/**
	* Ensures that only <LF> is used for linebreaks
	*
	* @param {Object} options Stream options
	*/
	var LeUnix = class extends Transform$3 {
		constructor(options) {
			super(options);
		}
		/**
		* Escapes dots
		*/
		_transform(chunk, encoding, done) {
			let buf;
			let lastPos = 0;
			for (let i = 0, len = chunk.length; i < len; i++) if (chunk[i] === 13) {
				buf = chunk.slice(lastPos, i);
				lastPos = i + 1;
				this.push(buf);
			}
			if (lastPos && lastPos < chunk.length) {
				buf = chunk.slice(lastPos);
				this.push(buf);
			} else if (!lastPos) this.push(chunk);
			done();
		}
	};
	module.exports = LeUnix;
}));
//#endregion
//#region node_modules/nodemailer/lib/mime-node/index.js
var require_mime_node = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var crypto$8 = __require("crypto");
	var fs$4 = __require("fs");
	var punycode = require_punycode();
	var { PassThrough: PassThrough$2 } = __require("stream");
	var shared = require_shared();
	var mimeFuncs = require_mime_funcs();
	var qp = require_qp();
	var base64 = require_base64();
	var addressparser = require_addressparser();
	var nmfetch = require_fetch();
	var errors = require_errors();
	var LastNewline = require_last_newline();
	var LeWindows = require_le_windows();
	var LeUnix = require_le_unix();
	var FORMATTED_HEADERS = [
		"From",
		"Sender",
		"To",
		"Cc",
		"Bcc",
		"Reply-To",
		"Date",
		"References"
	];
	module.exports = class MimeNode {
		constructor(contentType, options) {
			this.nodeCounter = 0;
			options = options || {};
			/**
			* shared part of the unique multipart boundary
			*/
			this.baseBoundary = options.baseBoundary || crypto$8.randomBytes(8).toString("hex");
			this.boundaryPrefix = options.boundaryPrefix || "--_NmP";
			this.disableFileAccess = !!options.disableFileAccess;
			this.disableUrlAccess = !!options.disableUrlAccess;
			this.normalizeHeaderKey = options.normalizeHeaderKey;
			/**
			* If date headers is missing and current node is the root, this value is used instead
			*/
			this.date = options.parentNode ? null : /* @__PURE__ */ new Date();
			/**
			* Root node for current mime tree
			*/
			this.rootNode = options.rootNode || this;
			/**
			* If true include Bcc in generated headers (if available)
			*/
			this.keepBcc = !!options.keepBcc;
			/**
			* If filename is specified but contentType is not (probably an attachment)
			* detect the content type from filename extension
			*/
			if (options.filename) {
				/**
				* Filename for this node. Useful with attachments
				*/
				this.filename = options.filename;
				if (!contentType) contentType = mimeFuncs.detectMimeType(this.filename.split(".").pop());
			}
			/**
			* Indicates which encoding should be used for header strings: "Q" or "B"
			*/
			this.textEncoding = (options.textEncoding || "").toString().trim().charAt(0).toUpperCase();
			/**
			* Immediate parent for this node (or undefined if not set)
			*/
			this.parentNode = options.parentNode;
			/**
			* Hostname for default message-id values
			*/
			this.hostname = options.hostname;
			/**
			* If set to 'win' then uses \r\n, if 'linux' then \n. If not set (or `raw` is used) then newlines are kept as is.
			*/
			this.newline = options.newline;
			/**
			* An array for possible child nodes
			*/
			this.childNodes = [];
			/**
			* Used for generating unique boundaries (prepended to the shared base)
			*/
			this._nodeId = ++this.rootNode.nodeCounter;
			/**
			* A list of header values for this node in the form of [{key:'', value:''}]
			*/
			this._headers = [];
			/**
			* True if the content only uses ASCII printable characters
			* @type {Boolean}
			*/
			this._isPlainText = false;
			/**
			* True if the content is plain text but has longer lines than allowed
			* @type {Boolean}
			*/
			this._hasLongLines = false;
			/**
			* If set, use instead this value for envelopes instead of generating one
			* @type {Boolean}
			*/
			this._envelope = false;
			/**
			* If set then use this value as the stream content instead of building it
			* @type {String|Buffer|Stream}
			*/
			this._raw = false;
			/**
			* Additional transform streams that the message will be piped before
			* exposing by createReadStream
			* @type {Array}
			*/
			this._transforms = [];
			/**
			* Additional process functions that the message will be piped through before
			* exposing by createReadStream. These functions are run after transforms
			* @type {Array}
			*/
			this._processFuncs = [];
			/**
			* If content type is set (or derived from the filename) add it to headers
			*/
			if (contentType) this.setHeader("Content-Type", contentType);
		}
		/**
		* Creates and appends a child node.Arguments provided are passed to MimeNode constructor
		*
		* @param {String} [contentType] Optional content type
		* @param {Object} [options] Optional options object
		* @return {Object} Created node object
		*/
		createChild(contentType, options) {
			if (!options && typeof contentType === "object") {
				options = contentType;
				contentType = void 0;
			}
			const node = new MimeNode(contentType, options);
			this.appendChild(node);
			return node;
		}
		/**
		* Appends an existing node to the mime tree. Removes the node from an existing
		* tree if needed
		*
		* @param {Object} childNode node to be appended
		* @return {Object} Appended node object
		*/
		appendChild(childNode) {
			if (childNode.rootNode !== this.rootNode) {
				childNode.rootNode = this.rootNode;
				childNode._nodeId = ++this.rootNode.nodeCounter;
			}
			childNode.parentNode = this;
			this.childNodes.push(childNode);
			return childNode;
		}
		/**
		* Replaces current node with another node
		*
		* @param {Object} node Replacement node
		* @return {Object} Replacement node
		*/
		replace(node) {
			if (node === this) return this;
			this.parentNode.childNodes.forEach((childNode, i) => {
				if (childNode === this) {
					node.rootNode = this.rootNode;
					node.parentNode = this.parentNode;
					node._nodeId = this._nodeId;
					this.rootNode = this;
					this.parentNode = void 0;
					node.parentNode.childNodes[i] = node;
				}
			});
			return node;
		}
		/**
		* Removes current node from the mime tree
		*
		* @return {Object} removed node
		*/
		remove() {
			if (!this.parentNode) return this;
			for (let i = this.parentNode.childNodes.length - 1; i >= 0; i--) if (this.parentNode.childNodes[i] === this) {
				this.parentNode.childNodes.splice(i, 1);
				this.parentNode = void 0;
				this.rootNode = this;
				return this;
			}
		}
		/**
		* Sets a header value. If the value for selected key exists, it is overwritten.
		* You can set multiple values as well by using [{key:'', value:''}] or
		* {key: 'value'} as the first argument.
		*
		* @param {String|Array|Object} key Header key or a list of key value pairs
		* @param {String} value Header value
		* @return {Object} current node
		*/
		setHeader(key, value) {
			let added = false;
			if (!value && key && typeof key === "object") {
				if (key.key && "value" in key) this.setHeader(key.key, key.value);
				else if (Array.isArray(key)) key.forEach((i) => {
					this.setHeader(i.key, i.value);
				});
				else Object.keys(key).forEach((i) => {
					this.setHeader(i, key[i]);
				});
				return this;
			}
			key = this._normalizeHeaderKey(key);
			const headerValue = {
				key,
				value
			};
			for (let i = 0, len = this._headers.length; i < len; i++) if (this._headers[i].key === key) if (!added) {
				this._headers[i] = headerValue;
				added = true;
			} else {
				this._headers.splice(i, 1);
				i--;
				len--;
			}
			if (!added) this._headers.push(headerValue);
			return this;
		}
		/**
		* Adds a header value. If the value for selected key exists, the value is appended
		* as a new field and old one is not touched.
		* You can set multiple values as well by using [{key:'', value:''}] or
		* {key: 'value'} as the first argument.
		*
		* @param {String|Array|Object} key Header key or a list of key value pairs
		* @param {String} value Header value
		* @return {Object} current node
		*/
		addHeader(key, value) {
			if (!value && key && typeof key === "object") {
				if (key.key && key.value) this.addHeader(key.key, key.value);
				else if (Array.isArray(key)) key.forEach((i) => {
					this.addHeader(i.key, i.value);
				});
				else Object.keys(key).forEach((i) => {
					this.addHeader(i, key[i]);
				});
				return this;
			} else if (Array.isArray(value)) {
				value.forEach((val) => {
					this.addHeader(key, val);
				});
				return this;
			}
			this._headers.push({
				key: this._normalizeHeaderKey(key),
				value
			});
			return this;
		}
		/**
		* Retrieves the first mathcing value of a selected key
		*
		* @param {String} key Key to search for
		* @retun {String} Value for the key
		*/
		getHeader(key) {
			key = this._normalizeHeaderKey(key);
			for (let i = 0, len = this._headers.length; i < len; i++) if (this._headers[i].key === key) return this._headers[i].value;
		}
		/**
		* Sets body content for current node. If the value is a string, charset is added automatically
		* to Content-Type (if it is text/*). If the value is a Buffer, you need to specify
		* the charset yourself
		*
		* @param (String|Buffer) content Body content
		* @return {Object} current node
		*/
		setContent(content) {
			this.content = content;
			if (typeof this.content.pipe === "function") {
				this._contentErrorHandler = (err) => {
					this.content.removeListener("error", this._contentErrorHandler);
					this.content = err;
				};
				this.content.once("error", this._contentErrorHandler);
			} else if (typeof this.content === "string") {
				this._isPlainText = mimeFuncs.isPlainText(this.content);
				if (this._isPlainText && mimeFuncs.hasLongerLines(this.content, 76)) this._hasLongLines = true;
			}
			return this;
		}
		build(callback) {
			let promise;
			if (!callback) promise = new Promise((resolve, reject) => {
				callback = shared.callbackPromise(resolve, reject);
			});
			const stream = this.createReadStream();
			const buf = [];
			let buflen = 0;
			let returned = false;
			stream.on("readable", () => {
				let chunk;
				while ((chunk = stream.read()) !== null) {
					buf.push(chunk);
					buflen += chunk.length;
				}
			});
			stream.once("error", (err) => {
				if (returned) return;
				returned = true;
				return callback(err);
			});
			stream.once("end", (chunk) => {
				if (returned) return;
				returned = true;
				if (chunk && chunk.length) {
					buf.push(chunk);
					buflen += chunk.length;
				}
				return callback(null, Buffer.concat(buf, buflen));
			});
			return promise;
		}
		getTransferEncoding() {
			let transferEncoding = false;
			const contentType = (this.getHeader("Content-Type") || "").toString().toLowerCase().trim();
			if (this.content) {
				transferEncoding = (this.getHeader("Content-Transfer-Encoding") || "").toString().toLowerCase().trim();
				if (!transferEncoding || !["base64", "quoted-printable"].includes(transferEncoding)) {
					if (/^text\//i.test(contentType)) if (this._isPlainText && !this._hasLongLines) transferEncoding = "7bit";
					else if (typeof this.content === "string" || this.content instanceof Buffer) transferEncoding = this._getTextEncoding(this.content) === "Q" ? "quoted-printable" : "base64";
					else transferEncoding = this.textEncoding === "B" ? "base64" : "quoted-printable";
					else if (!/^(multipart|message)\//i.test(contentType)) transferEncoding = transferEncoding || "base64";
				}
			}
			return transferEncoding;
		}
		/**
		* Builds the header block for the mime node. Append \r\n\r\n before writing the content
		*
		* @returns {String} Headers
		*/
		buildHeaders() {
			const transferEncoding = this.getTransferEncoding();
			const headers = [];
			if (transferEncoding) this.setHeader("Content-Transfer-Encoding", transferEncoding);
			if (this.filename && !this.getHeader("Content-Disposition")) this.setHeader("Content-Disposition", "attachment");
			if (this.rootNode === this) {
				if (!this.getHeader("Date")) this.setHeader("Date", this.date.toUTCString().replace(/GMT/, "+0000"));
				this.messageId();
				if (!this.getHeader("MIME-Version")) this.setHeader("MIME-Version", "1.0");
				for (let i = this._headers.length - 2; i >= 0; i--) {
					const header = this._headers[i];
					if (header.key === "Content-Type") {
						this._headers.splice(i, 1);
						this._headers.push(header);
					}
				}
			}
			this._headers.forEach((header) => {
				let key = header.key;
				let value = header.value;
				let structured;
				let param;
				const options = {};
				if (value && typeof value === "object" && !FORMATTED_HEADERS.includes(key)) {
					Object.keys(value).forEach((key) => {
						if (key !== "value") options[key] = value[key];
					});
					value = (value.value || "").toString();
					if (!value.trim()) return;
				}
				if (options.prepared) {
					if (options.foldLines) headers.push(mimeFuncs.foldLines(key + ": " + value));
					else headers.push(key + ": " + value);
					return;
				}
				switch (header.key) {
					case "Content-Disposition":
						structured = mimeFuncs.parseHeaderValue(value);
						if (this.filename) structured.params.filename = this.filename;
						value = mimeFuncs.buildHeaderValue(structured);
						break;
					case "Content-Type":
						structured = mimeFuncs.parseHeaderValue(value);
						this._handleContentType(structured);
						if (structured.value.match(/^text\/plain\b/) && typeof this.content === "string" && /[\u0080-\uFFFF]/.test(this.content)) structured.params.charset = "utf-8";
						value = mimeFuncs.buildHeaderValue(structured);
						if (this.filename) {
							param = this._encodeWords(this.filename);
							if (param !== this.filename || /[\s'"\\;:/=(),<>@[\]?]|^-/.test(param)) param = "\"" + param + "\"";
							value += "; name=" + param;
						}
						break;
					case "Bcc": if (!this.keepBcc) return;
				}
				value = this._encodeHeaderValue(key, value);
				if (!(value || "").toString().trim()) return;
				if (typeof this.normalizeHeaderKey === "function") {
					const normalized = this.normalizeHeaderKey(key, value);
					if (normalized && typeof normalized === "string" && normalized.length) key = normalized;
				}
				headers.push(mimeFuncs.foldLines(key + ": " + value, 76));
			});
			return headers.join("\r\n");
		}
		/**
		* Streams the rfc2822 message from the current node. If this is a root node,
		* mandatory header fields are set if missing (Date, Message-Id, MIME-Version)
		*
		* @return {String} Compiled message
		*/
		createReadStream(options) {
			options = options || {};
			const stream = new PassThrough$2(options);
			let outputStream = stream;
			let transform;
			this.stream(stream, options, (err) => {
				if (err) {
					outputStream.emit("error", err);
					return;
				}
				stream.end();
			});
			for (let i = 0, len = this._transforms.length; i < len; i++) {
				transform = typeof this._transforms[i] === "function" ? this._transforms[i]() : this._transforms[i];
				outputStream.once("error", (err) => {
					transform.emit("error", err);
				});
				outputStream = outputStream.pipe(transform);
			}
			transform = new LastNewline();
			outputStream.once("error", (err) => {
				transform.emit("error", err);
			});
			outputStream = outputStream.pipe(transform);
			for (let i = 0, len = this._processFuncs.length; i < len; i++) {
				transform = this._processFuncs[i];
				outputStream = transform(outputStream);
			}
			if (this.newline) {
				const newlineTransform = [
					"win",
					"windows",
					"dos",
					"\r\n"
				].includes(this.newline.toString().toLowerCase()) ? new LeWindows() : new LeUnix();
				const stream = outputStream.pipe(newlineTransform);
				outputStream.on("error", (err) => stream.emit("error", err));
				return stream;
			}
			return outputStream;
		}
		/**
		* Appends a transform stream object to the transforms list. Final output
		* is passed through this stream before exposing
		*
		* @param {Object} transform Read-Write stream
		*/
		transform(transform) {
			this._transforms.push(transform);
		}
		/**
		* Appends a post process function. The functon is run after transforms and
		* uses the following syntax
		*
		*   processFunc(input) -> outputStream
		*
		* @param {Object} processFunc Read-Write stream
		*/
		processFunc(processFunc) {
			this._processFuncs.push(processFunc);
		}
		stream(outputStream, options, done) {
			const transferEncoding = this.getTransferEncoding();
			let contentStream;
			let localStream;
			let returned = false;
			const callback = (err) => {
				if (returned) return;
				returned = true;
				done(err);
			};
			const finalize = () => {
				let childId = 0;
				const processChildNode = () => {
					if (childId >= this.childNodes.length) {
						outputStream.write("\r\n--" + this.boundary + "--\r\n");
						return callback();
					}
					const child = this.childNodes[childId++];
					outputStream.write((childId > 1 ? "\r\n" : "") + "--" + this.boundary + "\r\n");
					child.stream(outputStream, options, (err) => {
						if (err) return callback(err);
						setImmediate(processChildNode);
					});
				};
				if (this.multipart) setImmediate(processChildNode);
				else return callback();
			};
			const sendContent = () => {
				if (this.content) {
					if (Object.prototype.toString.call(this.content) === "[object Error]") return callback(this.content);
					if (typeof this.content.pipe === "function") {
						this.content.removeListener("error", this._contentErrorHandler);
						this._contentErrorHandler = (err) => callback(err);
						this.content.once("error", this._contentErrorHandler);
					}
					const createStream = () => {
						if (["quoted-printable", "base64"].includes(transferEncoding)) {
							contentStream = new (transferEncoding === "base64" ? base64 : qp).Encoder(options);
							contentStream.pipe(outputStream, { end: false });
							contentStream.once("end", finalize);
							contentStream.once("error", (err) => callback(err));
							localStream = this._getStream(this.content);
							localStream.pipe(contentStream);
						} else {
							localStream = this._getStream(this.content);
							localStream.pipe(outputStream, { end: false });
							localStream.once("end", finalize);
						}
						localStream.once("error", (err) => callback(err));
					};
					if (this.content._resolve) {
						const chunks = [];
						let chunklen = 0;
						let returned = false;
						const sourceStream = this._getStream(this.content);
						sourceStream.on("error", (err) => {
							if (returned) return;
							returned = true;
							callback(err);
						});
						sourceStream.on("readable", () => {
							let chunk;
							while ((chunk = sourceStream.read()) !== null) {
								chunks.push(chunk);
								chunklen += chunk.length;
							}
						});
						sourceStream.on("end", () => {
							if (returned) return;
							returned = true;
							this.content._resolve = false;
							this.content._resolvedValue = Buffer.concat(chunks, chunklen);
							setImmediate(createStream);
						});
					} else setImmediate(createStream);
					return;
				}
				return setImmediate(finalize);
			};
			if (this._raw) setImmediate(() => {
				if (Object.prototype.toString.call(this._raw) === "[object Error]") return callback(this._raw);
				if (typeof this._raw.pipe === "function") this._raw.removeListener("error", this._contentErrorHandler);
				const raw = this._getStream(this._raw);
				raw.pipe(outputStream, { end: false });
				raw.on("error", (err) => outputStream.emit("error", err));
				raw.on("end", finalize);
			});
			else {
				outputStream.write(this.buildHeaders() + "\r\n\r\n");
				setImmediate(sendContent);
			}
		}
		/**
		* Sets envelope to be used instead of the generated one
		*
		* @return {Object} SMTP envelope in the form of {from: 'from@example.com', to: ['to@example.com']}
		*/
		setEnvelope(envelope) {
			let list;
			this._envelope = {
				from: false,
				to: []
			};
			if (envelope.from) {
				list = [];
				this._convertAddresses(this._parseAddresses(envelope.from), list);
				list = list.filter((address) => address && address.address);
				if (list.length && list[0]) this._envelope.from = list[0].address;
			}
			[
				"to",
				"cc",
				"bcc"
			].forEach((key) => {
				if (envelope[key]) this._convertAddresses(this._parseAddresses(envelope[key]), this._envelope.to);
			});
			this._envelope.to = this._envelope.to.map((to) => to.address).filter((address) => address);
			const standardFields = [
				"to",
				"cc",
				"bcc",
				"from"
			];
			Object.keys(envelope).forEach((key) => {
				if (!standardFields.includes(key)) this._envelope[key] = envelope[key];
			});
			return this;
		}
		/**
		* Generates and returns an object with parsed address fields
		*
		* @return {Object} Address object
		*/
		getAddresses() {
			const addresses = {};
			this._headers.forEach((header) => {
				const key = header.key.toLowerCase();
				if ([
					"from",
					"sender",
					"reply-to",
					"to",
					"cc",
					"bcc"
				].includes(key)) {
					if (!Array.isArray(addresses[key])) addresses[key] = [];
					this._convertAddresses(this._parseAddresses(header.value), addresses[key]);
				}
			});
			return addresses;
		}
		/**
		* Generates and returns SMTP envelope with the sender address and a list of recipients addresses
		*
		* @return {Object} SMTP envelope in the form of {from: 'from@example.com', to: ['to@example.com']}
		*/
		getEnvelope() {
			if (this._envelope) return this._envelope;
			const envelope = {
				from: false,
				to: []
			};
			this._headers.forEach((header) => {
				const list = [];
				if (header.key === "From" || !envelope.from && ["Reply-To", "Sender"].includes(header.key)) {
					this._convertAddresses(this._parseAddresses(header.value), list);
					if (list.length && list[0]) envelope.from = list[0].address;
				} else if ([
					"To",
					"Cc",
					"Bcc"
				].includes(header.key)) this._convertAddresses(this._parseAddresses(header.value), envelope.to);
			});
			envelope.to = envelope.to.map((to) => to.address);
			return envelope;
		}
		/**
		* Returns Message-Id value. If it does not exist, then creates one
		*
		* @return {String} Message-Id value
		*/
		messageId() {
			let messageId = this.getHeader("Message-ID");
			if (!messageId) {
				messageId = this._generateMessageId();
				this.setHeader("Message-ID", messageId);
			}
			return messageId;
		}
		/**
		* Sets pregenerated content that will be used as the output of this node
		*
		* @param {String|Buffer|Stream} Raw MIME contents
		*/
		setRaw(raw) {
			this._raw = raw;
			if (this._raw && typeof this._raw.pipe === "function") {
				this._contentErrorHandler = (err) => {
					this._raw.removeListener("error", this._contentErrorHandler);
					this._raw = err;
				};
				this._raw.once("error", this._contentErrorHandler);
			}
			return this;
		}
		/**
		* Detects and returns handle to a stream related with the content.
		*
		* @param {Mixed} content Node content
		* @returns {Object} Stream object
		*/
		_getStream(content) {
			let contentStream;
			if (content._resolvedValue) {
				contentStream = new PassThrough$2();
				setImmediate(() => {
					try {
						contentStream.end(content._resolvedValue);
					} catch (_err) {
						contentStream.emit("error", _err);
					}
				});
				return contentStream;
			}
			if (typeof content.pipe === "function") return content;
			if (content && typeof content.path === "string" && !content.href) {
				if (this.disableFileAccess) {
					contentStream = new PassThrough$2();
					setImmediate(() => {
						const err = /* @__PURE__ */ new Error("File access rejected for " + content.path);
						err.code = errors.EFILEACCESS;
						contentStream.emit("error", err);
					});
					return contentStream;
				}
				return fs$4.createReadStream(content.path);
			}
			if (content && typeof content.href === "string") {
				if (this.disableUrlAccess) {
					contentStream = new PassThrough$2();
					setImmediate(() => {
						const err = /* @__PURE__ */ new Error("Url access rejected for " + content.href);
						err.code = errors.EURLACCESS;
						contentStream.emit("error", err);
					});
					return contentStream;
				}
				return nmfetch(content.href, {
					headers: content.httpHeaders,
					tls: content.tls
				});
			}
			contentStream = new PassThrough$2();
			setImmediate(() => {
				try {
					contentStream.end(content || "");
				} catch (_err) {
					contentStream.emit("error", _err);
				}
			});
			return contentStream;
		}
		/**
		* Parses addresses. Takes in a single address or an array or an
		* array of address arrays (eg. To: [[first group], [second group],...])
		*
		* @param {Mixed} addresses Addresses to be parsed
		* @return {Array} An array of address objects
		*/
		_parseAddresses(addresses) {
			return [].concat.apply([], [].concat(addresses).map((address) => {
				if (address && address.address) {
					address.address = this._normalizeAddress(address.address);
					address.name = address.name || "";
					return [address];
				}
				return addressparser(address);
			}));
		}
		/**
		* Normalizes a header key, uses Camel-Case form, except for uppercase MIME-
		*
		* @param {String} key Key to be normalized
		* @return {String} key in Camel-Case form
		*/
		_normalizeHeaderKey(key) {
			key = (key || "").toString().replace(/\r?\n|\r/g, " ").trim().toLowerCase().replace(/^X-SMTPAPI$|^(MIME|DKIM|ARC|BIMI)\b|^[a-z]|-(SPF|FBL|ID|MD5)$|-[a-z]/gi, (c) => c.toUpperCase()).replace(/^Content-Features$/i, "Content-features");
			return key;
		}
		/**
		* Checks if the content type is multipart and defines boundary if needed.
		* Doesn't return anything, modifies object argument instead.
		*
		* @param {Object} structured Parsed header value for 'Content-Type' key
		*/
		_handleContentType(structured) {
			this.contentType = structured.value.trim().toLowerCase();
			this.multipart = /^multipart\//i.test(this.contentType) ? this.contentType.substr(this.contentType.indexOf("/") + 1) : false;
			if (this.multipart) this.boundary = structured.params.boundary = structured.params.boundary || this.boundary || this._generateBoundary();
			else this.boundary = false;
		}
		/**
		* Generates a multipart boundary value
		*
		* @return {String} boundary value
		*/
		_generateBoundary() {
			return this.rootNode.boundaryPrefix + "-" + this.rootNode.baseBoundary + "-Part_" + this._nodeId;
		}
		/**
		* Encodes a header value for use in the generated rfc2822 email.
		*
		* @param {String} key Header key
		* @param {String} value Header value
		*/
		_encodeHeaderValue(key, value) {
			key = this._normalizeHeaderKey(key);
			switch (key) {
				case "From":
				case "Sender":
				case "To":
				case "Cc":
				case "Bcc":
				case "Reply-To": return this._convertAddresses(this._parseAddresses(value));
				case "Message-ID":
				case "In-Reply-To":
				case "Content-Id":
					value = (value || "").toString().replace(/\r?\n|\r/g, " ");
					if (value.charAt(0) !== "<") value = "<" + value;
					if (value.charAt(value.length - 1) !== ">") value = value + ">";
					return value;
				case "References":
					value = [].concat.apply([], [].concat(value || "").map((elm) => {
						elm = (elm || "").toString().replace(/\r?\n|\r/g, " ").trim();
						return elm.replace(/<[^>]*>/g, (str) => str.replace(/\s/g, "")).split(/\s+/);
					})).map((elm) => {
						if (elm.charAt(0) !== "<") elm = "<" + elm;
						if (elm.charAt(elm.length - 1) !== ">") elm = elm + ">";
						return elm;
					});
					return value.join(" ").trim();
				case "Date":
					if (Object.prototype.toString.call(value) === "[object Date]") return value.toUTCString().replace(/GMT/, "+0000");
					value = (value || "").toString().replace(/\r?\n|\r/g, " ");
					return this._encodeWords(value);
				case "Content-Type":
				case "Content-Disposition": return (value || "").toString().replace(/\r?\n|\r/g, " ");
				default:
					value = (value || "").toString().replace(/\r?\n|\r/g, " ");
					return this._encodeWords(value);
			}
		}
		/**
		* Rebuilds address object using punycode and other adjustments
		*
		* @param {Array} addresses An array of address objects
		* @param {Array} [uniqueList] An array to be populated with addresses
		* @return {String} address string
		*/
		_convertAddresses(addresses, uniqueList) {
			const values = [];
			uniqueList = uniqueList || [];
			[].concat(addresses || []).forEach((address) => {
				if (address.address) {
					address.address = this._normalizeAddress(address.address);
					if (!address.name) values.push(address.address.indexOf(" ") >= 0 ? `<${address.address}>` : `${address.address}`);
					else values.push(`${this._encodeAddressName(address.name)} <${address.address}>`);
					if (!uniqueList.some((a) => a.address === address.address)) uniqueList.push(address);
				} else if (address.group) {
					const groupListAddresses = (address.group.length ? this._convertAddresses(address.group, uniqueList) : "").trim();
					values.push(`${this._encodeAddressName(address.name)}:${groupListAddresses};`);
				}
			});
			return values.join(", ");
		}
		/**
		* Normalizes an email address
		*
		* @param {Array} address An array of address objects
		* @return {String} address string
		*/
		_normalizeAddress(address) {
			address = (address || "").toString().replace(/[\x00-\x1F<>]+/g, " ").trim();
			const lastAt = address.lastIndexOf("@");
			if (lastAt < 0) return address;
			let user = address.substr(0, lastAt);
			const domain = address.substr(lastAt + 1);
			let encodedDomain = domain;
			try {
				if (/[\x80-\uFFFF]/.test(user)) encodedDomain = punycode.toUnicode(domain.toLowerCase());
				else encodedDomain = punycode.toASCII(domain.toLowerCase());
			} catch (_err) {}
			if (user.indexOf(" ") >= 0) {
				if (user.charAt(0) !== "\"") user = "\"" + user;
				if (user.substr(-1) !== "\"") user = user + "\"";
			}
			return `${user}@${encodedDomain}`;
		}
		/**
		* If needed, mime encodes the name part
		*
		* @param {String} name Name part of an address
		* @returns {String} Mime word encoded string if needed
		*/
		_encodeAddressName(name) {
			if (!/^[\w ]*$/.test(name)) if (/^[\x20-\x7e]*$/.test(name)) return "\"" + name.replace(/([\\"])/g, "\\$1") + "\"";
			else return mimeFuncs.encodeWord(name, this._getTextEncoding(name), 52);
			return name;
		}
		/**
		* If needed, mime encodes the name part
		*
		* @param {String} name Name part of an address
		* @returns {String} Mime word encoded string if needed
		*/
		_encodeWords(value) {
			return mimeFuncs.encodeWords(value, this._getTextEncoding(value), 52, true);
		}
		/**
		* Detects best mime encoding for a text value
		*
		* @param {String} value Value to check for
		* @return {String} either 'Q' or 'B'
		*/
		_getTextEncoding(value) {
			value = (value || "").toString();
			if (this.textEncoding) return this.textEncoding;
			let nonLatinLen = 0;
			let latinLen = 0;
			for (let i = 0, len = value.length; i < len; i++) {
				const code = value.charCodeAt(i);
				if (code >= 0 && code <= 8 || code === 11 || code === 12 || code >= 14 && code <= 31 || code >= 128) nonLatinLen++;
				else if (code >= 65 && code <= 90 || code >= 97 && code <= 122) latinLen++;
			}
			return nonLatinLen < latinLen ? "Q" : "B";
		}
		/**
		* Generates a message id
		*
		* @return {String} Random Message-ID value
		*/
		_generateMessageId() {
			return "<" + [
				2,
				2,
				2,
				6
			].reduce((prev, len) => prev + "-" + crypto$8.randomBytes(len).toString("hex"), crypto$8.randomBytes(4).toString("hex")) + "@" + (this.getEnvelope().from || this.hostname || "localhost").split("@").pop() + ">";
		}
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/mail-composer/index.js
var require_mail_composer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var MimeNode = require_mime_node();
	var mimeFuncs = require_mime_funcs();
	var { parseDataURI } = require_shared();
	/**
	* Creates the object for composing a MimeNode instance out from the mail options
	*
	* @constructor
	* @param {Object} mail Mail options
	*/
	var MailComposer = class {
		constructor(mail) {
			this.mail = mail || {};
			this.message = false;
		}
		/**
		* Builds MimeNode instance
		*/
		compile() {
			this._alternatives = this.getAlternatives();
			this._htmlNode = this._alternatives.filter((alternative) => /^text\/html\b/i.test(alternative.contentType)).pop();
			this._attachments = this.getAttachments(!!this._htmlNode);
			this._useRelated = !!(this._htmlNode && this._attachments.related.length);
			this._useAlternative = this._alternatives.length > 1;
			this._useMixed = this._attachments.attached.length > 1 || this._alternatives.length && this._attachments.attached.length === 1;
			if (this.mail.raw) this.message = new MimeNode("message/rfc822", {
				newline: this.mail.newline,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess
			}).setRaw(this.mail.raw);
			else if (this._useMixed) this.message = this._createMixed();
			else if (this._useAlternative) this.message = this._createAlternative();
			else if (this._useRelated) this.message = this._createRelated();
			else this.message = this._createContentNode(false, [].concat(this._alternatives || []).concat(this._attachments.attached || []).shift() || {
				contentType: "text/plain",
				content: ""
			});
			if (this.mail.headers) this.message.addHeader(this.mail.headers);
			[
				"from",
				"sender",
				"to",
				"cc",
				"bcc",
				"reply-to",
				"in-reply-to",
				"references",
				"subject",
				"message-id",
				"date"
			].forEach((header) => {
				const key = header.replace(/-(\w)/g, (o, c) => c.toUpperCase());
				if (this.mail[key]) this.message.setHeader(header, this.mail[key]);
			});
			if (this.mail.envelope) this.message.setEnvelope(this.mail.envelope);
			this.message.messageId();
			return this.message;
		}
		/**
		* List all attachments. Resulting attachment objects can be used as input for MimeNode nodes
		*
		* @param {Boolean} findRelated If true separate related attachments from attached ones
		* @returns {Object} An object of arrays (`related` and `attached`)
		*/
		getAttachments(findRelated) {
			let eventObject;
			const attachments = [].concat(this.mail.attachments || []).map((attachment, i) => {
				if (/^data:/i.test(attachment.path || attachment.href)) attachment = this._processDataUrl(attachment);
				const contentType = attachment.contentType || mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || "bin");
				const isImage = /^image\//i.test(contentType);
				const isMessageNode = /^message\//i.test(contentType);
				const contentDisposition = attachment.contentDisposition || (isMessageNode || isImage && attachment.cid ? "inline" : "attachment");
				let contentTransferEncoding;
				if ("contentTransferEncoding" in attachment) contentTransferEncoding = attachment.contentTransferEncoding;
				else if (isMessageNode) contentTransferEncoding = "8bit";
				else contentTransferEncoding = "base64";
				const data = {
					contentType,
					contentDisposition,
					contentTransferEncoding
				};
				if (attachment.filename) data.filename = attachment.filename;
				else if (!isMessageNode && attachment.filename !== false) {
					data.filename = (attachment.path || attachment.href || "").split("/").pop().split("?").shift() || "attachment-" + (i + 1);
					if (data.filename.indexOf(".") < 0) data.filename += "." + mimeFuncs.detectExtension(data.contentType);
				}
				if (/^https?:\/\//i.test(attachment.path)) {
					attachment.href = attachment.path;
					attachment.path = void 0;
				}
				if (attachment.cid) data.cid = attachment.cid;
				if (attachment.raw) data.raw = attachment.raw;
				else if (attachment.path) data.content = { path: attachment.path };
				else if (attachment.href) data.content = {
					href: attachment.href,
					httpHeaders: attachment.httpHeaders,
					tls: attachment.tls
				};
				else data.content = attachment.content || "";
				if (attachment.encoding) data.encoding = attachment.encoding;
				if (attachment.headers) data.headers = attachment.headers;
				return data;
			});
			if (this.mail.icalEvent) {
				eventObject = Object.assign({}, this._getIcalEvent());
				eventObject.contentType = "application/ics";
				if (!eventObject.headers) eventObject.headers = {};
				eventObject.filename = eventObject.filename || "invite.ics";
				eventObject.headers["Content-Disposition"] = "attachment";
				eventObject.headers["Content-Transfer-Encoding"] = "base64";
			}
			if (!findRelated) return {
				attached: attachments.concat(eventObject || []),
				related: []
			};
			return {
				attached: attachments.filter((attachment) => !attachment.cid).concat(eventObject || []),
				related: attachments.filter((attachment) => !!attachment.cid)
			};
		}
		/**
		* Returns the icalEvent value with `path`/`href`/data uri input normalized into
		* a `content` entry, the same way as for regular attachments. The same event is
		* included twice (as a text/calendar alternative and as an application/ics
		* attachment), so the shared content object is marked to be resolved just once
		* and the buffered result is reused by the second node.
		*
		* @returns {Object} Normalized icalEvent data
		*/
		_getIcalEvent() {
			if (!this._icalEvent) {
				let icalEvent;
				if (typeof this.mail.icalEvent === "object" && (this.mail.icalEvent.content || this.mail.icalEvent.path || this.mail.icalEvent.href || this.mail.icalEvent.raw)) icalEvent = Object.assign({}, this.mail.icalEvent);
				else icalEvent = { content: this.mail.icalEvent };
				if (/^data:/i.test(icalEvent.path || icalEvent.href)) icalEvent = this._processDataUrl(icalEvent);
				if (/^https?:\/\//i.test(icalEvent.path)) {
					icalEvent.href = icalEvent.path;
					icalEvent.path = void 0;
				}
				if (!icalEvent.raw) {
					if (icalEvent.path) {
						icalEvent.content = { path: icalEvent.path };
						icalEvent.path = void 0;
					} else if (icalEvent.href) {
						icalEvent.content = {
							href: icalEvent.href,
							httpHeaders: icalEvent.httpHeaders
						};
						icalEvent.href = void 0;
					}
				}
				if (icalEvent.content && typeof icalEvent.content === "object") icalEvent.content._resolve = true;
				this._icalEvent = icalEvent;
			}
			return this._icalEvent;
		}
		/**
		* List alternatives. Resulting objects can be used as input for MimeNode nodes
		*
		* @returns {Array} An array of alternative elements. Includes the `text` and `html` values as well
		*/
		getAlternatives() {
			const alternatives = [];
			let text, html, watchHtml, amp, eventObject;
			if (this.mail.text) {
				if (typeof this.mail.text === "object" && (this.mail.text.content || this.mail.text.path || this.mail.text.href || this.mail.text.raw)) text = this.mail.text;
				else text = { content: this.mail.text };
				text.contentType = "text/plain; charset=utf-8";
			}
			if (this.mail.watchHtml) {
				if (typeof this.mail.watchHtml === "object" && (this.mail.watchHtml.content || this.mail.watchHtml.path || this.mail.watchHtml.href || this.mail.watchHtml.raw)) watchHtml = this.mail.watchHtml;
				else watchHtml = { content: this.mail.watchHtml };
				watchHtml.contentType = "text/watch-html; charset=utf-8";
			}
			if (this.mail.amp) {
				if (typeof this.mail.amp === "object" && (this.mail.amp.content || this.mail.amp.path || this.mail.amp.href || this.mail.amp.raw)) amp = this.mail.amp;
				else amp = { content: this.mail.amp };
				amp.contentType = "text/x-amp-html; charset=utf-8";
			}
			if (this.mail.icalEvent) {
				eventObject = Object.assign({}, this._getIcalEvent());
				eventObject.filename = false;
				eventObject.contentType = "text/calendar; charset=utf-8; method=" + (eventObject.method || "PUBLISH").toString().trim().toUpperCase();
				if (!eventObject.headers) eventObject.headers = {};
			}
			if (this.mail.html) {
				if (typeof this.mail.html === "object" && (this.mail.html.content || this.mail.html.path || this.mail.html.href || this.mail.html.raw)) html = this.mail.html;
				else html = { content: this.mail.html };
				html.contentType = "text/html; charset=utf-8";
			}
			[].concat(text || []).concat(watchHtml || []).concat(amp || []).concat(html || []).concat(eventObject || []).concat(this.mail.alternatives || []).forEach((alternative) => {
				if (/^data:/i.test(alternative.path || alternative.href)) alternative = this._processDataUrl(alternative);
				const data = {
					contentType: alternative.contentType || mimeFuncs.detectMimeType(alternative.filename || alternative.path || alternative.href || "txt"),
					contentTransferEncoding: alternative.contentTransferEncoding
				};
				if (alternative.filename) data.filename = alternative.filename;
				if (/^https?:\/\//i.test(alternative.path)) {
					alternative.href = alternative.path;
					alternative.path = void 0;
				}
				if (alternative.raw) data.raw = alternative.raw;
				else if (alternative.path) data.content = { path: alternative.path };
				else if (alternative.href) data.content = { href: alternative.href };
				else data.content = alternative.content || "";
				if (alternative.encoding) data.encoding = alternative.encoding;
				if (alternative.headers) data.headers = alternative.headers;
				alternatives.push(data);
			});
			return alternatives;
		}
		/**
		* Builds multipart/mixed node. It should always contain different type of elements on the same level
		* eg. text + attachments
		*
		* @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
		* @returns {Object} MimeNode node element
		*/
		_createMixed(parentNode) {
			const node = parentNode ? parentNode.createChild("multipart/mixed", {
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			}) : new MimeNode("multipart/mixed", {
				baseBoundary: this.mail.baseBoundary,
				textEncoding: this.mail.textEncoding,
				boundaryPrefix: this.mail.boundaryPrefix,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			});
			if (this._useAlternative) this._createAlternative(node);
			else if (this._useRelated) this._createRelated(node);
			[].concat(!this._useAlternative && this._alternatives || []).concat(this._attachments.attached || []).forEach((element) => {
				if (!this._useRelated || element !== this._htmlNode) this._createContentNode(node, element);
			});
			return node;
		}
		/**
		* Builds multipart/alternative node. It should always contain same type of elements on the same level
		* eg. text + html view of the same data
		*
		* @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
		* @returns {Object} MimeNode node element
		*/
		_createAlternative(parentNode) {
			const node = parentNode ? parentNode.createChild("multipart/alternative", {
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			}) : new MimeNode("multipart/alternative", {
				baseBoundary: this.mail.baseBoundary,
				textEncoding: this.mail.textEncoding,
				boundaryPrefix: this.mail.boundaryPrefix,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			});
			this._alternatives.forEach((alternative) => {
				if (this._useRelated && this._htmlNode === alternative) this._createRelated(node);
				else this._createContentNode(node, alternative);
			});
			return node;
		}
		/**
		* Builds multipart/related node. It should always contain html node with related attachments
		*
		* @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
		* @returns {Object} MimeNode node element
		*/
		_createRelated(parentNode) {
			const node = parentNode ? parentNode.createChild("multipart/related; type=\"text/html\"", {
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			}) : new MimeNode("multipart/related; type=\"text/html\"", {
				baseBoundary: this.mail.baseBoundary,
				textEncoding: this.mail.textEncoding,
				boundaryPrefix: this.mail.boundaryPrefix,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			});
			this._createContentNode(node, this._htmlNode);
			this._attachments.related.forEach((alternative) => this._createContentNode(node, alternative));
			return node;
		}
		/**
		* Creates a regular node with contents
		*
		* @param {Object} parentNode Parent for this note. If it does not exist, a root node is created
		* @param {Object} element Node data
		* @returns {Object} MimeNode node element
		*/
		_createContentNode(parentNode, element) {
			element = element || {};
			element.content = element.content || "";
			const encoding = (element.encoding || "utf8").toString().toLowerCase().replace(/[-_\s]/g, "");
			const node = parentNode ? parentNode.createChild(element.contentType, {
				filename: element.filename,
				textEncoding: this.mail.textEncoding,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			}) : new MimeNode(element.contentType, {
				filename: element.filename,
				baseBoundary: this.mail.baseBoundary,
				textEncoding: this.mail.textEncoding,
				boundaryPrefix: this.mail.boundaryPrefix,
				disableUrlAccess: this.mail.disableUrlAccess,
				disableFileAccess: this.mail.disableFileAccess,
				normalizeHeaderKey: this.mail.normalizeHeaderKey,
				newline: this.mail.newline
			});
			if (element.headers) node.addHeader(element.headers);
			if (element.cid) node.setHeader("Content-Id", "<" + element.cid.replace(/[<>]/g, "") + ">");
			if (element.contentTransferEncoding) node.setHeader("Content-Transfer-Encoding", element.contentTransferEncoding);
			else if (this.mail.encoding && /^text\//i.test(element.contentType)) node.setHeader("Content-Transfer-Encoding", this.mail.encoding);
			if (!/^text\//i.test(element.contentType) || element.contentDisposition) node.setHeader("Content-Disposition", element.contentDisposition || (element.cid && /^image\//i.test(element.contentType) ? "inline" : "attachment"));
			if (typeof element.content === "string" && ![
				"utf8",
				"usascii",
				"ascii"
			].includes(encoding)) element.content = Buffer.from(element.content, encoding);
			if (element.raw) node.setRaw(element.raw);
			else node.setContent(element.content);
			return node;
		}
		/**
		* Parses data uri and converts it to a Buffer
		*
		* @param {Object} element Content element
		* @return {Object} Parsed element
		*/
		_processDataUrl(element) {
			const dataUrl = element.path || element.href;
			if (!dataUrl || typeof dataUrl !== "string") return element;
			if (!dataUrl.startsWith("data:")) return element;
			if (dataUrl.length > 52428800) {
				let detectedType = "application/octet-stream";
				const commaPos = dataUrl.indexOf(",");
				if (commaPos > 0 && commaPos < 200) {
					const parts = dataUrl.substring(5, commaPos).split(";");
					if (parts[0] && parts[0].includes("/")) detectedType = parts[0].trim();
				}
				return Object.assign({}, element, {
					path: false,
					href: false,
					content: Buffer.alloc(0),
					contentType: element.contentType || detectedType
				});
			}
			let parsedDataUri;
			try {
				parsedDataUri = parseDataURI(dataUrl);
			} catch (_err) {
				return element;
			}
			if (!parsedDataUri) return element;
			element.content = parsedDataUri.data;
			element.contentType = element.contentType || parsedDataUri.contentType;
			if ("path" in element) element.path = false;
			if ("href" in element) element.href = false;
			return element;
		}
	};
	module.exports = MailComposer;
}));
//#endregion
//#region node_modules/nodemailer/lib/dkim/message-parser.js
var require_message_parser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$2 } = __require("stream");
	/**
	* MessageParser instance is a transform stream that separates message headers
	* from the rest of the body. Headers are emitted with the 'headers' event. Message
	* body is passed on as the resulting stream.
	*/
	var MessageParser = class extends Transform$2 {
		constructor(options) {
			super(options);
			this.lastBytes = Buffer.alloc(4);
			this.headersParsed = false;
			this.headerBytes = 0;
			this.headerChunks = [];
			this.rawHeaders = false;
			this.bodySize = 0;
		}
		/**
		* Keeps count of the last 4 bytes in order to detect line breaks on chunk boundaries
		*
		* @param {Buffer} data Next data chunk from the stream
		*/
		updateLastBytes(data) {
			const lblen = this.lastBytes.length;
			const nblen = Math.min(data.length, lblen);
			for (let i = 0, len = lblen - nblen; i < len; i++) this.lastBytes[i] = this.lastBytes[i + nblen];
			for (let i = 1; i <= nblen; i++) this.lastBytes[lblen - i] = data[data.length - i];
		}
		/**
		* Finds and removes message headers from the remaining body. We want to keep
		* headers separated until final delivery to be able to modify these
		*
		* @param {Buffer} data Next chunk of data
		* @return {Boolean} Returns true if headers are already found or false otherwise
		*/
		checkHeaders(data) {
			if (this.headersParsed) return true;
			const lblen = this.lastBytes.length;
			let headerPos = 0;
			for (let i = 0, len = this.lastBytes.length + data.length; i < len; i++) {
				let chr;
				if (i < lblen) chr = this.lastBytes[i];
				else chr = data[i - lblen];
				if (chr === 10 && i) {
					const pr1 = i - 1 < lblen ? this.lastBytes[i - 1] : data[i - 1 - lblen];
					const pr2 = i > 1 ? i - 2 < lblen ? this.lastBytes[i - 2] : data[i - 2 - lblen] : false;
					if (pr1 === 10) {
						this.headersParsed = true;
						headerPos = i - lblen + 1;
						this.headerBytes += headerPos;
						break;
					} else if (pr1 === 13 && pr2 === 10) {
						this.headersParsed = true;
						headerPos = i - lblen + 1;
						this.headerBytes += headerPos;
						break;
					}
				}
			}
			if (this.headersParsed) {
				this.headerChunks.push(data.slice(0, headerPos));
				this.rawHeaders = Buffer.concat(this.headerChunks, this.headerBytes);
				this.headerChunks = null;
				this.emit("headers", this.parseHeaders());
				if (data.length - 1 > headerPos) {
					const chunk = data.slice(headerPos);
					this.bodySize += chunk.length;
					setImmediate(() => this.push(chunk));
				}
				return false;
			}
			this.headerBytes += data.length;
			this.headerChunks.push(data);
			this.updateLastBytes(data);
			return false;
		}
		_transform(chunk, encoding, callback) {
			if (!chunk || !chunk.length) return callback();
			if (typeof chunk === "string") chunk = Buffer.from(chunk, encoding);
			let headersFound;
			try {
				headersFound = this.checkHeaders(chunk);
			} catch (E) {
				return callback(E);
			}
			if (headersFound) {
				this.bodySize += chunk.length;
				this.push(chunk);
			}
			setImmediate(callback);
		}
		_flush(callback) {
			if (this.headerChunks) {
				const chunk = Buffer.concat(this.headerChunks, this.headerBytes);
				this.bodySize += chunk.length;
				this.push(chunk);
				this.headerChunks = null;
			}
			callback();
		}
		parseHeaders() {
			const lines = (this.rawHeaders || "").toString().split(/\r?\n/);
			for (let i = lines.length - 1; i > 0; i--) if (/^\s/.test(lines[i])) {
				lines[i - 1] += "\n" + lines[i];
				lines.splice(i, 1);
			}
			return lines.filter((line) => line.trim()).map((line) => ({
				key: line.substr(0, line.indexOf(":")).trim().toLowerCase(),
				line
			}));
		}
	};
	module.exports = MessageParser;
}));
//#endregion
//#region node_modules/nodemailer/lib/dkim/relaxed-body.js
var require_relaxed_body = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform: Transform$1 } = __require("stream");
	var crypto$7 = __require("crypto");
	var RelaxedBody = class extends Transform$1 {
		constructor(options) {
			super();
			options = options || {};
			this.chunkBuffer = [];
			this.chunkBufferLen = 0;
			this.bodyHash = crypto$7.createHash(options.hashAlgo || "sha256");
			this.remainder = "";
			this.byteLength = 0;
			this.debug = options.debug;
			this._debugBody = options.debug ? [] : false;
		}
		updateHash(chunk) {
			let bodyStr;
			let nextRemainder = "";
			let state = "file";
			for (let i = chunk.length - 1; i >= 0; i--) {
				const c = chunk[i];
				if (state === "file" && (c === 10 || c === 13)) {} else if (state === "file" && (c === 9 || c === 32)) state = "line";
				else if (state === "line" && (c === 9 || c === 32)) {} else if (state === "file" || state === "line") {
					state = "body";
					if (i === chunk.length - 1) break;
				}
				if (i === 0) {
					if (state === "file" && (!this.remainder || /[\r\n]$/.test(this.remainder)) || state === "line" && (!this.remainder || /[ \t]$/.test(this.remainder))) {
						this.remainder += chunk.toString("binary");
						return;
					} else if (state === "line" || state === "file") {
						nextRemainder = chunk.toString("binary");
						chunk = false;
						break;
					}
				}
				if (state !== "body") continue;
				nextRemainder = chunk.slice(i + 1).toString("binary");
				chunk = chunk.slice(0, i + 1);
				break;
			}
			let needsFixing = !!this.remainder;
			if (chunk && !needsFixing) {
				for (let i = 0, len = chunk.length; i < len; i++) if (i && chunk[i] === 10 && chunk[i - 1] !== 13) {
					needsFixing = true;
					break;
				} else if (i && chunk[i] === 13 && chunk[i - 1] === 32) {
					needsFixing = true;
					break;
				} else if (i && chunk[i] === 32 && chunk[i - 1] === 32) {
					needsFixing = true;
					break;
				} else if (chunk[i] === 9) {
					needsFixing = true;
					break;
				}
			}
			if (needsFixing) {
				bodyStr = this.remainder + (chunk ? chunk.toString("binary") : "");
				this.remainder = nextRemainder;
				bodyStr = bodyStr.replace(/\r?\n/g, "\n").replace(/[ \t]*$/gm, "").replace(/[ \t]+/gm, " ").replace(/\n/g, "\r\n");
				chunk = Buffer.from(bodyStr, "binary");
			} else if (nextRemainder) this.remainder = nextRemainder;
			if (this.debug) this._debugBody.push(chunk);
			this.bodyHash.update(chunk);
		}
		_transform(chunk, encoding, callback) {
			if (!chunk || !chunk.length) return callback();
			if (typeof chunk === "string") chunk = Buffer.from(chunk, encoding);
			this.updateHash(chunk);
			this.byteLength += chunk.length;
			this.push(chunk);
			callback();
		}
		_flush(callback) {
			if (/[\r\n]$/.test(this.remainder) && this.byteLength > 2) this.bodyHash.update(Buffer.from("\r\n"));
			if (!this.byteLength) this.push(Buffer.from("\r\n"));
			this.emit("hash", this.bodyHash.digest("base64"), this.debug ? Buffer.concat(this._debugBody) : false);
			callback();
		}
	};
	module.exports = RelaxedBody;
}));
//#endregion
//#region node_modules/nodemailer/lib/dkim/sign.js
var require_sign = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var punycode = require_punycode();
	var mimeFuncs = require_mime_funcs();
	var crypto$6 = __require("crypto");
	/**
	* Returns DKIM signature header line
	*
	* @param {Object} headers Parsed headers object from MessageParser
	* @param {String} bodyHash Base64 encoded hash of the message
	* @param {Object} options DKIM options
	* @param {String} options.domainName Domain name to be signed for
	* @param {String} options.keySelector DKIM key selector to use
	* @param {String} options.privateKey DKIM private key to use
	* @return {String} Complete header line
	*/
	module.exports = (headers, hashAlgo, bodyHash, options) => {
		options = options || {};
		const canonicalizedHeaderData = relaxedHeaders(headers, options.headerFieldNames || "From:Sender:Reply-To:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive", options.skipFields);
		const dkimHeader = generateDKIMHeader(options.domainName, options.keySelector, canonicalizedHeaderData.fieldNames, hashAlgo, bodyHash);
		canonicalizedHeaderData.headers += "dkim-signature:" + relaxedHeaderLine(dkimHeader);
		const signer = crypto$6.createSign(("rsa-" + hashAlgo).toUpperCase());
		signer.update(canonicalizedHeaderData.headers);
		let signature;
		try {
			signature = signer.sign(options.privateKey, "base64");
		} catch (_E) {
			return false;
		}
		return dkimHeader + signature.replace(/(^.{73}|.{75}(?!\r?\n|\r))/g, "$&\r\n ").trim();
	};
	module.exports.relaxedHeaders = relaxedHeaders;
	function generateDKIMHeader(domainName, keySelector, fieldNames, hashAlgo, bodyHash) {
		const dkim = [
			"v=1",
			"a=rsa-" + hashAlgo,
			"c=relaxed/relaxed",
			"d=" + punycode.toASCII(domainName),
			"q=dns/txt",
			"s=" + keySelector,
			"bh=" + bodyHash,
			"h=" + fieldNames
		].join("; ");
		return mimeFuncs.foldLines("DKIM-Signature: " + dkim, 76) + ";\r\n b=";
	}
	function relaxedHeaders(headers, fieldNames, skipFields) {
		const includedFields = /* @__PURE__ */ new Set();
		const skip = /* @__PURE__ */ new Set();
		const headerFields = /* @__PURE__ */ new Map();
		(skipFields || "").toLowerCase().split(":").forEach((field) => {
			skip.add(field.trim());
		});
		(fieldNames || "").toLowerCase().split(":").filter((field) => !skip.has(field.trim())).forEach((field) => {
			includedFields.add(field.trim());
		});
		for (let i = headers.length - 1; i >= 0; i--) {
			const line = headers[i];
			if (includedFields.has(line.key) && !headerFields.has(line.key)) headerFields.set(line.key, relaxedHeaderLine(line.line));
		}
		const headersList = [];
		const fields = [];
		includedFields.forEach((field) => {
			if (headerFields.has(field)) {
				fields.push(field);
				headersList.push(field + ":" + headerFields.get(field));
			}
		});
		return {
			headers: headersList.join("\r\n") + "\r\n",
			fieldNames: fields.join(":")
		};
	}
	function relaxedHeaderLine(line) {
		return line.substr(line.indexOf(":") + 1).replace(/\r?\n/g, "").replace(/\s+/g, " ").trim();
	}
}));
//#endregion
//#region node_modules/nodemailer/lib/dkim/index.js
var require_dkim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var MessageParser = require_message_parser();
	var RelaxedBody = require_relaxed_body();
	var sign = require_sign();
	var { PassThrough: PassThrough$1 } = __require("stream");
	var fs$3 = __require("fs");
	var path$2 = __require("path");
	var crypto$5 = __require("crypto");
	var DKIM_ALGO = "sha256";
	var MAX_MESSAGE_SIZE = 2097152;
	var DKIMSigner = class {
		constructor(options, keys, input, output) {
			this.options = options || {};
			this.keys = keys;
			this.cacheTreshold = Number(this.options.cacheTreshold) || MAX_MESSAGE_SIZE;
			this.hashAlgo = this.options.hashAlgo || DKIM_ALGO;
			this.cacheDir = this.options.cacheDir || false;
			this.chunks = [];
			this.chunklen = 0;
			this.readPos = 0;
			this.cachePath = this.cacheDir ? path$2.join(this.cacheDir, "message." + Date.now() + "-" + crypto$5.randomBytes(14).toString("hex")) : false;
			this.cache = false;
			this.headers = false;
			this.bodyHash = false;
			this.parser = false;
			this.relaxedBody = false;
			this.input = input;
			this.output = output;
			this.output.usingCache = false;
			this.hasErrored = false;
			this.input.on("error", (err) => {
				this.hasErrored = true;
				this.cleanup();
				output.emit("error", err);
			});
		}
		cleanup() {
			if (!this.cache || !this.cachePath) return;
			fs$3.unlink(this.cachePath, () => false);
		}
		createReadCache() {
			this.cache = fs$3.createReadStream(this.cachePath);
			this.cache.once("error", (err) => {
				this.cleanup();
				this.output.emit("error", err);
			});
			this.cache.once("close", () => {
				this.cleanup();
			});
			this.cache.pipe(this.output);
		}
		sendNextChunk() {
			if (this.hasErrored) return;
			if (this.readPos >= this.chunks.length) {
				if (!this.cache) return this.output.end();
				return this.createReadCache();
			}
			const chunk = this.chunks[this.readPos++];
			if (this.output.write(chunk) === false) return this.output.once("drain", () => {
				this.sendNextChunk();
			});
			setImmediate(() => this.sendNextChunk());
		}
		sendSignedOutput() {
			let keyPos = 0;
			const signNextKey = () => {
				if (keyPos >= this.keys.length) {
					this.output.write(this.parser.rawHeaders);
					return setImmediate(() => this.sendNextChunk());
				}
				const key = this.keys[keyPos++];
				const dkimField = sign(this.headers, this.hashAlgo, this.bodyHash, {
					domainName: key.domainName,
					keySelector: key.keySelector,
					privateKey: key.privateKey,
					headerFieldNames: this.options.headerFieldNames,
					skipFields: this.options.skipFields
				});
				if (dkimField) this.output.write(Buffer.from(dkimField + "\r\n"));
				return setImmediate(signNextKey);
			};
			if (this.bodyHash && this.headers) return signNextKey();
			this.output.write(this.parser.rawHeaders);
			this.sendNextChunk();
		}
		createWriteCache() {
			this.output.usingCache = true;
			this.cache = fs$3.createWriteStream(this.cachePath);
			this.cache.once("error", (err) => {
				this.cleanup();
				this.relaxedBody.unpipe(this.cache);
				this.relaxedBody.on("readable", () => {
					while (this.relaxedBody.read() !== null);
				});
				this.hasErrored = true;
				this.output.emit("error", err);
			});
			this.cache.once("close", () => {
				this.sendSignedOutput();
			});
			this.relaxedBody.removeAllListeners("readable");
			this.relaxedBody.pipe(this.cache);
		}
		signStream() {
			this.parser = new MessageParser();
			this.relaxedBody = new RelaxedBody({ hashAlgo: this.hashAlgo });
			this.parser.on("headers", (value) => {
				this.headers = value;
			});
			this.relaxedBody.on("hash", (value) => {
				this.bodyHash = value;
			});
			this.relaxedBody.on("readable", () => {
				let chunk;
				if (this.cache) return;
				while ((chunk = this.relaxedBody.read()) !== null) {
					this.chunks.push(chunk);
					this.chunklen += chunk.length;
					if (this.chunklen >= this.cacheTreshold && this.cachePath) return this.createWriteCache();
				}
			});
			this.relaxedBody.on("end", () => {
				if (this.cache) return;
				this.sendSignedOutput();
			});
			this.parser.pipe(this.relaxedBody);
			setImmediate(() => this.input.pipe(this.parser));
		}
	};
	var DKIM = class {
		constructor(options) {
			this.options = options || {};
			this.keys = [].concat(this.options.keys || {
				domainName: options.domainName,
				keySelector: options.keySelector,
				privateKey: options.privateKey
			});
		}
		sign(input, extraOptions) {
			const output = new PassThrough$1();
			let inputStream = input;
			let writeValue = false;
			if (Buffer.isBuffer(input)) {
				writeValue = input;
				inputStream = new PassThrough$1();
			} else if (typeof input === "string") {
				writeValue = Buffer.from(input);
				inputStream = new PassThrough$1();
			}
			let options = this.options;
			if (extraOptions && Object.keys(extraOptions).length) options = Object.assign({}, extraOptions, this.options);
			const signer = new DKIMSigner(options, this.keys, inputStream, output);
			setImmediate(() => {
				signer.signStream();
				if (writeValue) setImmediate(() => {
					inputStream.end(writeValue);
				});
			});
			return output;
		}
	};
	module.exports = DKIM;
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-connection/http-proxy-client.js
var require_http_proxy_client = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/**
	* Minimal HTTP/S proxy client
	*/
	var net$3 = __require("net");
	var tls$1 = __require("tls");
	var urllib = require_url();
	var errors = require_errors();
	var MAX_RESPONSE_HEADER_BYTES = 65536;
	/**
	* Establishes proxied connection to destinationPort
	*
	* httpProxyClient("http://localhost:3128/", 80, "google.com", function(err, socket){
	*     socket.write("GET / HTTP/1.0\r\n\r\n");
	* });
	*
	* @param {String} proxyUrl proxy configuration, etg "http://proxy.host:3128/"
	* @param {Number} destinationPort Port to open in destination host
	* @param {String} destinationHost Destination hostname
	* @param {Object} [tlsOptions] Optional TLS options for an HTTPS proxy (e.g. { rejectUnauthorized: false })
	* @param {Function} callback Callback to run with the rocket object once connection is established
	*/
	function httpProxyClient(proxyUrl, destinationPort, destinationHost, tlsOptions, callback) {
		if (typeof tlsOptions === "function") {
			callback = tlsOptions;
			tlsOptions = {};
		}
		tlsOptions = tlsOptions || {};
		destinationPort = Number(destinationPort) || 0;
		if (!destinationPort || /[\r\n]/.test(destinationHost)) {
			const err = /* @__PURE__ */ new Error("Invalid proxy destination");
			err.code = errors.EPROXY;
			return setImmediate(() => callback(err));
		}
		const proxy = urllib.parse(proxyUrl);
		const connectOptions = {
			host: proxy.hostname,
			port: Number(proxy.port) ? Number(proxy.port) : proxy.protocol === "https:" ? 443 : 80
		};
		let connect;
		if (proxy.protocol === "https:") {
			connectOptions.rejectUnauthorized = tlsOptions.rejectUnauthorized !== false;
			connect = tls$1.connect.bind(tls$1);
		} else connect = net$3.connect.bind(net$3);
		let socket;
		let finished = false;
		const tempSocketErr = (err) => {
			if (finished) return;
			finished = true;
			try {
				socket.destroy();
			} catch (_E) {}
			callback(err);
		};
		const timeoutErr = () => {
			const err = /* @__PURE__ */ new Error("Proxy socket timed out");
			err.code = "ETIMEDOUT";
			tempSocketErr(err);
		};
		socket = connect(connectOptions, () => {
			if (finished) return;
			const reqHeaders = {
				Host: destinationHost + ":" + destinationPort,
				Connection: "close"
			};
			if (proxy.auth) reqHeaders["Proxy-Authorization"] = "Basic " + Buffer.from(proxy.auth).toString("base64");
			socket.write("CONNECT " + destinationHost + ":" + destinationPort + " HTTP/1.1\r\n" + Object.keys(reqHeaders).map((key) => key + ": " + reqHeaders[key]).join("\r\n") + "\r\n\r\n");
			let headers = "";
			const onSocketData = (chunk) => {
				let match;
				let remainder;
				if (finished) return;
				headers += chunk.toString("binary");
				if (match = headers.match(/\r\n\r\n/)) {
					socket.removeListener("data", onSocketData);
					remainder = headers.substr(match.index + match[0].length);
					headers = headers.substr(0, match.index);
					if (remainder) socket.unshift(Buffer.from(remainder, "binary"));
					finished = true;
					match = headers.match(/^HTTP\/\d+\.\d+ (\d+)/i);
					if (!match || (match[1] || "").charAt(0) !== "2") {
						try {
							socket.destroy();
						} catch (_E) {}
						const err = /* @__PURE__ */ new Error("Invalid response from proxy" + (match && ": " + match[1] || ""));
						err.code = errors.EPROXY;
						return callback(err);
					}
					socket.removeListener("error", tempSocketErr);
					socket.removeListener("timeout", timeoutErr);
					socket.setTimeout(0);
					return callback(null, socket);
				}
				if (headers.length > MAX_RESPONSE_HEADER_BYTES) {
					socket.removeListener("data", onSocketData);
					const err = /* @__PURE__ */ new Error("Proxy response headers too large");
					err.code = errors.EPROXY;
					return tempSocketErr(err);
				}
			};
			socket.on("data", onSocketData);
		});
		socket.setTimeout(httpProxyClient.timeout || 3e4);
		socket.on("timeout", timeoutErr);
		socket.once("error", tempSocketErr);
	}
	module.exports = httpProxyClient;
}));
//#endregion
//#region node_modules/nodemailer/lib/mailer/mail-message.js
var require_mail_message = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var shared = require_shared();
	var MimeNode = require_mime_node();
	var mimeFuncs = require_mime_funcs();
	var MailMessage = class {
		constructor(mailer, data) {
			this.mailer = mailer;
			this.data = {};
			this.message = null;
			data = data || {};
			const options = mailer.options || {};
			const defaults = mailer._defaults || {};
			Object.assign(this.data, data);
			this.data.headers = this.data.headers || {};
			Object.keys(defaults).forEach((key) => {
				if (!(key in this.data)) this.data[key] = defaults[key];
				else if (key === "headers") Object.keys(defaults.headers).forEach((key) => {
					if (!(key in this.data.headers)) this.data.headers[key] = defaults.headers[key];
				});
			});
			[
				"disableFileAccess",
				"disableUrlAccess",
				"normalizeHeaderKey"
			].forEach((key) => {
				if (key in options) this.data[key] = options[key];
			});
		}
		resolveContent(...args) {
			return shared.resolveContent(...args);
		}
		resolveAll(callback) {
			const keys = [
				[this.data, "html"],
				[this.data, "text"],
				[this.data, "watchHtml"],
				[this.data, "amp"],
				[this.data, "icalEvent"]
			];
			if (this.data.alternatives && this.data.alternatives.length) this.data.alternatives.forEach((alternative, i) => {
				keys.push([this.data.alternatives, i]);
			});
			if (this.data.attachments && this.data.attachments.length) this.data.attachments.forEach((attachment, i) => {
				if (!attachment.filename) {
					attachment.filename = (attachment.path || attachment.href || "").split("/").pop().split("?").shift() || "attachment-" + (i + 1);
					if (attachment.filename.indexOf(".") < 0) attachment.filename += "." + mimeFuncs.detectExtension(attachment.contentType);
				}
				if (!attachment.contentType) attachment.contentType = mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || "bin");
				keys.push([this.data.attachments, i]);
			});
			const mimeNode = new MimeNode();
			[
				"from",
				"to",
				"cc",
				"bcc",
				"sender",
				"replyTo"
			].forEach((address) => {
				let value;
				if (this.message) value = [].concat(mimeNode._parseAddresses(this.message.getHeader(address === "replyTo" ? "reply-to" : address)) || []);
				else if (this.data[address]) value = [].concat(mimeNode._parseAddresses(this.data[address]) || []);
				if (value && value.length) this.data[address] = value;
				else if (address in this.data) this.data[address] = null;
			});
			["from", "sender"].forEach((address) => {
				if (this.data[address]) this.data[address] = this.data[address].shift();
			});
			let pos = 0;
			const resolveNext = () => {
				if (pos >= keys.length) return callback(null, this.data);
				const args = keys[pos++];
				if (!args[0] || !args[0][args[1]]) return resolveNext();
				shared.resolveContent(...args, {
					disableFileAccess: this.data.disableFileAccess,
					disableUrlAccess: this.data.disableUrlAccess
				}, (err, value) => {
					if (err) return callback(err);
					const node = { content: value };
					if (args[0][args[1]] && typeof args[0][args[1]] === "object" && !Buffer.isBuffer(args[0][args[1]])) Object.keys(args[0][args[1]]).forEach((key) => {
						if (!(key in node) && ![
							"content",
							"path",
							"href",
							"raw"
						].includes(key)) node[key] = args[0][args[1]][key];
					});
					args[0][args[1]] = node;
					resolveNext();
				});
			};
			setImmediate(() => resolveNext());
		}
		normalize(callback) {
			const envelope = this.data.envelope || this.message.getEnvelope();
			const messageId = this.message.messageId();
			this.resolveAll((err, data) => {
				if (err) return callback(err);
				data.envelope = envelope;
				data.messageId = messageId;
				[
					"html",
					"text",
					"watchHtml",
					"amp"
				].forEach((key) => {
					if (data[key] && data[key].content) {
						if (typeof data[key].content === "string") data[key] = data[key].content;
						else if (Buffer.isBuffer(data[key].content)) data[key] = data[key].content.toString();
					}
				});
				if (data.icalEvent && Buffer.isBuffer(data.icalEvent.content)) {
					data.icalEvent.content = data.icalEvent.content.toString("base64");
					data.icalEvent.encoding = "base64";
				}
				if (data.alternatives && data.alternatives.length) data.alternatives.forEach((alternative) => {
					if (alternative && alternative.content && Buffer.isBuffer(alternative.content)) {
						alternative.content = alternative.content.toString("base64");
						alternative.encoding = "base64";
					}
				});
				if (data.attachments && data.attachments.length) data.attachments.forEach((attachment) => {
					if (attachment && attachment.content && Buffer.isBuffer(attachment.content)) {
						attachment.content = attachment.content.toString("base64");
						attachment.encoding = "base64";
					}
				});
				data.normalizedHeaders = {};
				Object.keys(data.headers || {}).forEach((key) => {
					let value = [].concat(data.headers[key] || []).shift();
					value = value && value.value || value;
					if (value) {
						if ([
							"references",
							"in-reply-to",
							"message-id",
							"content-id"
						].includes(key)) value = this.message._encodeHeaderValue(key, value);
						data.normalizedHeaders[key] = value;
					}
				});
				if (data.list && typeof data.list === "object") this._getListHeaders(data.list).forEach((entry) => {
					data.normalizedHeaders[entry.key] = entry.value.map((val) => val && val.value || val).join(", ");
				});
				if (data.references) data.normalizedHeaders.references = this.message._encodeHeaderValue("references", data.references);
				if (data.inReplyTo) data.normalizedHeaders["in-reply-to"] = this.message._encodeHeaderValue("in-reply-to", data.inReplyTo);
				return callback(null, data);
			});
		}
		setMailerHeader() {
			if (!this.message || !this.data.xMailer) return;
			this.message.setHeader("X-Mailer", this.data.xMailer);
		}
		setPriorityHeaders() {
			if (!this.message || !this.data.priority) return;
			switch ((this.data.priority || "").toString().toLowerCase()) {
				case "high":
					this.message.setHeader("X-Priority", "1 (Highest)");
					this.message.setHeader("X-MSMail-Priority", "High");
					this.message.setHeader("Importance", "High");
					break;
				case "low":
					this.message.setHeader("X-Priority", "5 (Lowest)");
					this.message.setHeader("X-MSMail-Priority", "Low");
					this.message.setHeader("Importance", "Low");
			}
		}
		setListHeaders() {
			if (!this.message || !this.data.list || typeof this.data.list !== "object") return;
			this._getListHeaders(this.data.list).forEach((listHeader) => {
				listHeader.value.forEach((value) => {
					this.message.addHeader(listHeader.key, value);
				});
			});
		}
		_getListHeaders(listData) {
			return Object.keys(listData).map((key) => ({
				key: "list-" + key.toLowerCase().trim(),
				value: [].concat(listData[key] || []).map((value) => ({
					prepared: true,
					foldLines: true,
					value: [].concat(value || []).map((value) => {
						if (typeof value === "string") value = { url: value };
						if (value && value.url) {
							if (key.toLowerCase().trim() === "id") {
								let comment = (value.comment || "").toString().replace(/\r?\n|\r/g, " ");
								if (mimeFuncs.isPlainText(comment)) comment = "\"" + comment + "\"";
								else comment = mimeFuncs.encodeWord(comment);
								return (value.comment ? comment + " " : "") + this._formatListUrl(value.url).replace(/^<[^:]+:\/{0,2}/, "<");
							}
							let comment = (value.comment || "").toString().replace(/\r?\n|\r/g, " ");
							if (!mimeFuncs.isPlainText(comment)) comment = mimeFuncs.encodeWord(comment);
							return this._formatListUrl(value.url) + (value.comment ? " (" + comment + ")" : "");
						}
						return "";
					}).filter((value) => value).join(", ")
				}))
			}));
		}
		_formatListUrl(url) {
			url = url.replace(/[\s<]+|[\s>]+/g, "");
			if (/^(https?|mailto|ftp):/.test(url)) return "<" + url + ">";
			if (/^[^@]+@[^@]+$/.test(url)) return "<mailto:" + url + ">";
			return "<http://" + url + ">";
		}
	};
	module.exports = MailMessage;
}));
//#endregion
//#region node_modules/nodemailer/lib/mailer/index.js
var require_mailer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var EventEmitter$6 = __require("events");
	var shared = require_shared();
	var mimeTypes = require_mime_types();
	var MailComposer = require_mail_composer();
	var DKIM = require_dkim();
	var httpProxyClient = require_http_proxy_client();
	var errors = require_errors();
	var util$6 = __require("util");
	var urllib = require_url();
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var MailMessage = require_mail_message();
	var net$2 = __require("net");
	var dns = __require("dns");
	var crypto$4 = __require("crypto");
	/**
	* Creates an object for exposing the Mail API
	*
	* @constructor
	* @param {Object} transporter Transport object instance to pass the mails to
	*/
	var Mail = class extends EventEmitter$6 {
		constructor(transporter, options, defaults) {
			super();
			this.options = options || {};
			this._defaults = defaults || {};
			this._defaultPlugins = {
				compile: [(...args) => this._convertDataImages(...args)],
				stream: []
			};
			this._userPlugins = {
				compile: [],
				stream: []
			};
			this.meta = /* @__PURE__ */ new Map();
			this.dkim = this.options.dkim ? new DKIM(this.options.dkim) : false;
			this.transporter = transporter;
			this.transporter.mailer = this;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "mail" });
			this.logger.debug({ tnx: "create" }, "Creating transport: %s", this.getVersionString());
			if (typeof this.transporter.on === "function") {
				this.transporter.on("log", (log) => {
					this.logger.debug({ tnx: "transport" }, "%s: %s", log.type, log.message);
				});
				this.transporter.on("error", (err) => {
					this.logger.error({
						err,
						tnx: "transport"
					}, "Transport Error: %s", err.message);
					this.emit("error", err);
				});
				this.transporter.on("idle", (...args) => {
					this.emit("idle", ...args);
				});
				this.transporter.on("clear", (...args) => {
					this.emit("clear", ...args);
				});
			}
			/**
			* Optional methods passed to the underlying transport object
			*/
			[
				"close",
				"isIdle",
				"verify"
			].forEach((method) => {
				this[method] = (...args) => {
					if (typeof this.transporter[method] === "function") {
						if (method === "verify" && typeof this.getSocket === "function") {
							this.transporter.getSocket = this.getSocket;
							this.getSocket = false;
						}
						return this.transporter[method](...args);
					}
					this.logger.warn({
						tnx: "transport",
						methodName: method
					}, "Non existing method %s called for transport", method);
					return false;
				};
			});
			if (this.options.proxy && typeof this.options.proxy === "string") this.setupProxy(this.options.proxy);
		}
		use(step, plugin) {
			step = (step || "").toString();
			if (!this._userPlugins.hasOwnProperty(step)) this._userPlugins[step] = [plugin];
			else this._userPlugins[step].push(plugin);
			return this;
		}
		/**
		* Sends an email using the preselected transport object
		*
		* @param {Object} data E-data description
		* @param {Function?} callback Callback to run once the sending succeeded or failed
		*/
		sendMail(data, callback = null) {
			let promise;
			if (!callback) promise = new Promise((resolve, reject) => {
				callback = shared.callbackPromise(resolve, reject);
			});
			if (typeof this.getSocket === "function") {
				this.transporter.getSocket = this.getSocket;
				this.getSocket = false;
			}
			const mail = new MailMessage(this, data);
			this.logger.debug({
				tnx: "transport",
				name: this.transporter.name,
				version: this.transporter.version,
				action: "send"
			}, "Sending mail using %s/%s", this.transporter.name, this.transporter.version);
			this._processPlugins("compile", mail, (err) => {
				if (err) {
					this.logger.error({
						err,
						tnx: "plugin",
						action: "compile"
					}, "PluginCompile Error: %s", err.message);
					return callback(err);
				}
				mail.message = new MailComposer(mail.data).compile();
				mail.setMailerHeader();
				mail.setPriorityHeaders();
				mail.setListHeaders();
				this._processPlugins("stream", mail, (err) => {
					if (err) {
						this.logger.error({
							err,
							tnx: "plugin",
							action: "stream"
						}, "PluginStream Error: %s", err.message);
						return callback(err);
					}
					if (mail.data.dkim || this.dkim) mail.message.processFunc((input) => {
						const dkim = mail.data.dkim ? new DKIM(mail.data.dkim) : this.dkim;
						this.logger.debug({
							tnx: "DKIM",
							messageId: mail.message.messageId(),
							dkimDomains: dkim.keys.map((key) => key.keySelector + "." + key.domainName).join(", ")
						}, "Signing outgoing message with %s keys", dkim.keys.length);
						return dkim.sign(input, mail.data._dkim);
					});
					this.transporter.send(mail, (...args) => {
						if (args[0]) this.logger.error({
							err: args[0],
							tnx: "transport",
							action: "send"
						}, "Send Error: %s", args[0].message);
						callback(...args);
					});
				});
			});
			return promise;
		}
		getVersionString() {
			return util$6.format("%s (%s; +%s; %s/%s)", packageData.name, packageData.version, packageData.homepage, this.transporter.name, this.transporter.version);
		}
		_processPlugins(step, mail, callback) {
			step = (step || "").toString();
			if (!this._userPlugins.hasOwnProperty(step)) return callback();
			const userPlugins = this._userPlugins[step] || [];
			const defaultPlugins = this._defaultPlugins[step] || [];
			if (userPlugins.length) this.logger.debug({
				tnx: "transaction",
				pluginCount: userPlugins.length,
				step
			}, "Using %s plugins for %s", userPlugins.length, step);
			if (userPlugins.length + defaultPlugins.length === 0) return callback();
			let pos = 0;
			let block = "default";
			const processPlugins = () => {
				let curplugins = block === "default" ? defaultPlugins : userPlugins;
				if (pos >= curplugins.length) if (block === "default" && userPlugins.length) {
					block = "user";
					pos = 0;
					curplugins = userPlugins;
				} else return callback();
				const plugin = curplugins[pos++];
				plugin(mail, (err) => {
					if (err) return callback(err);
					processPlugins();
				});
			};
			processPlugins();
		}
		/**
		* Sets up proxy handler for a Nodemailer object
		*
		* @param {String} proxyUrl Proxy configuration url
		*/
		setupProxy(proxyUrl) {
			const proxy = urllib.parse(proxyUrl);
			this.getSocket = (options, callback) => {
				const protocol = proxy.protocol.replace(/:$/, "").toLowerCase();
				if (this.meta.has("proxy_handler_" + protocol)) return this.meta.get("proxy_handler_" + protocol)(proxy, options, callback);
				switch (protocol) {
					case "http":
					case "https":
						httpProxyClient(proxy.href, options.port, options.host, this.options.tls || {}, (err, socket) => {
							if (err) return callback(err);
							return callback(null, { connection: socket });
						});
						return;
					case "socks":
					case "socks5":
					case "socks4":
					case "socks4a": {
						if (!this.meta.has("proxy_socks_module")) {
							let err = /* @__PURE__ */ new Error("Socks module not loaded");
							err.code = errors.EPROXY;
							return callback(err);
						}
						const connect = (ipaddress) => {
							const proxyV2 = !!this.meta.get("proxy_socks_module").SocksClient;
							const socksClient = proxyV2 ? this.meta.get("proxy_socks_module").SocksClient : this.meta.get("proxy_socks_module");
							const proxyType = Number(proxy.protocol.replace(/\D/g, "")) || 5;
							const connectionOpts = {
								proxy: {
									ipaddress,
									port: Number(proxy.port),
									type: proxyType
								},
								[proxyV2 ? "destination" : "target"]: {
									host: options.host,
									port: options.port
								},
								command: "connect"
							};
							if (proxy.auth) {
								const username = decodeURIComponent(proxy.auth.split(":").shift());
								const password = decodeURIComponent(proxy.auth.split(":").pop());
								if (proxyV2) {
									connectionOpts.proxy.userId = username;
									connectionOpts.proxy.password = password;
								} else if (proxyType === 4) connectionOpts.userid = username;
								else connectionOpts.authentication = {
									username,
									password
								};
							}
							socksClient.createConnection(connectionOpts, (err, info) => {
								if (err) return callback(err);
								return callback(null, { connection: info.socket || info });
							});
						};
						if (net$2.isIP(proxy.hostname)) return connect(proxy.hostname);
						return dns.resolve(proxy.hostname, (err, address) => {
							if (err) return callback(err);
							connect(Array.isArray(address) ? address[0] : address);
						});
					}
				}
				let err = /* @__PURE__ */ new Error("Unknown proxy configuration");
				err.code = errors.EPROXY;
				callback(err);
			};
		}
		_convertDataImages(mail, callback) {
			if (!this.options.attachDataUrls && !mail.data.attachDataUrls || !mail.data.html) return callback();
			mail.resolveContent(mail.data, "html", {
				disableFileAccess: mail.data.disableFileAccess,
				disableUrlAccess: mail.data.disableUrlAccess
			}, (err, html) => {
				if (err) return callback(err);
				let cidCounter = 0;
				html = (html || "").toString().replace(/(<img\b[^<>]{0,1024} src\s{0,20}=[\s"']{0,20})(data:([^;]+);[^"'>\s]+)/gi, (match, prefix, dataUri, mimeType) => {
					const cid = crypto$4.randomBytes(10).toString("hex") + "@localhost";
					if (!mail.data.attachments) mail.data.attachments = [];
					if (!Array.isArray(mail.data.attachments)) mail.data.attachments = [].concat(mail.data.attachments || []);
					mail.data.attachments.push({
						path: dataUri,
						cid,
						filename: "image-" + ++cidCounter + "." + mimeTypes.detectExtension(mimeType)
					});
					return prefix + "cid:" + cid;
				});
				mail.data.html = html;
				callback();
			});
		}
		set(key, value) {
			return this.meta.set(key, value);
		}
		get(key) {
			return this.meta.get(key);
		}
	};
	module.exports = Mail;
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-connection/data-stream.js
var require_data_stream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Transform } = __require("stream");
	/**
	* Escapes dots in the beginning of lines. Ends the stream with <CR><LF>.<CR><LF>
	* Also makes sure that only <CR><LF> sequences are used for linebreaks
	*
	* @param {Object} options Stream options
	*/
	var DataStream = class extends Transform {
		constructor(options) {
			super(options);
			this.options = options || {};
			this.inByteCount = 0;
			this.outByteCount = 0;
			this.lastByte = false;
		}
		/**
		* Escapes dots
		*/
		_transform(chunk, encoding, done) {
			const chunks = [];
			let chunklen = 0;
			let i, len, lastPos = 0;
			let buf;
			if (!chunk || !chunk.length) return done();
			if (typeof chunk === "string") chunk = Buffer.from(chunk);
			this.inByteCount += chunk.length;
			for (i = 0, len = chunk.length; i < len; i++) if (chunk[i] === 46) {
				if (i && chunk[i - 1] === 10 || !i && (!this.lastByte || this.lastByte === 10)) {
					buf = chunk.slice(lastPos, i + 1);
					chunks.push(buf);
					chunks.push(Buffer.from("."));
					chunklen += buf.length + 1;
					lastPos = i + 1;
				}
			} else if (chunk[i] === 10) {
				if (i && chunk[i - 1] !== 13 || !i && this.lastByte !== 13) {
					if (i > lastPos) {
						buf = chunk.slice(lastPos, i);
						chunks.push(buf);
						chunklen += buf.length + 2;
					} else chunklen += 2;
					chunks.push(Buffer.from("\r\n"));
					lastPos = i + 1;
				}
			}
			if (chunklen) {
				if (lastPos < chunk.length) {
					buf = chunk.slice(lastPos);
					chunks.push(buf);
					chunklen += buf.length;
				}
				this.outByteCount += chunklen;
				this.push(Buffer.concat(chunks, chunklen));
			} else {
				this.outByteCount += chunk.length;
				this.push(chunk);
			}
			this.lastByte = chunk[chunk.length - 1];
			done();
		}
		/**
		* Finalizes the stream with a dot on a single line
		*/
		_flush(done) {
			let buf;
			if (this.lastByte === 10) buf = Buffer.from(".\r\n");
			else if (this.lastByte === 13) buf = Buffer.from("\n.\r\n");
			else buf = Buffer.from("\r\n.\r\n");
			this.outByteCount += buf.length;
			this.push(buf);
			done();
		}
	};
	module.exports = DataStream;
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-connection/index.js
var require_smtp_connection = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var packageInfo = (init_package(), __toCommonJS(package_exports).default);
	var { EventEmitter: EventEmitter$5 } = __require("events");
	var net$1 = __require("net");
	var tls = __require("tls");
	var os$1 = __require("os");
	var crypto$3 = __require("crypto");
	var DataStream = require_data_stream();
	var { PassThrough } = __require("stream");
	var shared = require_shared();
	var CONNECTION_TIMEOUT = 12e4;
	var SOCKET_TIMEOUT = 6e5;
	var GREETING_TIMEOUT = 3e4;
	var DNS_TIMEOUT = 3e4;
	var TEARDOWN_NOOP = () => {};
	/**
	* Re-interpret a server response stored in fake 8-bit byte-container form
	* (the result of chunk.toString('binary') in _onData) as UTF-8.
	*
	* Server reply text has no formally defined charset (RFC 5321 §4.2.1), but
	* modern MTAs commonly use UTF-8. The byte-container plumbing in _onData is
	* required to reassemble multi-byte sequences split across socket chunks;
	* this helper performs the actual decode at the line boundary, falling back
	* to the byte-container form when the bytes are not valid UTF-8 so that
	* legacy 8-bit replies are still recoverable byte-for-byte.
	*/
	function decodeServerResponse(str) {
		if (!str) return str;
		const utf8 = Buffer.from(str, "binary").toString("utf8");
		return utf8.includes("�") ? str : utf8;
	}
	/**
	* Generates a SMTP connection object
	*
	* Optional options object takes the following possible properties:
	*
	*  * **port** - is the port to connect to (defaults to 587 or 465)
	*  * **host** - is the hostname or IP address to connect to (defaults to 'localhost')
	*  * **secure** - use SSL
	*  * **ignoreTLS** - ignore server support for STARTTLS
	*  * **requireTLS** - forces the client to use STARTTLS
	*  * **name** - the name of the client server
	*  * **localAddress** - outbound address to bind to (see: http://nodejs.org/api/net.html#net_net_connect_options_connectionlistener)
	*  * **greetingTimeout** - Time to wait in ms until greeting message is received from the server (defaults to 30 seconds)
	*  * **connectionTimeout** - how many milliseconds to wait for the connection to establish (defaults to 2 minutes)
	*  * **socketTimeout** - Time of inactivity until the connection is closed (defaults to 10 minutes)
	*  * **dnsTimeout** - Time to wait in ms for the DNS requests to be resolved (defaults to 30 seconds)
	*  * **lmtp** - if true, uses LMTP instead of SMTP protocol
	*  * **logger** - bunyan compatible logger interface
	*  * **debug** - if true pass SMTP traffic to the logger
	*  * **tls** - options for createCredentials
	*  * **socket** - existing socket to use instead of creating a new one (see: http://nodejs.org/api/net.html#net_class_net_socket)
	*  * **secured** - boolean indicates that the provided socket has already been upgraded to tls
	*
	* @constructor
	* @namespace SMTP Client module
	* @param {Object} [options] Option properties
	*/
	var SMTPConnection = class extends EventEmitter$5 {
		constructor(options) {
			super(options);
			this.id = crypto$3.randomBytes(8).toString("base64").replace(/\W/g, "");
			this.stage = "init";
			this.options = options || {};
			this.secureConnection = !!this.options.secure;
			this.alreadySecured = !!this.options.secured;
			this.port = Number(this.options.port) || (this.secureConnection ? 465 : 587);
			this.host = this.options.host || "localhost";
			this.servername = this.options.servername ? this.options.servername : !net$1.isIP(this.host) ? this.host : false;
			this.allowInternalNetworkInterfaces = this.options.allowInternalNetworkInterfaces || false;
			if (typeof this.options.secure === "undefined" && this.port === 465) this.secureConnection = true;
			this.name = (this.options.name || this._getHostname()).toString().replace(/[\r\n]+/g, "");
			this.logger = shared.getLogger(this.options, {
				component: this.options.component || "smtp-connection",
				sid: this.id
			});
			this.customAuth = /* @__PURE__ */ new Map();
			for (const key of Object.keys(this.options.customAuth || {})) {
				const mapKey = (key || "").toString().trim().toUpperCase();
				if (mapKey) this.customAuth.set(mapKey, this.options.customAuth[key]);
			}
			/**
			* Expose version nr, just for the reference
			* @type {String}
			*/
			this.version = packageInfo.version;
			/**
			* If true, then the user is authenticated
			* @type {Boolean}
			*/
			this.authenticated = false;
			/**
			* If set to true, this instance is no longer active
			* @private
			*/
			this.destroyed = false;
			/**
			* Defines if the current connection is secure or not. If not,
			* STARTTLS can be used if available
			* @private
			*/
			this.secure = !!this.secureConnection;
			/**
			* Store incomplete messages coming from the server
			* @private
			*/
			this._remainder = "";
			/**
			* Unprocessed responses from the server
			* @type {Array}
			*/
			this._responseQueue = [];
			this.lastServerResponse = false;
			/**
			* The socket connecting to the server
			* @public
			*/
			this._socket = false;
			/**
			* Lists supported auth mechanisms
			* @private
			*/
			this._supportedAuth = [];
			/**
			* Set to true, if EHLO response includes "AUTH".
			* If false then authentication is not tried
			*/
			this.allowsAuth = false;
			/**
			* Includes current envelope (from, to)
			* @private
			*/
			this._envelope = false;
			/**
			* Lists supported extensions
			* @private
			*/
			this._supportedExtensions = [];
			/**
			* Defines the maximum allowed size for a single message
			* @private
			*/
			this._maxAllowedSize = 0;
			/**
			* Function queue to run if a data chunk comes from the server
			* @private
			*/
			this._responseActions = [];
			this._recipientQueue = [];
			/**
			* Timeout variable for waiting the greeting
			* @private
			*/
			this._greetingTimeout = false;
			/**
			* Timeout variable for waiting the connection to start
			* @private
			*/
			this._connectionTimeout = false;
			/**
			* If the socket is deemed already closed
			* @private
			*/
			this._destroyed = false;
			/**
			* If the socket is already being closed
			* @private
			*/
			this._closing = false;
			/**
			* Message DATA stream currently piped to the socket, if any. Tracked so
			* close() can unpipe it before tearing the socket down.
			* @private
			*/
			this._currentDataStream = false;
			/**
			* Callbacks for socket's listeners
			*/
			this._onSocketData = (chunk) => this._onData(chunk);
			this._onSocketError = (error) => this._onError(error, "ESOCKET", false, "CONN");
			this._onSocketClose = () => this._onClose();
			this._onSocketEnd = () => this._onEnd();
			this._onSocketTimeout = () => this._onTimeout();
			/**
			* Connection-phase error handler (supports fallback to alternative addresses)
			*/
			this._onConnectionSocketError = (err) => this._onConnectionError(err, "ESOCKET");
			/**
			* Connection attempt counter for fallback race condition protection
			* @private
			*/
			this._connectionAttemptId = 0;
		}
		/**
		* Creates a connection to a SMTP server and sets up connection
		* listener
		*/
		connect(connectCallback) {
			if (typeof connectCallback === "function") {
				this.once("connect", () => {
					this.logger.debug({ tnx: "smtp" }, "SMTP handshake finished");
					connectCallback();
				});
				const isDestroyedMessage = this._isDestroyedMessage("connect");
				if (isDestroyedMessage) return connectCallback(this._formatError(isDestroyedMessage, "ECONNECTION", false, "CONN"));
			}
			let opts = {
				port: this.port,
				host: this.host,
				allowInternalNetworkInterfaces: this.allowInternalNetworkInterfaces,
				timeout: this.options.dnsTimeout || DNS_TIMEOUT
			};
			if (this.options.localAddress) opts.localAddress = this.options.localAddress;
			if (this.options.connection) {
				this._socket = this.options.connection;
				this._setupConnectionHandlers();
				if (this.secureConnection && !this.alreadySecured) setImmediate(() => this._upgradeConnection((err) => {
					if (err) {
						this._onError(/* @__PURE__ */ new Error("Error initiating TLS - " + (err.message || err)), "ETLS", false, "CONN");
						return;
					}
					this._onConnect();
				}));
				else setImmediate(() => this._onConnect());
				return;
			} else if (this.options.socket) {
				this._socket = this.options.socket;
				return this._resolveAndConnect(opts, (_resolved) => {
					try {
						this._socket.connect(this.port, this.host, () => {
							this._socket.setKeepAlive(true);
							if (this.secureConnection && !this.alreadySecured) return this._upgradeConnection((err) => {
								if (err) {
									this._onError(/* @__PURE__ */ new Error("Error initiating TLS - " + (err.message || err)), "ETLS", false, "CONN");
									return;
								}
								this._onConnect();
							});
							this._onConnect();
						});
						this._setupConnectionHandlers();
					} catch (E) {
						return setImmediate(() => this._onError(E, "ECONNECTION", false, "CONN"));
					}
				});
			} else {
				if (this.secureConnection) {
					Object.assign(opts, this.options.tls || {});
					if (this.servername && !opts.servername) opts.servername = this.servername;
				}
				return this._resolveAndConnect(opts, (resolved) => {
					this._fallbackAddresses = (resolved._addresses || []).filter((addr) => addr !== opts.host);
					this._connectOpts = Object.assign({}, opts);
					this._connectToHost(opts, this.secureConnection);
				});
			}
		}
		/**
		* Resolves the hostname and applies resolved values to opts,
		* then calls the provided callback with the resolved data
		*
		* @param {Object} opts Connection options (modified in place)
		* @param {Function} callback Called with resolved data on success
		*/
		_resolveAndConnect(opts, callback) {
			return shared.resolveHostname(opts, (err, resolved) => {
				if (err) return setImmediate(() => this._onError(err, "EDNS", false, "CONN"));
				this.logger.debug({
					tnx: "dns",
					source: opts.host,
					resolved: resolved.host,
					cached: !!resolved.cached
				}, "Resolved %s as %s [cache %s]", opts.host, resolved.host, resolved.cached ? "hit" : "miss");
				for (const key of Object.keys(resolved)) if (key.charAt(0) !== "_" && resolved[key]) opts[key] = resolved[key];
				callback(resolved);
			});
		}
		/**
		* Attempts to connect to the specified host address
		*
		* @param {Object} opts Connection options
		* @param {Boolean} secure Whether to use TLS
		*/
		_connectToHost(opts, secure) {
			if (this._destroyed || this._closing) return;
			this._connectionAttemptId++;
			const currentAttemptId = this._connectionAttemptId;
			const connectFn = secure ? tls.connect : net$1.connect;
			try {
				this._socket = connectFn(opts, () => {
					if (this._connectionAttemptId !== currentAttemptId) return;
					this._socket.setKeepAlive(true);
					this._onConnect();
				});
				this._setupConnectionHandlers();
			} catch (E) {
				return setImmediate(() => this._onError(E, "ECONNECTION", false, "CONN"));
			}
		}
		/**
		* Sets up connection timeout and error handlers
		*/
		_setupConnectionHandlers() {
			this._connectionTimeout = setTimeout(() => {
				this._onConnectionError("Connection timeout", "ETIMEDOUT");
			}, this.options.connectionTimeout || CONNECTION_TIMEOUT);
			this._socket.on("error", this._onConnectionSocketError);
		}
		/**
		* Handles connection errors with fallback to alternative addresses
		*
		* @param {Error|String} err Error object or message
		* @param {String} code Error code
		*/
		_onConnectionError(err, code) {
			clearTimeout(this._connectionTimeout);
			if (!(this._fallbackAddresses && this._fallbackAddresses.length && this.stage === "init" && !this._destroyed)) {
				this._onError(err, code, false, "CONN");
				return;
			}
			const nextHost = this._fallbackAddresses.shift();
			this.logger.info({
				tnx: "network",
				failedHost: this._connectOpts.host,
				nextHost,
				error: err.message || err
			}, "Connection to %s failed, trying %s", this._connectOpts.host, nextHost);
			if (this._socket) {
				try {
					this._socket.removeListener("error", this._onConnectionSocketError);
					this._socket.on("error", TEARDOWN_NOOP);
					this._socket.destroy();
				} catch (_E) {}
				this._socket = null;
			}
			this._connectOpts.host = nextHost;
			this._connectToHost(this._connectOpts, this.secureConnection);
		}
		/**
		* Sends QUIT
		*/
		quit() {
			this._sendCommand("QUIT");
			this._responseActions.push(this.close);
		}
		/**
		* Closes the connection to the server
		*/
		close() {
			clearTimeout(this._connectionTimeout);
			clearTimeout(this._greetingTimeout);
			this._responseActions = [];
			if (this._closing) return;
			this._closing = true;
			const closeMethod = this.stage === "init" ? "destroy" : "end";
			this.logger.debug({ tnx: "smtp" }, "Closing connection to the server using \"%s\"", closeMethod);
			const socket = this._socket && this._socket.socket || this._socket;
			if (this._currentDataStream) {
				try {
					this._currentDataStream.unpipe(this._socket);
				} catch (_E) {}
				this._currentDataStream = false;
			}
			if (socket && !socket.destroyed) try {
				socket.setTimeout(0);
				socket.removeListener("data", this._onSocketData);
				socket.removeListener("timeout", this._onSocketTimeout);
				socket.removeListener("close", this._onSocketClose);
				socket.removeListener("end", this._onSocketEnd);
				socket.removeListener("error", this._onSocketError);
				socket.removeListener("error", this._onConnectionSocketError);
				socket.on("error", TEARDOWN_NOOP);
				socket[closeMethod]();
			} catch (_E) {}
			this._destroy();
		}
		/**
		* Authenticate user
		*/
		login(authData, callback) {
			const isDestroyedMessage = this._isDestroyedMessage("login");
			if (isDestroyedMessage) return callback(this._formatError(isDestroyedMessage, "ECONNECTION", false, "API"));
			this._auth = authData || {};
			this._authMethod = (this._auth.method || "").toString().trim().toUpperCase() || false;
			if (!this._authMethod && this._auth.oauth2 && !this._auth.credentials) this._authMethod = "XOAUTH2";
			else if (!this._authMethod || this._authMethod === "XOAUTH2" && !this._auth.oauth2) this._authMethod = (this._supportedAuth[0] || "PLAIN").toUpperCase().trim();
			if (this._authMethod !== "XOAUTH2" && (!this._auth.credentials || !this._auth.credentials.user || !this._auth.credentials.pass)) if (this._auth.user && this._auth.pass || this.customAuth.has(this._authMethod)) this._auth.credentials = {
				user: this._auth.user,
				pass: this._auth.pass,
				options: this._auth.options
			};
			else return callback(this._formatError("Missing credentials for \"" + this._authMethod + "\"", "EAUTH", false, "API"));
			if (this.customAuth.has(this._authMethod)) {
				const handler = this.customAuth.get(this._authMethod);
				let lastResponse;
				let returned = false;
				const resolve = () => {
					if (returned) return;
					returned = true;
					this.logger.info({
						tnx: "smtp",
						username: this._auth.user,
						action: "authenticated",
						method: this._authMethod
					}, "User %s authenticated", JSON.stringify(this._auth.user));
					this.authenticated = true;
					callback(null, true);
				};
				const reject = (err) => {
					if (returned) return;
					returned = true;
					callback(this._formatError(err, "EAUTH", lastResponse, "AUTH " + this._authMethod));
				};
				const handlerResponse = handler({
					auth: this._auth,
					method: this._authMethod,
					extensions: [].concat(this._supportedExtensions),
					authMethods: [].concat(this._supportedAuth),
					maxAllowedSize: this._maxAllowedSize || false,
					sendCommand: (cmd, done) => {
						let promise;
						if (!done) promise = new Promise((resolve, reject) => {
							done = shared.callbackPromise(resolve, reject);
						});
						this._responseActions.push((str) => {
							lastResponse = str;
							let codes = str.match(/^(\d+)(?:\s(\d+\.\d+\.\d+))?\s/);
							let data = {
								command: cmd,
								response: str
							};
							if (codes) {
								data.status = Number(codes[1]) || 0;
								if (codes[2]) data.code = codes[2];
								data.text = str.substr(codes[0].length);
							} else {
								data.text = str;
								data.status = 0;
							}
							done(null, data);
						});
						setImmediate(() => this._sendCommand(cmd));
						return promise;
					},
					resolve,
					reject
				});
				if (handlerResponse && typeof handlerResponse.catch === "function") handlerResponse.then(resolve).catch(reject);
				return;
			}
			switch (this._authMethod) {
				case "XOAUTH2":
					this._handleXOauth2Token(false, callback);
					return;
				case "LOGIN":
					this._responseActions.push((str) => {
						this._actionAUTH_LOGIN_USER(str, callback);
					});
					this._sendCommand("AUTH LOGIN");
					return;
				case "PLAIN":
					this._responseActions.push((str) => {
						this._actionAUTHComplete(str, callback);
					});
					this._sendCommand("AUTH PLAIN " + Buffer.from("\0" + this._auth.credentials.user + "\0" + this._auth.credentials.pass, "utf-8").toString("base64"), "AUTH PLAIN " + Buffer.from("\0" + this._auth.credentials.user + "\0/* secret */", "utf-8").toString("base64"));
					return;
				case "CRAM-MD5":
					this._responseActions.push((str) => {
						this._actionAUTH_CRAM_MD5(str, callback);
					});
					this._sendCommand("AUTH CRAM-MD5");
					return;
			}
			return callback(this._formatError("Unknown authentication method \"" + this._authMethod + "\"", "EAUTH", false, "API"));
		}
		/**
		* Sends a message
		*
		* @param {Object} envelope Envelope object, {from: addr, to: [addr]}
		* @param {Object} message String, Buffer or a Stream
		* @param {Function} callback Callback to return once sending is completed
		*/
		send(envelope, message, done) {
			if (!message) return done(this._formatError("Empty message", "EMESSAGE", false, "API"));
			const isDestroyedMessage = this._isDestroyedMessage("send message");
			if (isDestroyedMessage) return done(this._formatError(isDestroyedMessage, "ECONNECTION", false, "API"));
			if (this._maxAllowedSize && envelope.size > this._maxAllowedSize) return setImmediate(() => {
				done(this._formatError("Message size larger than allowed " + this._maxAllowedSize, "EMESSAGE", false, "MAIL FROM"));
			});
			let returned = false;
			const callback = function() {
				if (returned) return;
				returned = true;
				done(...arguments);
			};
			if (typeof message.on === "function") message.on("error", (err) => callback(this._formatError(err, "ESTREAM", false, "API")));
			const startTime = Date.now();
			this._setEnvelope(envelope, (err, info) => {
				if (err) {
					const stream = new PassThrough();
					if (typeof message.pipe === "function") message.pipe(stream);
					else {
						stream.write(message);
						stream.end();
					}
					return callback(err);
				}
				const envelopeTime = Date.now();
				const stream = this._createSendStream((err, str) => {
					if (err) return callback(err);
					info.envelopeTime = envelopeTime - startTime;
					info.messageTime = Date.now() - envelopeTime;
					info.messageSize = stream.outByteCount;
					info.response = str;
					return callback(null, info);
				});
				if (typeof message.pipe === "function") message.pipe(stream);
				else {
					stream.write(message);
					stream.end();
				}
			});
		}
		/**
		* Resets connection state
		*
		* @param {Function} callback Callback to return once connection is reset
		*/
		reset(callback) {
			const isDestroyedMessage = this._isDestroyedMessage("reset");
			if (isDestroyedMessage) return callback(this._formatError(isDestroyedMessage, "ECONNECTION", false, "API"));
			this._sendCommand("RSET");
			this._responseActions.push((str) => {
				if (str.charAt(0) !== "2") return callback(this._formatError("Could not reset session state. response=" + str, "EPROTOCOL", str, "RSET"));
				this._envelope = false;
				return callback(null, true);
			});
		}
		/**
		* Connection listener that is run when the connection to
		* the server is opened
		*
		* @event
		*/
		_onConnect() {
			clearTimeout(this._connectionTimeout);
			this.logger.info({
				tnx: "network",
				localAddress: this._socket.localAddress,
				localPort: this._socket.localPort,
				remoteAddress: this._socket.remoteAddress,
				remotePort: this._socket.remotePort
			}, "%s established to %s:%s", this.secure ? "Secure connection" : "Connection", this._socket.remoteAddress, this._socket.remotePort);
			if (this._destroyed) {
				this.close();
				return;
			}
			this.stage = "connected";
			this._socket.removeListener("data", this._onSocketData);
			this._socket.removeListener("timeout", this._onSocketTimeout);
			this._socket.removeListener("close", this._onSocketClose);
			this._socket.removeListener("end", this._onSocketEnd);
			this._socket.removeListener("error", this._onConnectionSocketError);
			this._socket.removeListener("error", this._onSocketError);
			this._socket.on("error", this._onSocketError);
			this._socket.on("data", this._onSocketData);
			this._socket.once("close", this._onSocketClose);
			this._socket.once("end", this._onSocketEnd);
			this._socket.setTimeout(this.options.socketTimeout || SOCKET_TIMEOUT);
			this._socket.on("timeout", this._onSocketTimeout);
			this._greetingTimeout = setTimeout(() => {
				if (this._socket && !this._destroyed && this._responseActions[0] === this._actionGreeting) this._onError("Greeting never received", "ETIMEDOUT", false, "CONN");
			}, this.options.greetingTimeout || GREETING_TIMEOUT);
			this._responseActions.push(this._actionGreeting);
			this._socket.resume();
		}
		/**
		* 'data' listener for data coming from the server
		*
		* @event
		* @param {Buffer} chunk Data chunk coming from the server
		*/
		_onData(chunk) {
			if (this._destroyed || !chunk || !chunk.length) return;
			let data = chunk.toString("binary");
			let lines = (this._remainder + data).split(/\r?\n/);
			let lastline;
			this._remainder = lines.pop();
			for (let i = 0, len = lines.length; i < len; i++) {
				if (this._responseQueue.length) {
					lastline = this._responseQueue[this._responseQueue.length - 1];
					if (/^\d+-/.test(lastline.split("\n").pop())) {
						this._responseQueue[this._responseQueue.length - 1] += "\n" + lines[i];
						continue;
					}
				}
				this._responseQueue.push(lines[i]);
			}
			if (this._responseQueue.length) {
				lastline = this._responseQueue[this._responseQueue.length - 1];
				if (/^\d+-/.test(lastline.split("\n").pop())) return;
			}
			this._processResponse();
		}
		/**
		* 'error' listener for the socket
		*
		* @event
		* @param {Error} err Error object
		* @param {String} type Error name
		*/
		_onError(err, type, data, command) {
			clearTimeout(this._connectionTimeout);
			clearTimeout(this._greetingTimeout);
			if (this._destroyed) return;
			err = this._formatError(err, type, data, command);
			if ([
				"ETIMEDOUT",
				"ESOCKET",
				"ECONNECTION"
			].includes(err.code)) this.logger.warn(data, err.message);
			else this.logger.error(data, err.message);
			this.emit("error", err);
			this.close();
		}
		_formatError(message, type, response, command) {
			let err;
			if (/Error\]$/i.test(Object.prototype.toString.call(message))) err = message;
			else err = new Error(message);
			if (type && type !== "Error") err.code = type;
			if (response) {
				err.response = response;
				err.message += ": " + response;
			}
			const responseCode = typeof response === "string" && Number((response.match(/^\d+/) || [])[0]) || false;
			if (responseCode) err.responseCode = responseCode;
			if (command) err.command = command;
			return err;
		}
		/**
		* 'close' listener for the socket
		*
		* @event
		*/
		_onClose() {
			let serverResponse = false;
			if (this._remainder && this._remainder.trim()) {
				this.lastServerResponse = serverResponse = decodeServerResponse(this._remainder.trim());
				if (this.options.debug || this.options.transactionLog) this.logger.debug({ tnx: "server" }, serverResponse);
			}
			this.logger.info({ tnx: "network" }, "Connection closed");
			if (this.upgrading && !this._destroyed) return this._onError(/* @__PURE__ */ new Error("Connection closed unexpectedly"), "ETLS", serverResponse, "CONN");
			else if (![this._actionGreeting, this.close].includes(this._responseActions[0]) && !this._destroyed) return this._onError(/* @__PURE__ */ new Error("Connection closed unexpectedly"), "ECONNECTION", serverResponse, "CONN");
			else if (/^[45]\d{2}\b/.test(serverResponse)) return this._onError(/* @__PURE__ */ new Error("Connection closed unexpectedly"), "ECONNECTION", serverResponse, "CONN");
			this._destroy();
		}
		/**
		* 'end' listener for the socket
		*
		* @event
		*/
		_onEnd() {
			if (this._socket && !this._socket.destroyed) this._socket.end();
		}
		/**
		* 'timeout' listener for the socket
		*
		* @event
		*/
		_onTimeout() {
			return this._onError(/* @__PURE__ */ new Error("Timeout"), "ETIMEDOUT", false, "CONN");
		}
		/**
		* Destroys the client, emits 'end'
		*/
		_destroy() {
			if (this._destroyed) return;
			this._destroyed = true;
			this.destroyed = true;
			this.emit("end");
		}
		/**
		* Upgrades the connection to TLS
		*
		* @param {Function} callback Callback function to run when the connection
		*        has been secured
		*/
		_upgradeConnection(callback) {
			this._remainder = "";
			this._responseQueue = [];
			this._socket.removeListener("data", this._onSocketData);
			this._socket.removeListener("timeout", this._onSocketTimeout);
			const socketPlain = this._socket;
			const opts = Object.assign({
				socket: this._socket,
				host: this.host
			}, this.options.tls || {});
			if (this.servername && !opts.servername) opts.servername = this.servername;
			const removePlainSocketListeners = () => {
				socketPlain.removeListener("close", this._onSocketClose);
				socketPlain.removeListener("end", this._onSocketEnd);
				socketPlain.removeListener("error", this._onSocketError);
				socketPlain.removeListener("error", this._onConnectionSocketError);
			};
			this.upgrading = true;
			try {
				this._socket = tls.connect(opts, () => {
					this.secure = true;
					this.upgrading = false;
					this._socket.on("data", this._onSocketData);
					removePlainSocketListeners();
					return callback(null, true);
				});
			} catch (err) {
				removePlainSocketListeners();
				return callback(err);
			}
			this._socket.on("error", this._onSocketError);
			this._socket.once("close", this._onSocketClose);
			this._socket.once("end", this._onSocketEnd);
			this._socket.setTimeout(this.options.socketTimeout || SOCKET_TIMEOUT);
			this._socket.on("timeout", this._onSocketTimeout);
			socketPlain.resume();
		}
		/**
		* Processes queued responses from the server
		*/
		_processResponse() {
			if (!this._responseQueue.length) return false;
			const raw = (this._responseQueue.shift() || "").toString();
			if (!raw.trim()) {
				setImmediate(() => this._processResponse());
				return;
			}
			let str = this.lastServerResponse = decodeServerResponse(raw);
			if (/^\d+-/.test(str.split("\n").pop())) {
				this._responseQueue.unshift(raw);
				return;
			}
			if (this.options.debug || this.options.transactionLog) this.logger.debug({ tnx: "server" }, str.replace(/\r?\n$/, ""));
			const action = this._responseActions.shift();
			if (typeof action === "function") {
				action.call(this, str);
				setImmediate(() => this._processResponse());
			} else return this._onError(/* @__PURE__ */ new Error("Unexpected Response"), "EPROTOCOL", str, "CONN");
		}
		/**
		* Send a command to the server, append \r\n
		*
		* @param {String} str String to be sent to the server
		* @param {String} logStr Optional string to be used for logging instead of the actual string
		*/
		_sendCommand(str, logStr) {
			if (this._destroyed) return;
			if (this._socket.destroyed) return this.close();
			if (this.options.debug || this.options.transactionLog) this.logger.debug({ tnx: "client" }, (logStr || str || "").toString().replace(/\r?\n$/, ""));
			this._socket.write(Buffer.from(str + "\r\n", "utf-8"));
		}
		/**
		* Initiates a new message by submitting envelope data, starting with
		* MAIL FROM: command
		*
		* @param {Object} envelope Envelope object in the form of
		*        {from:'...', to:['...']}
		*        or
		*        {from:{address:'...',name:'...'}, to:[address:'...',name:'...']}
		*/
		_setEnvelope(envelope, callback) {
			const args = [];
			let useSmtpUtf8 = false;
			this._envelope = envelope || {};
			this._envelope.from = (this._envelope.from && this._envelope.from.address || this._envelope.from || "").toString().trim();
			this._envelope.to = [].concat(this._envelope.to || []).map((to) => (to && to.address || to || "").toString().trim());
			if (!this._envelope.to.length) return callback(this._formatError("No recipients defined", "EENVELOPE", false, "API"));
			if (this._envelope.from && /[\r\n<>]/.test(this._envelope.from)) return callback(this._formatError("Invalid sender " + JSON.stringify(this._envelope.from), "EENVELOPE", false, "API"));
			if (/[\x80-\uFFFF]/.test(this._envelope.from)) useSmtpUtf8 = true;
			for (let i = 0, len = this._envelope.to.length; i < len; i++) {
				if (!this._envelope.to[i] || /[\r\n<>]/.test(this._envelope.to[i])) return callback(this._formatError("Invalid recipient " + JSON.stringify(this._envelope.to[i]), "EENVELOPE", false, "API"));
				if (/[\x80-\uFFFF]/.test(this._envelope.to[i])) useSmtpUtf8 = true;
			}
			this._envelope.rcptQueue = [].concat(this._envelope.to || []);
			this._envelope.rejected = [];
			this._envelope.rejectedErrors = [];
			this._envelope.accepted = [];
			if (this._envelope.dsn) try {
				this._envelope.dsn = this._setDsnEnvelope(this._envelope.dsn);
			} catch (err) {
				return callback(this._formatError("Invalid DSN " + err.message, "EENVELOPE", false, "API"));
			}
			if (this._envelope.requireTLSExtensionEnabled) {
				if (!this.secure) return callback(this._formatError("REQUIRETLS can only be used over TLS connections (RFC 8689)", "EREQUIRETLS", false, "MAIL FROM"));
				if (!this._supportedExtensions.includes("REQUIRETLS")) return callback(this._formatError("Server does not support REQUIRETLS extension (RFC 8689)", "EREQUIRETLS", false, "MAIL FROM"));
			}
			this._responseActions.push((str) => {
				this._actionMAIL(str, callback);
			});
			if (useSmtpUtf8 && this._supportedExtensions.includes("SMTPUTF8")) {
				args.push("SMTPUTF8");
				this._usingSmtpUtf8 = true;
			}
			if (this._envelope.use8BitMime && this._supportedExtensions.includes("8BITMIME")) {
				args.push("BODY=8BITMIME");
				this._using8BitMime = true;
			}
			if (this._envelope.size && this._supportedExtensions.includes("SIZE")) {
				const sizeValue = Number(this._envelope.size) || 0;
				if (sizeValue > 0) args.push("SIZE=" + sizeValue);
			}
			if (this._envelope.dsn && this._supportedExtensions.includes("DSN")) {
				if (this._envelope.dsn.ret) args.push("RET=" + shared.encodeXText(this._envelope.dsn.ret));
				if (this._envelope.dsn.envid) args.push("ENVID=" + shared.encodeXText(this._envelope.dsn.envid));
			}
			if (this._envelope.requireTLSExtensionEnabled) args.push("REQUIRETLS");
			this._sendCommand("MAIL FROM:<" + this._envelope.from + ">" + (args.length ? " " + args.join(" ") : ""));
		}
		_setDsnEnvelope(params) {
			let ret = (params.ret || params.return || "").toString().toUpperCase() || null;
			if (ret) switch (ret) {
				case "HDRS":
				case "HEADERS":
					ret = "HDRS";
					break;
				case "FULL":
				case "BODY": ret = "FULL";
			}
			if (ret && !["FULL", "HDRS"].includes(ret)) throw new Error("ret: " + JSON.stringify(ret));
			const envid = (params.envid || params.id || "").toString() || null;
			let notify = params.notify || null;
			if (notify) {
				if (typeof notify === "string") notify = notify.split(",");
				notify = notify.map((n) => n.trim().toUpperCase());
				const validNotify = [
					"NEVER",
					"SUCCESS",
					"FAILURE",
					"DELAY"
				];
				if (notify.filter((n) => !validNotify.includes(n)).length || notify.length > 1 && notify.includes("NEVER")) throw new Error("notify: " + JSON.stringify(notify.join(",")));
				notify = notify.join(",");
			}
			let orcpt = (params.recipient || params.orcpt || "").toString() || null;
			if (orcpt && orcpt.indexOf(";") < 0) orcpt = "rfc822;" + orcpt;
			return {
				ret,
				envid,
				notify,
				orcpt
			};
		}
		_getDsnRcptToArgs() {
			const args = [];
			if (this._envelope.dsn && this._supportedExtensions.includes("DSN")) {
				if (this._envelope.dsn.notify) args.push("NOTIFY=" + shared.encodeXText(this._envelope.dsn.notify));
				if (this._envelope.dsn.orcpt) args.push("ORCPT=" + shared.encodeXText(this._envelope.dsn.orcpt));
			}
			return args.length ? " " + args.join(" ") : "";
		}
		_createSendStream(callback) {
			const dataStream = new DataStream();
			if (this.options.lmtp) this._envelope.accepted.forEach((recipient, i) => {
				const final = i === this._envelope.accepted.length - 1;
				this._responseActions.push((str) => {
					this._actionLMTPStream(recipient, final, str, callback);
				});
			});
			else this._responseActions.push((str) => {
				this._actionSMTPStream(str, callback);
			});
			this._currentDataStream = dataStream;
			dataStream.pipe(this._socket, { end: false });
			if (this.options.debug) {
				const logStream = new PassThrough();
				logStream.on("readable", () => {
					let chunk;
					while (chunk = logStream.read()) this.logger.debug({ tnx: "message" }, chunk.toString("binary").replace(/\r?\n$/, ""));
				});
				dataStream.pipe(logStream);
			}
			dataStream.once("end", () => {
				if (this._currentDataStream === dataStream) this._currentDataStream = false;
				this.logger.info({
					tnx: "message",
					inByteCount: dataStream.inByteCount,
					outByteCount: dataStream.outByteCount
				}, "<%s bytes encoded mime message (source size %s bytes)>", dataStream.outByteCount, dataStream.inByteCount);
			});
			return dataStream;
		}
		/** ACTIONS **/
		/**
		* Will be run after the connection is created and the server sends
		* a greeting. If the incoming message starts with 220 initiate
		* SMTP session by sending EHLO command
		*
		* @param {String} str Message from the server
		*/
		_actionGreeting(str) {
			clearTimeout(this._greetingTimeout);
			if (str.substr(0, 3) !== "220") {
				this._onError(/* @__PURE__ */ new Error("Invalid greeting. response=" + str), "EPROTOCOL", str, "CONN");
				return;
			}
			if (this.options.lmtp) {
				this._responseActions.push(this._actionLHLO);
				this._sendCommand("LHLO " + this.name);
			} else {
				this._responseActions.push(this._actionEHLO);
				this._sendCommand("EHLO " + this.name);
			}
		}
		/**
		* Handles server response for LHLO command. If it yielded in
		* error, emit 'error', otherwise treat this as an EHLO response
		*
		* @param {String} str Message from the server
		*/
		_actionLHLO(str) {
			if (str.charAt(0) !== "2") {
				this._onError(/* @__PURE__ */ new Error("Invalid LHLO. response=" + str), "EPROTOCOL", str, "LHLO");
				return;
			}
			this._actionEHLO(str);
		}
		/**
		* Handles server response for EHLO command. If it yielded in
		* error, try HELO instead, otherwise initiate TLS negotiation
		* if STARTTLS is supported by the server or move into the
		* authentication phase.
		*
		* @param {String} str Message from the server
		*/
		_actionEHLO(str) {
			let match;
			if (str.substr(0, 3) === "421") {
				this._onError(/* @__PURE__ */ new Error("Server terminates connection. response=" + str), "ECONNECTION", str, "EHLO");
				return;
			}
			if (str.charAt(0) !== "2") {
				if (this.options.requireTLS) {
					this._onError(/* @__PURE__ */ new Error("EHLO failed but HELO does not support required STARTTLS. response=" + str), "ECONNECTION", str, "EHLO");
					return;
				}
				this._responseActions.push(this._actionHELO);
				this._sendCommand("HELO " + this.name);
				return;
			}
			this._ehloLines = str.split(/\r?\n/).map((line) => line.replace(/^\d+[ -]/, "").trim()).filter((line) => line).slice(1);
			if (!this.secure && !this.options.ignoreTLS && (/[ -]STARTTLS\b/im.test(str) || this.options.requireTLS)) {
				this._sendCommand("STARTTLS");
				this._responseActions.push(this._actionSTARTTLS);
				return;
			}
			if (/[ -]SMTPUTF8\b/im.test(str)) this._supportedExtensions.push("SMTPUTF8");
			if (/[ -]DSN\b/im.test(str)) this._supportedExtensions.push("DSN");
			if (/[ -]8BITMIME\b/im.test(str)) this._supportedExtensions.push("8BITMIME");
			if (/[ -]REQUIRETLS\b/im.test(str)) this._supportedExtensions.push("REQUIRETLS");
			if (/[ -]PIPELINING\b/im.test(str)) this._supportedExtensions.push("PIPELINING");
			if (/[ -]AUTH\b/i.test(str)) this.allowsAuth = true;
			if (/[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)PLAIN/i.test(str)) this._supportedAuth.push("PLAIN");
			if (/[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)LOGIN/i.test(str)) this._supportedAuth.push("LOGIN");
			if (/[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)CRAM-MD5/i.test(str)) this._supportedAuth.push("CRAM-MD5");
			if (/[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)XOAUTH2/i.test(str)) this._supportedAuth.push("XOAUTH2");
			if (match = str.match(/[ -]SIZE(?:[ \t]+(\d+))?/im)) {
				this._supportedExtensions.push("SIZE");
				this._maxAllowedSize = Number(match[1]) || 0;
			}
			this.emit("connect");
		}
		/**
		* Handles server response for HELO command. If it yielded in
		* error, emit 'error', otherwise move into the authentication phase.
		*
		* @param {String} str Message from the server
		*/
		_actionHELO(str) {
			if (str.charAt(0) !== "2") {
				this._onError(/* @__PURE__ */ new Error("Invalid HELO. response=" + str), "EPROTOCOL", str, "HELO");
				return;
			}
			this.allowsAuth = true;
			this.emit("connect");
		}
		/**
		* Handles server response for STARTTLS command. If there's an error
		* try HELO instead, otherwise initiate TLS upgrade. If the upgrade
		* succeedes restart the EHLO
		*
		* @param {String} str Message from the server
		*/
		_actionSTARTTLS(str) {
			if (str.charAt(0) !== "2") {
				if (this.options.opportunisticTLS) {
					this.logger.info({ tnx: "smtp" }, "Failed STARTTLS upgrade, continuing unencrypted");
					return this.emit("connect");
				}
				this._onError(/* @__PURE__ */ new Error("Error upgrading connection with STARTTLS"), "ETLS", str, "STARTTLS");
				return;
			}
			this._upgradeConnection((err, secured) => {
				if (err) {
					this._onError(/* @__PURE__ */ new Error("Error initiating TLS - " + (err.message || err)), "ETLS", false, "STARTTLS");
					return;
				}
				this.logger.info({ tnx: "smtp" }, "Connection upgraded with STARTTLS");
				if (secured) if (this.options.lmtp) {
					this._responseActions.push(this._actionLHLO);
					this._sendCommand("LHLO " + this.name);
				} else {
					this._responseActions.push(this._actionEHLO);
					this._sendCommand("EHLO " + this.name);
				}
				else this.emit("connect");
			});
		}
		/**
		* Handle the response for AUTH LOGIN command. We are expecting
		* '334 VXNlcm5hbWU6' (base64 for 'Username:'). Data to be sent as
		* response needs to be base64 encoded username. We do not need
		* exact match but settle with 334 response in general as some
		* hosts invalidly use a longer message than VXNlcm5hbWU6
		*
		* @param {String} str Message from the server
		*/
		_actionAUTH_LOGIN_USER(str, callback) {
			if (!/^334[ -]/.test(str)) {
				callback(this._formatError("Invalid login sequence while waiting for \"334 VXNlcm5hbWU6\"", "EAUTH", str, "AUTH LOGIN"));
				return;
			}
			this._responseActions.push((str) => {
				this._actionAUTH_LOGIN_PASS(str, callback);
			});
			this._sendCommand(Buffer.from(this._auth.credentials.user + "", "utf-8").toString("base64"));
		}
		/**
		* Handle the response for AUTH CRAM-MD5 command. We are expecting
		* '334 <challenge string>'. Data to be sent as response needs to be
		* base64 decoded challenge string, MD5 hashed using the password as
		* a HMAC key, prefixed by the username and a space, and finally all
		* base64 encoded again.
		*
		* @param {String} str Message from the server
		*/
		_actionAUTH_CRAM_MD5(str, callback) {
			const challengeMatch = str.match(/^334\s+(.+)$/);
			if (!challengeMatch) return callback(this._formatError("Invalid login sequence while waiting for server challenge string", "EAUTH", str, "AUTH CRAM-MD5"));
			const base64decoded = Buffer.from(challengeMatch[1], "base64").toString("ascii");
			const hmacMD5 = crypto$3.createHmac("md5", this._auth.credentials.pass);
			hmacMD5.update(base64decoded);
			const prepended = this._auth.credentials.user + " " + hmacMD5.digest("hex");
			this._responseActions.push((str) => {
				this._actionAUTH_CRAM_MD5_PASS(str, callback);
			});
			this._sendCommand(Buffer.from(prepended).toString("base64"), Buffer.from(this._auth.credentials.user + " /* secret */").toString("base64"));
		}
		/**
		* Handles the response to CRAM-MD5 authentication, if there's no error,
		* the user can be considered logged in. Start waiting for a message to send
		*
		* @param {String} str Message from the server
		*/
		_actionAUTH_CRAM_MD5_PASS(str, callback) {
			if (!str.match(/^235\s+/)) return callback(this._formatError("Invalid login sequence while waiting for \"235\"", "EAUTH", str, "AUTH CRAM-MD5"));
			this.logger.info({
				tnx: "smtp",
				username: this._auth.user,
				action: "authenticated",
				method: this._authMethod
			}, "User %s authenticated", JSON.stringify(this._auth.user));
			this.authenticated = true;
			callback(null, true);
		}
		/**
		* Handle the response for AUTH LOGIN command. We are expecting
		* '334 UGFzc3dvcmQ6' (base64 for 'Password:'). Data to be sent as
		* response needs to be base64 encoded password.
		*
		* @param {String} str Message from the server
		*/
		_actionAUTH_LOGIN_PASS(str, callback) {
			if (!/^334[ -]/.test(str)) return callback(this._formatError("Invalid login sequence while waiting for \"334 UGFzc3dvcmQ6\"", "EAUTH", str, "AUTH LOGIN"));
			this._responseActions.push((str) => {
				this._actionAUTHComplete(str, callback);
			});
			this._sendCommand(Buffer.from((this._auth.credentials.pass || "").toString(), "utf-8").toString("base64"), Buffer.from("/* secret */", "utf-8").toString("base64"));
		}
		/**
		* Handles the response for authentication, if there's no error,
		* the user can be considered logged in. Start waiting for a message to send
		*
		* @param {String} str Message from the server
		*/
		_actionAUTHComplete(str, isRetry, callback) {
			if (!callback && typeof isRetry === "function") {
				callback = isRetry;
				isRetry = false;
			}
			if (str.substr(0, 3) === "334") {
				this._responseActions.push((str) => {
					if (isRetry || this._authMethod !== "XOAUTH2") this._actionAUTHComplete(str, true, callback);
					else setImmediate(() => this._handleXOauth2Token(true, callback));
				});
				this._sendCommand("");
				return;
			}
			if (str.charAt(0) !== "2") {
				this.logger.info({
					tnx: "smtp",
					username: this._auth.user,
					action: "authfail",
					method: this._authMethod
				}, "User %s failed to authenticate", JSON.stringify(this._auth.user));
				return callback(this._formatError("Invalid login", "EAUTH", str, "AUTH " + this._authMethod));
			}
			this.logger.info({
				tnx: "smtp",
				username: this._auth.user,
				action: "authenticated",
				method: this._authMethod
			}, "User %s authenticated", JSON.stringify(this._auth.user));
			this.authenticated = true;
			callback(null, true);
		}
		/**
		* Handle response for a MAIL FROM: command
		*
		* @param {String} str Message from the server
		*/
		_actionMAIL(str, callback) {
			if (Number(str.charAt(0)) !== 2) {
				const message = this._usingSmtpUtf8 && /^550 /.test(str) && /[\x80-\uFFFF]/.test(this._envelope.from) ? "Internationalized mailbox name not allowed" : "Mail command failed";
				return callback(this._formatError(message, "EENVELOPE", str, "MAIL FROM"));
			}
			if (!this._envelope.rcptQueue.length) return callback(this._formatError("Can't send mail - no recipients defined", "EENVELOPE", false, "API"));
			this._recipientQueue = [];
			const usePipelining = this._supportedExtensions.includes("PIPELINING");
			do {
				const curRecipient = this._envelope.rcptQueue.shift();
				this._recipientQueue.push(curRecipient);
				this._responseActions.push((str) => {
					this._actionRCPT(str, callback);
				});
				this._sendCommand("RCPT TO:<" + curRecipient + ">" + this._getDsnRcptToArgs());
			} while (usePipelining && this._envelope.rcptQueue.length);
		}
		/**
		* Handle response for a RCPT TO: command
		*
		* @param {String} str Message from the server
		*/
		_actionRCPT(str, callback) {
			let err;
			const curRecipient = this._recipientQueue.shift();
			if (Number(str.charAt(0)) !== 2) {
				const message = this._usingSmtpUtf8 && /^553 /.test(str) && /[\x80-\uFFFF]/.test(curRecipient) ? "Internationalized mailbox name not allowed" : "Recipient command failed";
				this._envelope.rejected.push(curRecipient);
				err = this._formatError(message, "EENVELOPE", str, "RCPT TO");
				err.recipient = curRecipient;
				this._envelope.rejectedErrors.push(err);
			} else this._envelope.accepted.push(curRecipient);
			if (!this._envelope.rcptQueue.length && !this._recipientQueue.length) if (this._envelope.rejected.length < this._envelope.to.length) {
				this._responseActions.push((str) => {
					this._actionDATA(str, callback);
				});
				this._sendCommand("DATA");
			} else {
				err = this._formatError("Can't send mail - all recipients were rejected", "EENVELOPE", str, "RCPT TO");
				err.rejected = this._envelope.rejected;
				err.rejectedErrors = this._envelope.rejectedErrors;
				return callback(err);
			}
			else if (this._envelope.rcptQueue.length) {
				const nextRecipient = this._envelope.rcptQueue.shift();
				this._recipientQueue.push(nextRecipient);
				this._responseActions.push((str) => {
					this._actionRCPT(str, callback);
				});
				this._sendCommand("RCPT TO:<" + nextRecipient + ">" + this._getDsnRcptToArgs());
			}
		}
		/**
		* Handle response for a DATA command
		*
		* @param {String} str Message from the server
		*/
		_actionDATA(str, callback) {
			if (!/^[23]/.test(str)) return callback(this._formatError("Data command failed", "EENVELOPE", str, "DATA"));
			const response = {
				accepted: this._envelope.accepted,
				rejected: this._envelope.rejected
			};
			if (this._ehloLines && this._ehloLines.length) response.ehlo = this._ehloLines;
			if (this._envelope.rejectedErrors.length) response.rejectedErrors = this._envelope.rejectedErrors;
			callback(null, response);
		}
		/**
		* Handle response for a DATA stream when using SMTP
		* We expect a single response that defines if the sending succeeded or failed
		*
		* @param {String} str Message from the server
		*/
		_actionSMTPStream(str, callback) {
			if (Number(str.charAt(0)) !== 2) return callback(this._formatError("Message failed", "EMESSAGE", str, "DATA"));
			return callback(null, str);
		}
		/**
		* Handle response for a DATA stream
		* We expect a separate response for every recipient. All recipients can either
		* succeed or fail separately
		*
		* @param {String} recipient The recipient this response applies to
		* @param {Boolean} final Is this the final recipient?
		* @param {String} str Message from the server
		*/
		_actionLMTPStream(recipient, final, str, callback) {
			let err;
			if (Number(str.charAt(0)) !== 2) {
				err = this._formatError("Message failed for recipient " + recipient, "EMESSAGE", str, "DATA");
				err.recipient = recipient;
				this._envelope.rejected.push(recipient);
				this._envelope.rejectedErrors.push(err);
				for (let i = 0, len = this._envelope.accepted.length; i < len; i++) if (this._envelope.accepted[i] === recipient) this._envelope.accepted.splice(i, 1);
			}
			if (final) return callback(null, str);
		}
		_handleXOauth2Token(isRetry, callback) {
			this._auth.oauth2.getToken(isRetry, (err, accessToken) => {
				if (err) {
					this.logger.info({
						tnx: "smtp",
						username: this._auth.user,
						action: "authfail",
						method: this._authMethod
					}, "User %s failed to authenticate", JSON.stringify(this._auth.user));
					return callback(this._formatError(err, "EAUTH", false, "AUTH XOAUTH2"));
				}
				this._responseActions.push((str) => {
					this._actionAUTHComplete(str, isRetry, callback);
				});
				this._sendCommand("AUTH XOAUTH2 " + this._auth.oauth2.buildXOAuth2Token(accessToken), "AUTH XOAUTH2 " + this._auth.oauth2.buildXOAuth2Token("/* secret */"));
			});
		}
		/**
		*
		* @param {string} command
		* @private
		*/
		_isDestroyedMessage(command) {
			if (this._destroyed) return "Cannot " + command + " - smtp connection is already destroyed.";
			if (this._socket) {
				if (this._socket.destroyed) return "Cannot " + command + " - smtp connection socket is already destroyed.";
				if (!this._socket.writable) return "Cannot " + command + " - smtp connection socket is already half-closed.";
			}
		}
		_getHostname() {
			let defaultHostname;
			try {
				defaultHostname = os$1.hostname() || "";
			} catch (_err) {
				defaultHostname = "localhost";
			}
			if (!defaultHostname || defaultHostname.indexOf(".") < 0) defaultHostname = "[127.0.0.1]";
			if (defaultHostname.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) defaultHostname = "[" + defaultHostname + "]";
			return defaultHostname;
		}
	};
	module.exports = SMTPConnection;
}));
//#endregion
//#region node_modules/nodemailer/lib/xoauth2/index.js
var require_xoauth2 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { Stream: Stream$3 } = __require("stream");
	var nmfetch = require_fetch();
	var crypto$2 = __require("crypto");
	var shared = require_shared();
	var errors = require_errors();
	/**
	* XOAUTH2 access_token generator for Gmail.
	* Create client ID for web applications in Google API console to use it.
	* See Offline Access for receiving the needed refreshToken for an user
	* https://developers.google.com/accounts/docs/OAuth2WebServer#offline
	*
	* Usage for generating access tokens with a custom method using provisionCallback:
	* provisionCallback(user, renew, callback)
	*   * user is the username to get the token for
	*   * renew is a boolean that if true indicates that existing token failed and needs to be renewed
	*   * callback is the callback to run with (error, accessToken [, expires])
	*     * accessToken is a string
	*     * expires is an optional expire time in milliseconds
	* If provisionCallback is used, then Nodemailer does not try to attempt generating the token by itself
	*
	* @constructor
	* @param {Object} options Client information for token generation
	* @param {String} options.user User e-mail address
	* @param {String} options.clientId Client ID value
	* @param {String} options.clientSecret Client secret value
	* @param {String} options.refreshToken Refresh token for an user
	* @param {String} options.accessUrl Endpoint for token generation, defaults to 'https://accounts.google.com/o/oauth2/token'
	* @param {String} options.accessToken An existing valid accessToken
	* @param {String} options.privateKey Private key for JSW
	* @param {Number} options.expires Optional Access Token expire time in ms
	* @param {Number} options.timeout Optional TTL for Access Token in seconds
	* @param {Function} options.provisionCallback Function to run when a new access token is required
	* @param {Object} options.tls Optional TLS options forwarded to the HTTPS token request. Defaults to strict cert validation; supply { rejectUnauthorized: false } only for self-hosted OAuth providers on private CAs.
	*/
	var XOAuth2 = class extends Stream$3 {
		constructor(options, logger) {
			super();
			this.options = options || {};
			if (options && options.serviceClient) {
				if (!options.privateKey || !options.user) {
					const err = /* @__PURE__ */ new Error("Options \"privateKey\" and \"user\" are required for service account!");
					err.code = errors.EOAUTH2;
					setImmediate(() => this.emit("error", err));
					return;
				}
				const serviceRequestTimeout = Math.min(Math.max(Number(this.options.serviceRequestTimeout) || 0, 0), 3600);
				this.options.serviceRequestTimeout = serviceRequestTimeout || 300;
			}
			this.logger = shared.getLogger({ logger }, { component: this.options.component || "OAuth2" });
			this.provisionCallback = typeof this.options.provisionCallback === "function" ? this.options.provisionCallback : false;
			this.options.accessUrl = this.options.accessUrl || "https://accounts.google.com/o/oauth2/token";
			this.options.customHeaders = this.options.customHeaders || {};
			this.options.customParams = this.options.customParams || {};
			this.accessToken = this.options.accessToken || false;
			if (this.options.expires && Number(this.options.expires)) this.expires = this.options.expires;
			else {
				const timeout = Math.max(Number(this.options.timeout) || 0, 0);
				this.expires = timeout && Date.now() + timeout * 1e3 || 0;
			}
			this.renewing = false;
			this.renewalQueue = [];
		}
		/**
		* Returns or generates (if previous has expired) a XOAuth2 token
		*
		* @param {Boolean} renew If false then use cached access token (if available)
		* @param {Function} callback Callback function with error object and token string
		*/
		getToken(renew, callback) {
			if (!renew && this.accessToken && (!this.expires || this.expires > Date.now())) {
				this.logger.debug({
					tnx: "OAUTH2",
					user: this.options.user,
					action: "reuse"
				}, "Reusing existing access token for %s", this.options.user);
				return callback(null, this.accessToken);
			}
			if (!this.provisionCallback && !this.options.refreshToken && !this.options.serviceClient) {
				if (this.accessToken) {
					this.logger.debug({
						tnx: "OAUTH2",
						user: this.options.user,
						action: "reuse"
					}, "Reusing existing access token (no refresh capability) for %s", this.options.user);
					return callback(null, this.accessToken);
				}
				this.logger.error({
					tnx: "OAUTH2",
					user: this.options.user,
					action: "renew"
				}, "Cannot renew access token for %s: No refresh mechanism available", this.options.user);
				const err = /* @__PURE__ */ new Error("Can't create new access token for user");
				err.code = errors.EOAUTH2;
				return callback(err);
			}
			if (this.renewing) return this.renewalQueue.push({
				renew,
				callback
			});
			this.renewing = true;
			const generateCallback = (err, accessToken) => {
				this.renewalQueue.forEach((item) => item.callback(err, accessToken));
				this.renewalQueue = [];
				this.renewing = false;
				if (err) this.logger.error({
					err,
					tnx: "OAUTH2",
					user: this.options.user,
					action: "renew"
				}, "Failed generating new Access Token for %s", this.options.user);
				else this.logger.info({
					tnx: "OAUTH2",
					user: this.options.user,
					action: "renew"
				}, "Generated new Access Token for %s", this.options.user);
				callback(err, accessToken);
			};
			if (this.provisionCallback) this.provisionCallback(this.options.user, !!renew, (err, accessToken, expires) => {
				if (!err && accessToken) {
					this.accessToken = accessToken;
					this.expires = expires || 0;
				}
				generateCallback(err, accessToken);
			});
			else this.generateToken(generateCallback);
		}
		/**
		* Updates token values
		*
		* @param {String} accessToken New access token
		* @param {Number} timeout Access token lifetime in seconds
		*
		* Emits 'token': { user: User email-address, accessToken: the new accessToken, timeout: TTL in seconds}
		*/
		updateToken(accessToken, timeout) {
			this.accessToken = accessToken;
			timeout = Math.max(Number(timeout) || 0, 0);
			this.expires = timeout && Date.now() + timeout * 1e3 || 0;
			this.emit("token", {
				user: this.options.user,
				accessToken: accessToken || "",
				expires: this.expires
			});
		}
		/**
		* Generates a new XOAuth2 token with the credentials provided at initialization
		*
		* @param {Function} callback Callback function with error object and token string
		*/
		generateToken(callback) {
			let urlOptions;
			let loggedUrlOptions;
			if (this.options.serviceClient) {
				const iat = Math.floor(Date.now() / 1e3);
				const tokenData = {
					iss: this.options.serviceClient,
					scope: this.options.scope || "https://mail.google.com/",
					sub: this.options.user,
					aud: this.options.accessUrl,
					iat,
					exp: iat + this.options.serviceRequestTimeout
				};
				let token;
				try {
					token = this.jwtSignRS256(tokenData);
				} catch (_err) {
					const err = /* @__PURE__ */ new Error("Can't generate token. Check your auth options");
					err.code = errors.EOAUTH2;
					return callback(err);
				}
				urlOptions = {
					grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
					assertion: token
				};
				loggedUrlOptions = {
					grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
					assertion: tokenData
				};
			} else {
				if (!this.options.refreshToken) {
					const err = /* @__PURE__ */ new Error("Can't create new access token for user");
					err.code = errors.EOAUTH2;
					return callback(err);
				}
				urlOptions = {
					client_id: this.options.clientId || "",
					client_secret: this.options.clientSecret || "",
					refresh_token: this.options.refreshToken,
					grant_type: "refresh_token"
				};
				loggedUrlOptions = {
					client_id: this.options.clientId || "",
					client_secret: (this.options.clientSecret || "").substr(0, 6) + "...",
					refresh_token: (this.options.refreshToken || "").substr(0, 6) + "...",
					grant_type: "refresh_token"
				};
			}
			Object.assign(urlOptions, this.options.customParams);
			Object.assign(loggedUrlOptions, this.options.customParams);
			this.logger.debug({
				tnx: "OAUTH2",
				user: this.options.user,
				action: "generate"
			}, "Requesting token using: %s", JSON.stringify(loggedUrlOptions));
			this.postRequest(this.options.accessUrl, urlOptions, this.options, (error, body) => {
				let data;
				if (error) return callback(error);
				try {
					data = JSON.parse(body.toString());
				} catch (E) {
					return callback(E);
				}
				if (!data || typeof data !== "object") {
					this.logger.debug({
						tnx: "OAUTH2",
						user: this.options.user,
						action: "post"
					}, "Response: %s", (body || "").toString());
					const err = /* @__PURE__ */ new Error("Invalid authentication response");
					err.code = errors.EOAUTH2;
					return callback(err);
				}
				const logData = Object.assign({}, data);
				if (logData.access_token) logData.access_token = (logData.access_token || "").toString().substr(0, 6) + "...";
				this.logger.debug({
					tnx: "OAUTH2",
					user: this.options.user,
					action: "post"
				}, "Response: %s", JSON.stringify(logData));
				if (data.error) {
					let errorMessage = data.error;
					if (data.error_description) errorMessage += ": " + data.error_description;
					if (data.error_uri) errorMessage += " (" + data.error_uri + ")";
					const err = new Error(errorMessage);
					err.code = errors.EOAUTH2;
					return callback(err);
				}
				if (data.access_token) {
					this.updateToken(data.access_token, data.expires_in);
					return callback(null, this.accessToken);
				}
				const err = /* @__PURE__ */ new Error("No access token");
				err.code = errors.EOAUTH2;
				return callback(err);
			});
		}
		/**
		* Converts an access_token and user id into a base64 encoded XOAuth2 token
		*
		* @param {String} [accessToken] Access token string
		* @return {String} Base64 encoded token for IMAP or SMTP login
		*/
		buildXOAuth2Token(accessToken) {
			const authData = [
				"user=" + (this.options.user || ""),
				"auth=Bearer " + (accessToken || this.accessToken),
				"",
				""
			];
			return Buffer.from(authData.join(""), "utf-8").toString("base64");
		}
		/**
		* Custom POST request handler.
		* This is only needed to keep paths short in Windows – usually this module
		* is a dependency of a dependency and if it tries to require something
		* like the request module the paths get way too long to handle for Windows.
		* As we do only a simple POST request we do not actually require complicated
		* logic support (no redirects, no nothing) anyway.
		*
		* @param {String} url Url to POST to
		* @param {String|Buffer} payload Payload to POST
		* @param {Function} callback Callback function with (err, buff)
		*/
		postRequest(url, payload, params, callback) {
			let returned = false;
			const chunks = [];
			let chunklen = 0;
			const fetchOptions = {
				method: "post",
				headers: params.customHeaders,
				body: payload,
				allowErrorResponse: true
			};
			if (/^https:/i.test(url)) fetchOptions.tls = Object.assign({ rejectUnauthorized: true }, params.tls || {});
			const req = nmfetch(url, fetchOptions);
			req.on("readable", () => {
				let chunk;
				while ((chunk = req.read()) !== null) {
					chunks.push(chunk);
					chunklen += chunk.length;
				}
			});
			req.once("error", (err) => {
				if (returned) return;
				returned = true;
				return callback(err);
			});
			req.once("end", () => {
				if (returned) return;
				returned = true;
				return callback(null, Buffer.concat(chunks, chunklen));
			});
		}
		/**
		* Encodes a buffer or a string into Base64url format
		*
		* @param {Buffer|String} data The data to convert
		* @return {String} The encoded string
		*/
		toBase64URL(data) {
			if (typeof data === "string") data = Buffer.from(data);
			return data.toString("base64").replace(/[=]+/g, "").replace(/\+/g, "-").replace(/\//g, "_");
		}
		/**
		* Creates a JSON Web Token signed with RS256 (SHA256 + RSA)
		*
		* @param {Object} payload The payload to include in the generated token
		* @return {String} The generated and signed token
		*/
		jwtSignRS256(payload) {
			payload = ["{\"alg\":\"RS256\",\"typ\":\"JWT\"}", JSON.stringify(payload)].map((val) => this.toBase64URL(val)).join(".");
			const signature = crypto$2.createSign("RSA-SHA256").update(payload).sign(this.options.privateKey);
			return payload + "." + this.toBase64URL(signature);
		}
	};
	module.exports = XOAuth2;
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-pool/pool-resource.js
var require_pool_resource = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var SMTPConnection = require_smtp_connection();
	var assign = require_shared().assign;
	var XOAuth2 = require_xoauth2();
	var errors = require_errors();
	var EventEmitter$4 = __require("events");
	/**
	* Creates an element for the pool
	*
	* @constructor
	* @param {Object} options SMTPPool instance
	*/
	var PoolResource = class extends EventEmitter$4 {
		constructor(pool) {
			super();
			this.pool = pool;
			this.options = pool.options;
			this.logger = this.pool.logger;
			if (this.options.auth) switch ((this.options.auth.type || "").toString().toUpperCase()) {
				case "OAUTH2": {
					const oauth2 = new XOAuth2(this.options.auth, this.logger);
					oauth2.provisionCallback = this.pool.mailer && this.pool.mailer.get("oauth2_provision_cb") || oauth2.provisionCallback;
					this.auth = {
						type: "OAUTH2",
						user: this.options.auth.user,
						oauth2,
						method: "XOAUTH2"
					};
					oauth2.on("token", (token) => this.pool.mailer.emit("token", token));
					oauth2.on("error", (err) => this.emit("error", err));
					break;
				}
				default:
					if (!this.options.auth.user && !this.options.auth.pass) break;
					this.auth = {
						type: (this.options.auth.type || "").toString().toUpperCase() || "LOGIN",
						user: this.options.auth.user,
						credentials: {
							user: this.options.auth.user || "",
							pass: this.options.auth.pass,
							options: this.options.auth.options
						},
						method: (this.options.auth.method || "").trim().toUpperCase() || this.options.authMethod || false
					};
			}
			this._connection = false;
			this._connected = false;
			this.messages = 0;
			this.available = true;
		}
		/**
		* Initiates a connection to the SMTP server
		*
		* @param {Function} callback Callback function to run once the connection is established or failed
		*/
		connect(callback) {
			this.pool.getSocket(this.options, (err, socketOptions) => {
				if (err) return callback(err);
				let returned = false;
				let options = this.options;
				if (socketOptions && socketOptions.connection) {
					this.logger.info({
						tnx: "proxy",
						remoteAddress: socketOptions.connection.remoteAddress,
						remotePort: socketOptions.connection.remotePort,
						destHost: options.host || "",
						destPort: options.port || "",
						action: "connected"
					}, "Using proxied socket from %s:%s to %s:%s", socketOptions.connection.remoteAddress, socketOptions.connection.remotePort, options.host || "", options.port || "");
					options = Object.assign(assign(false, options), socketOptions);
				}
				this.connection = new SMTPConnection(options);
				this.connection.once("error", (err) => {
					this.emit("error", err);
					if (returned) return;
					returned = true;
					return callback(err);
				});
				this.connection.once("end", () => {
					this.close();
					if (returned) return;
					returned = true;
					const timer = setTimeout(() => {
						if (returned) return;
						const err = /* @__PURE__ */ new Error("Unexpected socket close");
						if (this.connection && this.connection._socket && this.connection._socket.upgrading) err.code = errors.ETLS;
						callback(err);
					}, 1e3);
					try {
						timer.unref();
					} catch (_E) {}
				});
				this.connection.connect(() => {
					if (returned) return;
					if (this.auth && (this.connection.allowsAuth || options.forceAuth)) this.connection.login(this.auth, (err) => {
						if (returned) return;
						returned = true;
						if (err) {
							this.connection.close();
							this.emit("error", err);
							return callback(err);
						}
						this._connected = true;
						callback(null, true);
					});
					else {
						returned = true;
						this._connected = true;
						return callback(null, true);
					}
				});
			});
		}
		/**
		* Sends an e-mail to be sent using the selected settings
		*
		* @param {Object} mail Mail object
		* @param {Function} callback Callback function
		*/
		send(mail, callback) {
			if (!this._connected) return this.connect((err) => {
				if (err) return callback(err);
				return this.send(mail, callback);
			});
			const envelope = mail.message.getEnvelope();
			const messageId = mail.message.messageId();
			const recipients = [].concat(envelope.to || []);
			if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
			this.logger.info({
				tnx: "send",
				messageId,
				cid: this.id
			}, "Sending message %s using #%s to <%s>", messageId, this.id, recipients.join(", "));
			if (mail.data.dsn) envelope.dsn = mail.data.dsn;
			if (mail.data.requireTLSExtensionEnabled) envelope.requireTLSExtensionEnabled = mail.data.requireTLSExtensionEnabled;
			this.connection.send(envelope, mail.message.createReadStream(), (err, info) => {
				this.messages++;
				if (err) {
					this.connection.close();
					this.emit("error", err);
					return callback(err);
				}
				info.envelope = {
					from: envelope.from,
					to: envelope.to
				};
				info.messageId = messageId;
				setImmediate(() => {
					if (this.messages >= this.options.maxMessages) {
						const err = /* @__PURE__ */ new Error("Resource exhausted");
						err.code = errors.EMAXLIMIT;
						this.connection.close();
						this.emit("error", err);
					} else this.pool._checkRateLimit(() => {
						this.available = true;
						this.emit("available");
					});
				});
				callback(null, info);
			});
		}
		/**
		* Closes the connection
		*/
		close() {
			this._connected = false;
			if (this.auth && this.auth.oauth2) this.auth.oauth2.removeAllListeners();
			if (this.connection) this.connection.close();
			this.emit("close");
		}
	};
	module.exports = PoolResource;
}));
//#endregion
//#region node_modules/nodemailer/lib/well-known/services.json
var services_exports = /* @__PURE__ */ __exportAll({
	AOL: () => AOL,
	Aliyun: () => Aliyun,
	AliyunQiye: () => AliyunQiye,
	Aruba: () => Aruba,
	BOL: () => BOL,
	Bluewin: () => Bluewin,
	DebugMail: () => DebugMail,
	Disroot: () => Disroot,
	DynectEmail: () => DynectEmail,
	ElasticEmail: () => ElasticEmail,
	Ethereal: () => Ethereal,
	FastMail: () => FastMail,
	GMX: () => GMX,
	GandiMail: () => GandiMail,
	Gmail: () => Gmail,
	GmailWorkspace: () => GmailWorkspace,
	Godaddy: () => Godaddy,
	GodaddyAsia: () => GodaddyAsia,
	GodaddyEurope: () => GodaddyEurope,
	Hotmail: () => Hotmail,
	Infomaniak: () => Infomaniak,
	KolabNow: () => KolabNow,
	Loopia: () => Loopia,
	Loops: () => Loops,
	Maildev: () => Maildev,
	MailerSend: () => MailerSend,
	Mailgun: () => Mailgun,
	Mailjet: () => Mailjet,
	Mailosaur: () => Mailosaur,
	Mailtrap: () => Mailtrap,
	Mandrill: () => Mandrill,
	Naver: () => Naver,
	OhMySMTP: () => OhMySMTP,
	One: () => One,
	OpenMailBox: () => OpenMailBox,
	Outlook365: () => Outlook365,
	Postmark: () => Postmark,
	Proton: () => Proton,
	QQ: () => QQ,
	QQex: () => QQex,
	Resend: () => Resend,
	Runbox: () => Runbox,
	SES: () => SES,
	SMTP2GO: () => SMTP2GO,
	SendCloud: () => SendCloud,
	SendGrid: () => SendGrid,
	SendPulse: () => SendPulse,
	SendinBlue: () => SendinBlue,
	Seznam: () => Seznam,
	Sparkpost: () => Sparkpost,
	Tipimail: () => Tipimail,
	Tutanota: () => Tutanota,
	Yahoo: () => Yahoo,
	Yandex: () => Yandex,
	Zimbra: () => Zimbra,
	Zoho: () => Zoho,
	default: () => services_default,
	iCloud: () => iCloud
});
var Aliyun, AliyunQiye, AOL, Aruba, Bluewin, BOL, DebugMail, Disroot, DynectEmail, ElasticEmail, Ethereal, FastMail, GandiMail, Gmail, GmailWorkspace, GMX, Godaddy, GodaddyAsia, GodaddyEurope, Hotmail, iCloud, Infomaniak, KolabNow, Loopia, Loops, Maildev, MailerSend, Mailgun, Mailjet, Mailosaur, Mailtrap, Mandrill, Naver, OhMySMTP, One, OpenMailBox, Outlook365, Postmark, Proton, QQ, QQex, Resend, Runbox, SendCloud, SendGrid, SendinBlue, SendPulse, SES, Seznam, SMTP2GO, Sparkpost, Tipimail, Tutanota, Yahoo, Yandex, Zimbra, Zoho, services_default;
var init_services = __esmMin((() => {
	Aliyun = {
		"description": "Alibaba Cloud Mail",
		"domains": ["aliyun.com"],
		"host": "smtp.aliyun.com",
		"port": 465,
		"secure": true
	};
	AliyunQiye = {
		"description": "Alibaba Cloud Enterprise Mail",
		"host": "smtp.qiye.aliyun.com",
		"port": 465,
		"secure": true
	};
	AOL = {
		"description": "AOL Mail",
		"domains": ["aol.com"],
		"host": "smtp.aol.com",
		"port": 587
	};
	Aruba = {
		"description": "Aruba PEC (Italian email provider)",
		"domains": ["aruba.it", "pec.aruba.it"],
		"aliases": ["Aruba PEC"],
		"host": "smtps.aruba.it",
		"port": 465,
		"secure": true,
		"authMethod": "LOGIN"
	};
	Bluewin = {
		"description": "Bluewin (Swiss email provider)",
		"host": "smtpauths.bluewin.ch",
		"domains": ["bluewin.ch"],
		"port": 465
	};
	BOL = {
		"description": "BOL Mail (Brazilian provider)",
		"domains": ["bol.com.br"],
		"host": "smtp.bol.com.br",
		"port": 587,
		"requireTLS": true
	};
	DebugMail = {
		"description": "DebugMail (email testing service)",
		"host": "debugmail.io",
		"port": 25
	};
	Disroot = {
		"description": "Disroot (privacy-focused provider)",
		"domains": ["disroot.org"],
		"host": "disroot.org",
		"port": 587,
		"secure": false,
		"authMethod": "LOGIN"
	};
	DynectEmail = {
		"description": "Dyn Email Delivery",
		"aliases": ["Dynect"],
		"host": "smtp.dynect.net",
		"port": 25
	};
	ElasticEmail = {
		"description": "Elastic Email",
		"aliases": ["Elastic Email"],
		"host": "smtp.elasticemail.com",
		"port": 465,
		"secure": true
	};
	Ethereal = {
		"description": "Ethereal Email (email testing service)",
		"aliases": ["ethereal.email"],
		"host": "smtp.ethereal.email",
		"port": 587
	};
	FastMail = {
		"description": "FastMail",
		"domains": ["fastmail.fm"],
		"host": "smtp.fastmail.com",
		"port": 465,
		"secure": true
	};
	GandiMail = {
		"description": "Gandi Mail",
		"aliases": ["Gandi", "Gandi Mail"],
		"host": "mail.gandi.net",
		"port": 587
	};
	Gmail = {
		"description": "Gmail",
		"aliases": ["Google Mail"],
		"domains": ["gmail.com", "googlemail.com"],
		"host": "smtp.gmail.com",
		"port": 465,
		"secure": true
	};
	GmailWorkspace = {
		"description": "Gmail Workspace",
		"aliases": ["Google Workspace Mail"],
		"host": "smtp-relay.gmail.com",
		"port": 465,
		"secure": true
	};
	GMX = {
		"description": "GMX Mail",
		"domains": [
			"gmx.com",
			"gmx.net",
			"gmx.de"
		],
		"host": "mail.gmx.com",
		"port": 587
	};
	Godaddy = {
		"description": "GoDaddy Email (US)",
		"host": "smtpout.secureserver.net",
		"port": 25
	};
	GodaddyAsia = {
		"description": "GoDaddy Email (Asia)",
		"host": "smtp.asia.secureserver.net",
		"port": 25
	};
	GodaddyEurope = {
		"description": "GoDaddy Email (Europe)",
		"host": "smtp.europe.secureserver.net",
		"port": 25
	};
	Hotmail = {
		"description": "Outlook.com / Hotmail",
		"aliases": [
			"Outlook",
			"Outlook.com",
			"Hotmail.com"
		],
		"domains": ["hotmail.com", "outlook.com"],
		"host": "smtp-mail.outlook.com",
		"port": 587
	};
	iCloud = {
		"description": "iCloud Mail",
		"aliases": ["Me", "Mac"],
		"domains": ["me.com", "mac.com"],
		"host": "smtp.mail.me.com",
		"port": 587
	};
	Infomaniak = {
		"description": "Infomaniak Mail (Swiss hosting provider)",
		"host": "mail.infomaniak.com",
		"domains": [
			"ik.me",
			"ikmail.com",
			"etik.com"
		],
		"port": 587
	};
	KolabNow = {
		"description": "KolabNow (secure email service)",
		"domains": ["kolabnow.com"],
		"aliases": ["Kolab"],
		"host": "smtp.kolabnow.com",
		"port": 465,
		"secure": true,
		"authMethod": "LOGIN"
	};
	Loopia = {
		"description": "Loopia (Swedish hosting provider)",
		"host": "mailcluster.loopia.se",
		"port": 465
	};
	Loops = {
		"description": "Loops",
		"host": "smtp.loops.so",
		"port": 587
	};
	Maildev = {
		"description": "MailDev (local email testing)",
		"port": 1025,
		"ignoreTLS": true
	};
	MailerSend = {
		"description": "MailerSend",
		"host": "smtp.mailersend.net",
		"port": 587
	};
	Mailgun = {
		"description": "Mailgun",
		"host": "smtp.mailgun.org",
		"port": 465,
		"secure": true
	};
	Mailjet = {
		"description": "Mailjet",
		"host": "in.mailjet.com",
		"port": 587
	};
	Mailosaur = {
		"description": "Mailosaur (email testing service)",
		"host": "mailosaur.io",
		"port": 25
	};
	Mailtrap = {
		"description": "Mailtrap",
		"host": "live.smtp.mailtrap.io",
		"port": 587
	};
	Mandrill = {
		"description": "Mandrill (by Mailchimp)",
		"host": "smtp.mandrillapp.com",
		"port": 587
	};
	Naver = {
		"description": "Naver Mail (Korean email provider)",
		"host": "smtp.naver.com",
		"port": 587
	};
	OhMySMTP = {
		"description": "OhMySMTP (email delivery service)",
		"host": "smtp.ohmysmtp.com",
		"port": 587,
		"secure": false
	};
	One = {
		"description": "One.com Email",
		"host": "send.one.com",
		"port": 465,
		"secure": true
	};
	OpenMailBox = {
		"description": "OpenMailBox",
		"aliases": ["OMB", "openmailbox.org"],
		"host": "smtp.openmailbox.org",
		"port": 465,
		"secure": true
	};
	Outlook365 = {
		"description": "Microsoft 365 / Office 365",
		"host": "smtp.office365.com",
		"port": 587,
		"secure": false
	};
	Postmark = {
		"description": "Postmark",
		"aliases": ["PostmarkApp"],
		"host": "smtp.postmarkapp.com",
		"port": 2525
	};
	Proton = {
		"description": "Proton Mail",
		"aliases": [
			"ProtonMail",
			"Proton.me",
			"Protonmail.com",
			"Protonmail.ch"
		],
		"domains": [
			"proton.me",
			"protonmail.com",
			"pm.me",
			"protonmail.ch"
		],
		"host": "smtp.protonmail.ch",
		"port": 587,
		"requireTLS": true
	};
	QQ = {
		"description": "QQ Mail",
		"domains": ["qq.com"],
		"host": "smtp.qq.com",
		"port": 465,
		"secure": true
	};
	QQex = {
		"description": "QQ Enterprise Mail",
		"aliases": ["QQ Enterprise"],
		"domains": ["exmail.qq.com"],
		"host": "smtp.exmail.qq.com",
		"port": 465,
		"secure": true
	};
	Resend = {
		"description": "Resend",
		"host": "smtp.resend.com",
		"port": 465,
		"secure": true
	};
	Runbox = {
		"description": "Runbox (Norwegian email provider)",
		"domains": ["runbox.com"],
		"host": "smtp.runbox.com",
		"port": 465,
		"secure": true
	};
	SendCloud = {
		"description": "SendCloud (Chinese email delivery)",
		"host": "smtp.sendcloud.net",
		"port": 2525
	};
	SendGrid = {
		"description": "SendGrid",
		"host": "smtp.sendgrid.net",
		"port": 587
	};
	SendinBlue = {
		"description": "Brevo (formerly Sendinblue)",
		"aliases": ["Brevo"],
		"host": "smtp-relay.brevo.com",
		"port": 587
	};
	SendPulse = {
		"description": "SendPulse",
		"host": "smtp-pulse.com",
		"port": 465,
		"secure": true
	};
	SES = {
		"description": "AWS SES US East (N. Virginia)",
		"host": "email-smtp.us-east-1.amazonaws.com",
		"port": 465,
		"secure": true
	};
	Seznam = {
		"description": "Seznam Email (Czech email provider)",
		"aliases": ["Seznam Email"],
		"domains": [
			"seznam.cz",
			"email.cz",
			"post.cz",
			"spoluzaci.cz"
		],
		"host": "smtp.seznam.cz",
		"port": 465,
		"secure": true
	};
	SMTP2GO = {
		"description": "SMTP2GO",
		"host": "mail.smtp2go.com",
		"port": 2525
	};
	Sparkpost = {
		"description": "SparkPost",
		"aliases": ["SparkPost", "SparkPost Mail"],
		"domains": ["sparkpost.com"],
		"host": "smtp.sparkpostmail.com",
		"port": 587,
		"secure": false
	};
	Tipimail = {
		"description": "Tipimail (email delivery service)",
		"host": "smtp.tipimail.com",
		"port": 587
	};
	Tutanota = {
		"description": "Tutanota (Tuta Mail)",
		"domains": [
			"tutanota.com",
			"tuta.com",
			"tutanota.de",
			"tuta.io"
		],
		"host": "smtp.tutanota.com",
		"port": 465,
		"secure": true
	};
	Yahoo = {
		"description": "Yahoo Mail",
		"domains": ["yahoo.com"],
		"host": "smtp.mail.yahoo.com",
		"port": 465,
		"secure": true
	};
	Yandex = {
		"description": "Yandex Mail",
		"domains": ["yandex.ru"],
		"host": "smtp.yandex.ru",
		"port": 465,
		"secure": true
	};
	Zimbra = {
		"description": "Zimbra Mail Server",
		"aliases": ["Zimbra Collaboration"],
		"host": "smtp.zimbra.com",
		"port": 587,
		"requireTLS": true
	};
	Zoho = {
		"description": "Zoho Mail",
		"host": "smtp.zoho.com",
		"port": 465,
		"secure": true,
		"authMethod": "LOGIN"
	};
	services_default = {
		"1und1": {
			"description": "1&1 Mail (German hosting provider)",
			"host": "smtp.1und1.de",
			"port": 465,
			"secure": true,
			"authMethod": "LOGIN"
		},
		"126": {
			"description": "126 Mail (NetEase)",
			"host": "smtp.126.com",
			"port": 465,
			"secure": true
		},
		"163": {
			"description": "163 Mail (NetEase)",
			"host": "smtp.163.com",
			"port": 465,
			"secure": true
		},
		Aliyun,
		AliyunQiye,
		AOL,
		Aruba,
		Bluewin,
		BOL,
		DebugMail,
		Disroot,
		DynectEmail,
		ElasticEmail,
		Ethereal,
		FastMail,
		"Feishu Mail": {
			"description": "Feishu Mail (Lark)",
			"aliases": ["Feishu", "FeishuMail"],
			"domains": ["www.feishu.cn"],
			"host": "smtp.feishu.cn",
			"port": 465,
			"secure": true
		},
		"Forward Email": {
			"description": "Forward Email (email forwarding service)",
			"aliases": ["FE", "ForwardEmail"],
			"domains": ["forwardemail.net"],
			"host": "smtp.forwardemail.net",
			"port": 465,
			"secure": true
		},
		GandiMail,
		Gmail,
		GmailWorkspace,
		GMX,
		Godaddy,
		GodaddyAsia,
		GodaddyEurope,
		"hot.ee": {
			"description": "Hot.ee (Estonian email provider)",
			"host": "mail.hot.ee"
		},
		Hotmail,
		iCloud,
		Infomaniak,
		KolabNow,
		Loopia,
		Loops,
		"mail.ee": {
			"description": "Mail.ee (Estonian email provider)",
			"host": "smtp.mail.ee"
		},
		"Mail.ru": {
			"description": "Mail.ru",
			"host": "smtp.mail.ru",
			"port": 465,
			"secure": true
		},
		"Mailcatch.app": {
			"description": "Mailcatch (email testing service)",
			"host": "sandbox-smtp.mailcatch.app",
			"port": 2525
		},
		Maildev,
		MailerSend,
		Mailgun,
		Mailjet,
		Mailosaur,
		Mailtrap,
		Mandrill,
		Naver,
		OhMySMTP,
		One,
		OpenMailBox,
		Outlook365,
		Postmark,
		Proton,
		"qiye.aliyun": {
			"description": "Alibaba Mail Enterprise Edition",
			"host": "smtp.mxhichina.com",
			"port": "465",
			"secure": true
		},
		QQ,
		QQex,
		Resend,
		Runbox,
		SendCloud,
		SendGrid,
		SendinBlue,
		SendPulse,
		SES,
		"SES-AP-NORTHEAST-1": {
			"description": "AWS SES Asia Pacific (Tokyo)",
			"host": "email-smtp.ap-northeast-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-AP-NORTHEAST-2": {
			"description": "AWS SES Asia Pacific (Seoul)",
			"host": "email-smtp.ap-northeast-2.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-AP-NORTHEAST-3": {
			"description": "AWS SES Asia Pacific (Osaka)",
			"host": "email-smtp.ap-northeast-3.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-AP-SOUTH-1": {
			"description": "AWS SES Asia Pacific (Mumbai)",
			"host": "email-smtp.ap-south-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-AP-SOUTHEAST-1": {
			"description": "AWS SES Asia Pacific (Singapore)",
			"host": "email-smtp.ap-southeast-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-AP-SOUTHEAST-2": {
			"description": "AWS SES Asia Pacific (Sydney)",
			"host": "email-smtp.ap-southeast-2.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-CA-CENTRAL-1": {
			"description": "AWS SES Canada (Central)",
			"host": "email-smtp.ca-central-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-EU-CENTRAL-1": {
			"description": "AWS SES Europe (Frankfurt)",
			"host": "email-smtp.eu-central-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-EU-NORTH-1": {
			"description": "AWS SES Europe (Stockholm)",
			"host": "email-smtp.eu-north-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-EU-WEST-1": {
			"description": "AWS SES Europe (Ireland)",
			"host": "email-smtp.eu-west-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-EU-WEST-2": {
			"description": "AWS SES Europe (London)",
			"host": "email-smtp.eu-west-2.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-EU-WEST-3": {
			"description": "AWS SES Europe (Paris)",
			"host": "email-smtp.eu-west-3.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-SA-EAST-1": {
			"description": "AWS SES South America (São Paulo)",
			"host": "email-smtp.sa-east-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-EAST-1": {
			"description": "AWS SES US East (N. Virginia)",
			"host": "email-smtp.us-east-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-EAST-2": {
			"description": "AWS SES US East (Ohio)",
			"host": "email-smtp.us-east-2.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-GOV-EAST-1": {
			"description": "AWS SES GovCloud (US-East)",
			"host": "email-smtp.us-gov-east-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-GOV-WEST-1": {
			"description": "AWS SES GovCloud (US-West)",
			"host": "email-smtp.us-gov-west-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-WEST-1": {
			"description": "AWS SES US West (N. California)",
			"host": "email-smtp.us-west-1.amazonaws.com",
			"port": 465,
			"secure": true
		},
		"SES-US-WEST-2": {
			"description": "AWS SES US West (Oregon)",
			"host": "email-smtp.us-west-2.amazonaws.com",
			"port": 465,
			"secure": true
		},
		Seznam,
		SMTP2GO,
		Sparkpost,
		Tipimail,
		Tutanota,
		Yahoo,
		Yandex,
		Zimbra,
		Zoho
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/well-known/index.js
var require_well_known = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var services = (init_services(), __toCommonJS(services_exports).default);
	var normalized = {};
	Object.keys(services).forEach((key) => {
		const service = services[key];
		const normalizedService = normalizeService(service);
		normalized[normalizeKey(key)] = normalizedService;
		[].concat(service.aliases || []).forEach((alias) => {
			normalized[normalizeKey(alias)] = normalizedService;
		});
		[].concat(service.domains || []).forEach((domain) => {
			normalized[normalizeKey(domain)] = normalizedService;
		});
	});
	function normalizeKey(key) {
		return key.replace(/[^a-zA-Z0-9.-]/g, "").toLowerCase();
	}
	function normalizeService(service) {
		const response = {};
		Object.keys(service).forEach((key) => {
			if (!["domains", "aliases"].includes(key)) response[key] = service[key];
		});
		return response;
	}
	/**
	* Resolves SMTP config for given key. Key can be a name (like 'Gmail'), alias (like 'Google Mail') or
	* an email address (like 'test@googlemail.com').
	*
	* @param {String} key [description]
	* @returns {Object} SMTP config or false if not found
	*/
	module.exports = function(key) {
		key = normalizeKey(key.split("@").pop());
		return normalized[key] || false;
	};
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-pool/index.js
var require_smtp_pool = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var EventEmitter$3 = __require("events");
	var PoolResource = require_pool_resource();
	var SMTPConnection = require_smtp_connection();
	var wellKnown = require_well_known();
	var shared = require_shared();
	var errors = require_errors();
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	/**
	* Creates a SMTP pool transport object for Nodemailer
	*
	* @constructor
	* @param {Object} options SMTP Connection options
	*/
	var SMTPPool = class extends EventEmitter$3 {
		constructor(options) {
			super();
			options = options || {};
			if (typeof options === "string") options = { url: options };
			let urlData;
			let service = options.service;
			if (typeof options.getSocket === "function") this.getSocket = options.getSocket;
			if (options.url) {
				urlData = shared.parseConnectionUrl(options.url);
				service = service || urlData.service;
			}
			this.options = shared.assign(false, options, urlData, service && wellKnown(service));
			this.options.maxConnections = this.options.maxConnections || 5;
			this.options.maxMessages = this.options.maxMessages || 100;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "smtp-pool" });
			this.name = "SMTP (pool)";
			this.version = packageData.version + "[client:" + packageData.version + "]";
			this._rateLimit = {
				counter: 0,
				timeout: null,
				waiting: [],
				checkpoint: false,
				delta: Number(this.options.rateDelta) || 1e3,
				limit: Number(this.options.rateLimit) || 0
			};
			this._closed = false;
			this._queue = [];
			this._connections = [];
			this._connectionCounter = 0;
			this.idling = true;
			setImmediate(() => {
				if (this.idling) this.emit("idle");
			});
		}
		/**
		* Placeholder function for creating proxy sockets. This method immediatelly returns
		* without a socket
		*
		* @param {Object} options Connection options
		* @param {Function} callback Callback function to run with the socket keys
		*/
		getSocket(options, callback) {
			return setImmediate(() => callback(null, false));
		}
		/**
		* Queues an e-mail to be sent using the selected settings
		*
		* @param {Object} mail Mail object
		* @param {Function} callback Callback function
		*/
		send(mail, callback) {
			if (this._closed) return false;
			this._queue.push({
				mail,
				requeueAttempts: 0,
				callback
			});
			if (this.idling && this._queue.length >= this.options.maxConnections) this.idling = false;
			setImmediate(() => this._processMessages());
			return true;
		}
		/**
		* Closes all connections in the pool. If there is a message being sent, the connection
		* is closed later
		*/
		close() {
			let connection;
			const len = this._connections.length;
			this._closed = true;
			clearTimeout(this._rateLimit.timeout);
			if (!len && !this._queue.length) return;
			for (let i = len - 1; i >= 0; i--) if (this._connections[i] && this._connections[i].available) {
				connection = this._connections[i];
				connection.close();
				this.logger.info({
					tnx: "connection",
					cid: connection.id,
					action: "removed"
				}, "Connection #%s removed", connection.id);
			}
			if (len && !this._connections.length) this.logger.debug({ tnx: "connection" }, "All connections removed");
			if (!this._queue.length) return;
			const invokeCallbacks = () => {
				if (!this._queue.length) {
					this.logger.debug({ tnx: "connection" }, "Pending queue entries cleared");
					return;
				}
				const entry = this._queue.shift();
				if (entry && typeof entry.callback === "function") try {
					entry.callback(/* @__PURE__ */ new Error("Connection pool was closed"));
				} catch (E) {
					this.logger.error({
						err: E,
						tnx: "callback",
						cid: connection.id
					}, "Callback error for #%s: %s", connection.id, E.message);
				}
				setImmediate(invokeCallbacks);
			};
			setImmediate(invokeCallbacks);
		}
		/**
		* Check the queue and available connections. If there is a message to be sent and there is
		* an available connection, then use this connection to send the mail
		*/
		_processMessages() {
			if (this._closed) return;
			if (!this._queue.length) {
				if (!this.idling) {
					this.idling = true;
					this.emit("idle");
				}
				return;
			}
			let connection = this._connections.find((c) => c.available);
			if (!connection && this._connections.length < this.options.maxConnections) connection = this._createConnection();
			if (!connection) {
				this.idling = false;
				return;
			}
			if (!this.idling && this._queue.length < this.options.maxConnections) {
				this.idling = true;
				this.emit("idle");
			}
			const entry = connection.queueEntry = this._queue.shift();
			entry.messageId = (connection.queueEntry.mail.message.getHeader("message-id") || "").replace(/[<>\s]/g, "");
			connection.available = false;
			this.logger.debug({
				tnx: "pool",
				cid: connection.id,
				messageId: entry.messageId,
				action: "assign"
			}, "Assigned message <%s> to #%s (%s)", entry.messageId, connection.id, connection.messages + 1);
			if (this._rateLimit.limit) {
				this._rateLimit.counter++;
				if (!this._rateLimit.checkpoint) this._rateLimit.checkpoint = Date.now();
			}
			connection.send(entry.mail, (err, info) => {
				if (entry === connection.queueEntry) {
					try {
						entry.callback(err, info);
					} catch (E) {
						this.logger.error({
							err: E,
							tnx: "callback",
							cid: connection.id
						}, "Callback error for #%s: %s", connection.id, E.message);
					}
					connection.queueEntry = false;
				}
			});
		}
		/**
		* Creates a new pool resource
		*/
		_createConnection() {
			const connection = new PoolResource(this);
			connection.id = ++this._connectionCounter;
			this.logger.info({
				tnx: "pool",
				cid: connection.id,
				action: "conection"
			}, "Created new pool resource #%s", connection.id);
			connection.on("available", () => {
				this.logger.debug({
					tnx: "connection",
					cid: connection.id,
					action: "available"
				}, "Connection #%s became available", connection.id);
				if (this._closed) this.close();
				else this._processMessages();
			});
			connection.once("error", (err) => {
				if (err.code !== errors.EMAXLIMIT) this.logger.warn({
					err,
					tnx: "pool",
					cid: connection.id
				}, "Pool Error for #%s: %s", connection.id, err.message);
				else this.logger.debug({
					tnx: "pool",
					cid: connection.id,
					action: "maxlimit"
				}, "Max messages limit exchausted for #%s", connection.id);
				if (connection.queueEntry) {
					try {
						connection.queueEntry.callback(err);
					} catch (E) {
						this.logger.error({
							err: E,
							tnx: "callback",
							cid: connection.id
						}, "Callback error for #%s: %s", connection.id, E.message);
					}
					connection.queueEntry = false;
				}
				this._removeConnection(connection);
				this._continueProcessing();
			});
			connection.once("close", () => {
				this.logger.info({
					tnx: "connection",
					cid: connection.id,
					action: "closed"
				}, "Connection #%s was closed", connection.id);
				this._removeConnection(connection);
				if (connection.queueEntry) setTimeout(() => {
					if (connection.queueEntry) if (this._shouldRequeuOnConnectionClose(connection.queueEntry)) this._requeueEntryOnConnectionClose(connection);
					else this._failDeliveryOnConnectionClose(connection);
					this._continueProcessing();
				}, 50);
				else {
					if (!this._closed && this.idling && !this._connections.length) this.emit("clear");
					this._continueProcessing();
				}
			});
			this._connections.push(connection);
			return connection;
		}
		_shouldRequeuOnConnectionClose(queueEntry) {
			if (this.options.maxRequeues === void 0 || this.options.maxRequeues < 0) return true;
			return queueEntry.requeueAttempts < this.options.maxRequeues;
		}
		_failDeliveryOnConnectionClose(connection) {
			if (connection.queueEntry && connection.queueEntry.callback) {
				try {
					connection.queueEntry.callback(/* @__PURE__ */ new Error("Reached maximum number of retries after connection was closed"));
				} catch (E) {
					this.logger.error({
						err: E,
						tnx: "callback",
						messageId: connection.queueEntry.messageId,
						cid: connection.id
					}, "Callback error for #%s: %s", connection.id, E.message);
				}
				connection.queueEntry = false;
			}
		}
		_requeueEntryOnConnectionClose(connection) {
			connection.queueEntry.requeueAttempts += 1;
			this.logger.debug({
				tnx: "pool",
				cid: connection.id,
				messageId: connection.queueEntry.messageId,
				action: "requeue"
			}, "Re-queued message <%s> for #%s. Attempt: #%s", connection.queueEntry.messageId, connection.id, connection.queueEntry.requeueAttempts);
			this._queue.unshift(connection.queueEntry);
			connection.queueEntry = false;
		}
		/**
		* Continue to process message if the pool hasn't closed
		*/
		_continueProcessing() {
			if (this._closed) this.close();
			else setTimeout(() => this._processMessages(), 100);
		}
		/**
		* Remove resource from pool
		*
		* @param {Object} connection The PoolResource to remove
		*/
		_removeConnection(connection) {
			const index = this._connections.indexOf(connection);
			if (index !== -1) this._connections.splice(index, 1);
		}
		/**
		* Checks if connections have hit current rate limit and if so, queues the availability callback
		*
		* @param {Function} callback Callback function to run once rate limiter has been cleared
		*/
		_checkRateLimit(callback) {
			if (!this._rateLimit.limit) return callback();
			const now = Date.now();
			if (this._rateLimit.counter < this._rateLimit.limit) return callback();
			this._rateLimit.waiting.push(callback);
			if (this._rateLimit.checkpoint <= now - this._rateLimit.delta) return this._clearRateLimit();
			if (!this._rateLimit.timeout) {
				this._rateLimit.timeout = setTimeout(() => this._clearRateLimit(), this._rateLimit.delta - (now - this._rateLimit.checkpoint));
				this._rateLimit.checkpoint = now;
			}
		}
		/**
		* Clears current rate limit limitation and runs paused callback
		*/
		_clearRateLimit() {
			clearTimeout(this._rateLimit.timeout);
			this._rateLimit.timeout = null;
			this._rateLimit.counter = 0;
			this._rateLimit.checkpoint = false;
			while (this._rateLimit.waiting.length) {
				const cb = this._rateLimit.waiting.shift();
				setImmediate(cb);
			}
		}
		/**
		* Returns true if there are free slots in the queue
		*/
		isIdle() {
			return this.idling;
		}
		/**
		* Verifies SMTP configuration
		*
		* @param {Function} callback Callback function
		*/
		verify(callback) {
			let promise;
			if (!callback) promise = new Promise((resolve, reject) => {
				callback = shared.callbackPromise(resolve, reject);
			});
			const auth = new PoolResource(this).auth;
			this.getSocket(this.options, (err, socketOptions) => {
				if (err) return callback(err);
				let options = this.options;
				if (socketOptions && socketOptions.connection) {
					this.logger.info({
						tnx: "proxy",
						remoteAddress: socketOptions.connection.remoteAddress,
						remotePort: socketOptions.connection.remotePort,
						destHost: options.host || "",
						destPort: options.port || "",
						action: "connected"
					}, "Using proxied socket from %s:%s to %s:%s", socketOptions.connection.remoteAddress, socketOptions.connection.remotePort, options.host || "", options.port || "");
					options = Object.assign(shared.assign(false, options), socketOptions);
				}
				const connection = new SMTPConnection(options);
				let returned = false;
				connection.once("error", (err) => {
					if (returned) return;
					returned = true;
					connection.close();
					return callback(err);
				});
				connection.once("end", () => {
					if (returned) return;
					returned = true;
					return callback(/* @__PURE__ */ new Error("Connection closed"));
				});
				const finalize = () => {
					if (returned) return;
					returned = true;
					connection.quit();
					return callback(null, true);
				};
				connection.connect(() => {
					if (returned) return;
					if (auth && (connection.allowsAuth || options.forceAuth)) connection.login(auth, (err) => {
						if (returned) return;
						if (err) {
							returned = true;
							connection.close();
							return callback(err);
						}
						finalize();
					});
					else if (!auth && connection.allowsAuth && options.forceAuth) {
						const err = /* @__PURE__ */ new Error("Authentication info was not provided");
						err.code = errors.ENOAUTH;
						returned = true;
						connection.close();
						return callback(err);
					} else finalize();
				});
			});
			return promise;
		}
	};
	module.exports = SMTPPool;
}));
//#endregion
//#region node_modules/nodemailer/lib/smtp-transport/index.js
var require_smtp_transport = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var EventEmitter$2 = __require("events");
	var SMTPConnection = require_smtp_connection();
	var wellKnown = require_well_known();
	var shared = require_shared();
	var XOAuth2 = require_xoauth2();
	var errors = require_errors();
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	/**
	* Creates a SMTP transport object for Nodemailer
	*
	* @constructor
	* @param {Object} options Connection options
	*/
	var SMTPTransport = class extends EventEmitter$2 {
		constructor(options) {
			super();
			options = options || {};
			if (typeof options === "string") options = { url: options };
			let urlData;
			let service = options.service;
			if (typeof options.getSocket === "function") this.getSocket = options.getSocket;
			if (options.url) {
				urlData = shared.parseConnectionUrl(options.url);
				service = service || urlData.service;
			}
			this.options = shared.assign(false, options, urlData, service && wellKnown(service));
			this.logger = shared.getLogger(this.options, { component: this.options.component || "smtp-transport" });
			this.name = "SMTP";
			this.version = packageData.version + "[client:" + packageData.version + "]";
			if (this.options.auth) this.auth = this.getAuth({});
		}
		/**
		* Placeholder function for creating proxy sockets. This method immediatelly returns
		* without a socket
		*
		* @param {Object} options Connection options
		* @param {Function} callback Callback function to run with the socket keys
		*/
		getSocket(options, callback) {
			return setImmediate(() => callback(null, false));
		}
		getAuth(authOpts) {
			if (!authOpts) {
				if (this.auth && this.auth.oauth2 && this.mailer) this.auth.oauth2.provisionCallback = this.mailer.get("oauth2_provision_cb") || this.auth.oauth2.provisionCallback;
				return this.auth;
			}
			const authData = Object.assign({}, this.options.auth && typeof this.options.auth === "object" ? this.options.auth : {}, typeof authOpts === "object" ? authOpts : {});
			if (Object.keys(authData).length === 0) return false;
			switch ((authData.type || "").toString().toUpperCase()) {
				case "OAUTH2": {
					if (!authData.service && !authData.user) return false;
					const oauth2 = new XOAuth2(authData, this.logger);
					oauth2.provisionCallback = this.mailer && this.mailer.get("oauth2_provision_cb") || oauth2.provisionCallback;
					oauth2.on("token", (token) => this.mailer.emit("token", token));
					oauth2.on("error", (err) => this.emit("error", err));
					return {
						type: "OAUTH2",
						user: authData.user,
						oauth2,
						method: "XOAUTH2"
					};
				}
				default: return {
					type: (authData.type || "").toString().toUpperCase() || "LOGIN",
					user: authData.user,
					credentials: {
						user: authData.user || "",
						pass: authData.pass,
						options: authData.options
					},
					method: (authData.method || "").trim().toUpperCase() || this.options.authMethod || false
				};
			}
		}
		/**
		* Sends an e-mail using the selected settings
		*
		* @param {Object} mail Mail object
		* @param {Function} callback Callback function
		*/
		send(mail, callback) {
			this.getSocket(this.options, (err, socketOptions) => {
				if (err) return callback(err);
				let returned = false;
				let options = this.options;
				if (socketOptions && socketOptions.connection) {
					this.logger.info({
						tnx: "proxy",
						remoteAddress: socketOptions.connection.remoteAddress,
						remotePort: socketOptions.connection.remotePort,
						destHost: options.host || "",
						destPort: options.port || "",
						action: "connected"
					}, "Using proxied socket from %s:%s to %s:%s", socketOptions.connection.remoteAddress, socketOptions.connection.remotePort, options.host || "", options.port || "");
					options = Object.assign(shared.assign(false, options), socketOptions);
				}
				const connection = new SMTPConnection(options);
				let perCallAuth;
				const cleanupPerCallAuth = () => {
					if (perCallAuth && perCallAuth !== this.auth && perCallAuth.oauth2) perCallAuth.oauth2.removeAllListeners();
					perCallAuth = null;
				};
				connection.once("error", (err) => {
					if (returned) return;
					returned = true;
					cleanupPerCallAuth();
					connection.close();
					return callback(err);
				});
				connection.once("end", () => {
					if (returned) return;
					const timer = setTimeout(() => {
						if (returned) return;
						returned = true;
						cleanupPerCallAuth();
						const err = /* @__PURE__ */ new Error("Unexpected socket close");
						if (connection && connection._socket && connection._socket.upgrading) err.code = errors.ETLS;
						callback(err);
					}, 1e3);
					try {
						timer.unref();
					} catch (_E) {}
				});
				const sendMessage = () => {
					const envelope = mail.message.getEnvelope();
					const messageId = mail.message.messageId();
					const recipients = [].concat(envelope.to || []);
					if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
					if (mail.data.dsn) envelope.dsn = mail.data.dsn;
					if (mail.data.requireTLSExtensionEnabled) envelope.requireTLSExtensionEnabled = mail.data.requireTLSExtensionEnabled;
					this.logger.info({
						tnx: "send",
						messageId
					}, "Sending message %s to <%s>", messageId, recipients.join(", "));
					connection.send(envelope, mail.message.createReadStream(), (err, info) => {
						returned = true;
						cleanupPerCallAuth();
						connection.close();
						if (err) {
							this.logger.error({
								err,
								tnx: "send"
							}, "Send error for %s: %s", messageId, err.message);
							return callback(err);
						}
						info.envelope = {
							from: envelope.from,
							to: envelope.to
						};
						info.messageId = messageId;
						try {
							return callback(null, info);
						} catch (E) {
							this.logger.error({
								err: E,
								tnx: "callback"
							}, "Callback error for %s: %s", messageId, E.message);
						}
					});
				};
				connection.connect(() => {
					if (returned) return;
					perCallAuth = this.getAuth(mail.data.auth);
					if (perCallAuth && (connection.allowsAuth || options.forceAuth)) connection.login(perCallAuth, (err) => {
						cleanupPerCallAuth();
						if (returned) return;
						if (err) {
							returned = true;
							connection.close();
							return callback(err);
						}
						sendMessage();
					});
					else sendMessage();
				});
			});
		}
		/**
		* Verifies SMTP configuration
		*
		* @param {Function} callback Callback function
		*/
		verify(callback) {
			let promise;
			if (!callback) promise = new Promise((resolve, reject) => {
				callback = shared.callbackPromise(resolve, reject);
			});
			this.getSocket(this.options, (err, socketOptions) => {
				if (err) return callback(err);
				let options = this.options;
				if (socketOptions && socketOptions.connection) {
					this.logger.info({
						tnx: "proxy",
						remoteAddress: socketOptions.connection.remoteAddress,
						remotePort: socketOptions.connection.remotePort,
						destHost: options.host || "",
						destPort: options.port || "",
						action: "connected"
					}, "Using proxied socket from %s:%s to %s:%s", socketOptions.connection.remoteAddress, socketOptions.connection.remotePort, options.host || "", options.port || "");
					options = Object.assign(shared.assign(false, options), socketOptions);
				}
				const connection = new SMTPConnection(options);
				let returned = false;
				let perCallAuth;
				const cleanupPerCallAuth = () => {
					if (perCallAuth && perCallAuth !== this.auth && perCallAuth.oauth2) perCallAuth.oauth2.removeAllListeners();
					perCallAuth = null;
				};
				connection.once("error", (err) => {
					if (returned) return;
					returned = true;
					cleanupPerCallAuth();
					connection.close();
					return callback(err);
				});
				connection.once("end", () => {
					if (returned) return;
					returned = true;
					cleanupPerCallAuth();
					return callback(/* @__PURE__ */ new Error("Connection closed"));
				});
				const finalize = () => {
					if (returned) return;
					returned = true;
					cleanupPerCallAuth();
					connection.quit();
					return callback(null, true);
				};
				connection.connect(() => {
					if (returned) return;
					perCallAuth = this.getAuth({});
					if (perCallAuth && (connection.allowsAuth || options.forceAuth)) connection.login(perCallAuth, (err) => {
						cleanupPerCallAuth();
						if (returned) return;
						if (err) {
							returned = true;
							connection.close();
							return callback(err);
						}
						finalize();
					});
					else if (!perCallAuth && connection.allowsAuth && options.forceAuth) {
						const err = /* @__PURE__ */ new Error("Authentication info was not provided");
						err.code = errors.ENOAUTH;
						returned = true;
						cleanupPerCallAuth();
						connection.close();
						return callback(err);
					} else finalize();
				});
			});
			return promise;
		}
		/**
		* Releases resources
		*/
		close() {
			if (this.auth && this.auth.oauth2) this.auth.oauth2.removeAllListeners();
			this.emit("close");
		}
	};
	module.exports = SMTPTransport;
}));
//#endregion
//#region node_modules/nodemailer/lib/sendmail-transport/index.js
var require_sendmail_transport = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var { spawn } = __require("child_process");
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var shared = require_shared();
	var errors = require_errors();
	var LeWindows = require_le_windows();
	var LeUnix = require_le_unix();
	/**
	* Generates a Transport object for Sendmail
	*
	* Possible options can be the following:
	*
	*  * **path** optional path to sendmail binary
	*  * **newline** either 'windows' or 'unix'
	*  * **args** an array of arguments for the sendmail binary
	*
	* @constructor
	* @param {Object} optional config parameter for Sendmail
	*/
	var SendmailTransport = class {
		constructor(options) {
			options = options || {};
			this._spawn = spawn;
			this.options = options;
			this.name = "Sendmail";
			this.version = packageData.version;
			this.path = "sendmail";
			this.args = false;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "sendmail" });
			if (typeof options === "string") this.path = options;
			else if (typeof options === "object") {
				if (options.path) this.path = options.path;
				if (Array.isArray(options.args)) this.args = options.args;
			}
			this.winbreak = [
				"win",
				"windows",
				"dos",
				"\r\n"
			].includes((options.newline || "").toString().toLowerCase());
		}
		/**
		* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
		*
		* @param {Object} emailMessage MailComposer object
		* @param {Function} callback Callback function to run when the sending is completed
		*/
		send(mail, done) {
			mail.message.keepBcc = true;
			const envelope = mail.data.envelope || mail.message.getEnvelope();
			const messageId = mail.message.messageId();
			let returned;
			if ([].concat(envelope.from || []).concat(envelope.to || []).some((addr) => /^-/.test(addr))) {
				const err = /* @__PURE__ */ new Error("Can not send mail. Invalid envelope addresses.");
				err.code = errors.ESENDMAIL;
				return done(err);
			}
			const args = this.args ? ["-i"].concat(this.args).concat(envelope.to) : ["-i"].concat(envelope.from ? ["-f", envelope.from] : []).concat(envelope.to);
			const callback = (err) => {
				if (returned) return;
				returned = true;
				if (typeof done === "function") {
					if (err) return done(err);
					return done(null, {
						envelope,
						messageId,
						response: "Messages queued for delivery"
					});
				}
			};
			let sendmail;
			try {
				sendmail = this._spawn(this.path, args);
			} catch (E) {
				this.logger.error({
					err: E,
					tnx: "spawn",
					messageId
				}, "Error occurred while spawning sendmail. %s", E.message);
				return callback(E);
			}
			if (sendmail) {
				sendmail.on("error", (err) => {
					this.logger.error({
						err,
						tnx: "spawn",
						messageId
					}, "Error occurred when sending message %s. %s", messageId, err.message);
					callback(err);
				});
				sendmail.once("exit", (code) => {
					if (!code) return callback();
					const err = /* @__PURE__ */ new Error(code === 127 ? "Sendmail command not found, process exited with code " + code : "Sendmail exited with code " + code);
					err.code = errors.ESENDMAIL;
					this.logger.error({
						err,
						tnx: "stdin",
						messageId
					}, "Error sending message %s to sendmail. %s", messageId, err.message);
					callback(err);
				});
				sendmail.once("close", callback);
				sendmail.stdin.on("error", (err) => {
					this.logger.error({
						err,
						tnx: "stdin",
						messageId
					}, "Error occurred when piping message %s to sendmail. %s", messageId, err.message);
					callback(err);
				});
				const recipients = [].concat(envelope.to || []);
				if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
				this.logger.info({
					tnx: "send",
					messageId
				}, "Sending message %s to <%s>", messageId, recipients.join(", "));
				const sourceStream = mail.message.createReadStream();
				let stream = sourceStream;
				if (this.options.newline) {
					stream = sourceStream.pipe(this.winbreak ? new LeWindows() : new LeUnix());
					sourceStream.once("error", (err) => stream.emit("error", err));
				}
				stream.once("error", (err) => {
					this.logger.error({
						err,
						tnx: "stdin",
						messageId
					}, "Error occurred when generating message %s. %s", messageId, err.message);
					sendmail.kill("SIGINT");
					callback(err);
				});
				stream.pipe(sendmail.stdin);
			} else {
				const err = /* @__PURE__ */ new Error("sendmail was not found");
				err.code = errors.ESENDMAIL;
				return callback(err);
			}
		}
	};
	module.exports = SendmailTransport;
}));
//#endregion
//#region node_modules/nodemailer/lib/stream-transport/index.js
var require_stream_transport = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var shared = require_shared();
	var LeWindows = require_le_windows();
	var LeUnix = require_le_unix();
	/**
	* Generates a Transport object for streaming
	*
	* Possible options can be the following:
	*
	*  * **buffer** if true, then returns the message as a Buffer object instead of a stream
	*  * **newline** either 'windows' or 'unix'
	*
	* @constructor
	* @param {Object} optional config parameter
	*/
	var StreamTransport = class {
		constructor(options) {
			options = options || {};
			this.options = options;
			this.name = "StreamTransport";
			this.version = packageData.version;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "stream-transport" });
			this.winbreak = [
				"win",
				"windows",
				"dos",
				"\r\n"
			].includes((options.newline || "").toString().toLowerCase());
		}
		/**
		* Compiles a mailcomposer message and forwards it to handler that sends it
		*
		* @param {Object} emailMessage MailComposer object
		* @param {Function} callback Callback function to run when the sending is completed
		*/
		send(mail, done) {
			mail.message.keepBcc = true;
			const envelope = mail.data.envelope || mail.message.getEnvelope();
			const messageId = mail.message.messageId();
			const recipients = [].concat(envelope.to || []);
			if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
			this.logger.info({
				tnx: "send",
				messageId
			}, "Sending message %s to <%s> using %s line breaks", messageId, recipients.join(", "), this.winbreak ? "<CR><LF>" : "<LF>");
			setImmediate(() => {
				let stream;
				try {
					stream = mail.message.createReadStream();
					if (this.options.newline) {
						const sourceStream = stream;
						stream = sourceStream.pipe(this.winbreak ? new LeWindows() : new LeUnix());
						sourceStream.once("error", (err) => stream.emit("error", err));
					}
				} catch (E) {
					this.logger.error({
						err: E,
						tnx: "send",
						messageId
					}, "Creating send stream failed for %s. %s", messageId, E.message);
					return done(E);
				}
				if (!this.options.buffer) {
					stream.once("error", (err) => {
						this.logger.error({
							err,
							tnx: "send",
							messageId
						}, "Failed creating message for %s. %s", messageId, err.message);
					});
					return done(null, {
						envelope,
						messageId,
						message: stream
					});
				}
				const chunks = [];
				let chunklen = 0;
				stream.on("readable", () => {
					let chunk;
					while ((chunk = stream.read()) !== null) {
						chunks.push(chunk);
						chunklen += chunk.length;
					}
				});
				stream.once("error", (err) => {
					this.logger.error({
						err,
						tnx: "send",
						messageId
					}, "Failed creating message for %s. %s", messageId, err.message);
					return done(err);
				});
				stream.on("end", () => done(null, {
					envelope,
					messageId,
					message: Buffer.concat(chunks, chunklen)
				}));
			});
		}
	};
	module.exports = StreamTransport;
}));
//#endregion
//#region node_modules/nodemailer/lib/json-transport/index.js
var require_json_transport = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var shared = require_shared();
	/**
	* Generates a Transport object to generate JSON output
	*
	* @constructor
	* @param {Object} optional config parameter
	*/
	var JSONTransport = class {
		constructor(options) {
			options = options || {};
			this.options = options;
			this.name = "JSONTransport";
			this.version = packageData.version;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "json-transport" });
		}
		/**
		* <p>Compiles a mailcomposer message and forwards it to handler that sends it.</p>
		*
		* @param {Object} emailMessage MailComposer object
		* @param {Function} callback Callback function to run when the sending is completed
		*/
		send(mail, done) {
			mail.message.keepBcc = true;
			const envelope = mail.data.envelope || mail.message.getEnvelope();
			const messageId = mail.message.messageId();
			const recipients = [].concat(envelope.to || []);
			if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
			this.logger.info({
				tnx: "send",
				messageId
			}, "Composing JSON structure of %s to <%s>", messageId, recipients.join(", "));
			setImmediate(() => {
				mail.normalize((err, data) => {
					if (err) {
						this.logger.error({
							err,
							tnx: "send",
							messageId
						}, "Failed building JSON structure for %s. %s", messageId, err.message);
						return done(err);
					}
					delete data.envelope;
					delete data.normalizedHeaders;
					return done(null, {
						envelope,
						messageId,
						message: this.options.skipEncoding ? data : JSON.stringify(data)
					});
				});
			});
		}
	};
	module.exports = JSONTransport;
}));
//#endregion
//#region node_modules/nodemailer/lib/ses-transport/index.js
var require_ses_transport = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var EventEmitter$1 = __require("events");
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var shared = require_shared();
	var errors = require_errors();
	var LeWindows = require_le_windows();
	var MimeNode = require_mime_node();
	/**
	* Tags AWS SDK rejections that carry no `code` property (SDK v3 errors only
	* have a `name`) with the generic SES transport error code, keeping the
	* original error object intact
	*/
	function tagSesError(err) {
		if (err && typeof err === "object" && !err.code) err.code = errors.ESES;
		return err;
	}
	/**
	* Generates a Transport object for AWS SES
	*
	* @constructor
	* @param {Object} optional config parameter
	*/
	var SESTransport = class extends EventEmitter$1 {
		constructor(options) {
			super();
			options = options || {};
			this.options = options;
			this.ses = this.options.SES;
			this.name = "SESTransport";
			this.version = packageData.version;
			this.logger = shared.getLogger(this.options, { component: this.options.component || "ses-transport" });
		}
		getRegion(cb) {
			if (this.ses.sesClient.config && typeof this.ses.sesClient.config.region === "function") return this.ses.sesClient.config.region().then((region) => cb(null, region), (err) => cb(err));
			return cb(null, false);
		}
		/**
		* Compiles a mailcomposer message and forwards it to SES
		*
		* @param {Object} emailMessage MailComposer object
		* @param {Function} callback Callback function to run when the sending is completed
		*/
		send(mail, callback) {
			let fromHeader = mail.message._headers.find((header) => /^from$/i.test(header.key));
			if (fromHeader) {
				const mimeNode = new MimeNode("text/plain");
				fromHeader = mimeNode._convertAddresses(mimeNode._parseAddresses(fromHeader.value));
			}
			const envelope = mail.data.envelope || mail.message.getEnvelope();
			const messageId = mail.message.messageId();
			const recipients = [].concat(envelope.to || []);
			if (recipients.length > 3) recipients.push("...and " + recipients.splice(2).length + " more");
			this.logger.info({
				tnx: "send",
				messageId
			}, "Sending message %s to <%s>", messageId, recipients.join(", "));
			const getRawMessage = (next) => {
				if (!mail.data._dkim) mail.data._dkim = {};
				if (mail.data._dkim.skipFields && typeof mail.data._dkim.skipFields === "string") mail.data._dkim.skipFields += ":date:message-id";
				else mail.data._dkim.skipFields = "date:message-id";
				const sourceStream = mail.message.createReadStream();
				const stream = sourceStream.pipe(new LeWindows());
				const chunks = [];
				let chunklen = 0;
				stream.on("readable", () => {
					let chunk;
					while ((chunk = stream.read()) !== null) {
						chunks.push(chunk);
						chunklen += chunk.length;
					}
				});
				sourceStream.once("error", (err) => stream.emit("error", err));
				stream.once("error", (err) => next(err));
				stream.once("end", () => next(null, Buffer.concat(chunks, chunklen)));
			};
			setImmediate(() => getRawMessage((err, raw) => {
				if (err) {
					this.logger.error({
						err,
						tnx: "send",
						messageId
					}, "Failed creating message for %s. %s", messageId, err.message);
					return callback(err);
				}
				const sesMessage = Object.assign({
					Content: { Raw: { Data: raw } },
					FromEmailAddress: fromHeader || envelope.from,
					Destination: { ToAddresses: envelope.to }
				}, mail.data.ses || {});
				this.getRegion((err, region) => {
					if (err || !region) region = "us-east-1";
					let sendPromise;
					try {
						const command = new this.ses.SendEmailCommand(sesMessage);
						sendPromise = this.ses.sesClient.send(command);
					} catch (err) {
						tagSesError(err);
						this.logger.error({
							err,
							tnx: "send"
						}, "Send error for %s: %s", messageId, err.message);
						setImmediate(() => callback(err));
						return;
					}
					sendPromise.then((data) => {
						if (region === "us-east-1") region = "email";
						const info = {
							envelope: {
								from: envelope.from,
								to: envelope.to
							},
							messageId: "<" + data.MessageId + (!/@/.test(data.MessageId) ? "@" + region + ".amazonses.com" : "") + ">",
							response: data.MessageId,
							raw
						};
						setImmediate(() => callback(null, info));
					}).catch((err) => {
						tagSesError(err);
						this.logger.error({
							err,
							tnx: "send"
						}, "Send error for %s: %s", messageId, err.message);
						setImmediate(() => callback(err));
					});
				});
			}));
		}
		/**
		* Verifies SES configuration
		*
		* @param {Function} callback Callback function
		*/
		verify(callback) {
			let promise;
			if (!callback) promise = new Promise((resolve, reject) => {
				callback = shared.callbackPromise(resolve, reject);
			});
			const cb = (err) => {
				if (err && !["InvalidParameterValue", "MessageRejected"].includes(err.code || err.Code || err.name)) return callback(tagSesError(err));
				return callback(null, true);
			};
			const sesMessage = {
				Content: { Raw: { Data: Buffer.from("From: <invalid@invalid>\r\nTo: <invalid@invalid>\r\n Subject: Invalid\r\n\r\nInvalid") } },
				FromEmailAddress: "invalid@invalid",
				Destination: { ToAddresses: ["invalid@invalid"] }
			};
			this.getRegion(() => {
				let sendPromise;
				try {
					const command = new this.ses.SendEmailCommand(sesMessage);
					sendPromise = this.ses.sesClient.send(command);
				} catch (err) {
					setImmediate(() => cb(err));
					return;
				}
				sendPromise.then(() => setImmediate(() => cb(null))).catch((err) => setImmediate(() => cb(err)));
			});
			return promise;
		}
	};
	module.exports = SESTransport;
}));
//#endregion
//#region src/common/emailService.ts
var import_nodemailer = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Mailer = require_mailer();
	var shared = require_shared();
	var SMTPPool = require_smtp_pool();
	var SMTPTransport = require_smtp_transport();
	var SendmailTransport = require_sendmail_transport();
	var StreamTransport = require_stream_transport();
	var JSONTransport = require_json_transport();
	var SESTransport = require_ses_transport();
	var errors = require_errors();
	var nmfetch = require_fetch();
	var packageData = (init_package(), __toCommonJS(package_exports).default);
	var ETHEREAL_API = (process.env.ETHEREAL_API || "https://api.nodemailer.com").replace(/\/+$/, "");
	var ETHEREAL_WEB = (process.env.ETHEREAL_WEB || "https://ethereal.email").replace(/\/+$/, "");
	var ETHEREAL_API_KEY = (process.env.ETHEREAL_API_KEY || "").replace(/\s*/g, "") || null;
	var ETHEREAL_CACHE = [
		"true",
		"yes",
		"y",
		"1"
	].includes((process.env.ETHEREAL_CACHE || "yes").toString().trim().toLowerCase());
	var testAccount = false;
	module.exports.createTransport = function(transporter, defaults) {
		let options;
		if (typeof transporter === "object" && typeof transporter.send !== "function" || typeof transporter === "string" && /^(smtps?|direct):/i.test(transporter)) {
			const urlConfig = typeof transporter === "string" ? transporter : transporter.url;
			if (urlConfig) options = shared.parseConnectionUrl(urlConfig);
			else options = transporter;
			if (options.pool) transporter = new SMTPPool(options);
			else if (options.sendmail) transporter = new SendmailTransport(options);
			else if (options.streamTransport) transporter = new StreamTransport(options);
			else if (options.jsonTransport) transporter = new JSONTransport(options);
			else if (options.SES) {
				if (options.SES.ses && options.SES.aws) {
					const error = /* @__PURE__ */ new Error("Using legacy SES configuration, expecting @aws-sdk/client-sesv2, see https://nodemailer.com/transports/ses/");
					error.code = errors.ECONFIG;
					throw error;
				}
				transporter = new SESTransport(options);
			} else transporter = new SMTPTransport(options);
		}
		return new Mailer(transporter, options, defaults);
	};
	module.exports.createTestAccount = function(apiUrl, callback) {
		let promise;
		if (!callback && typeof apiUrl === "function") {
			callback = apiUrl;
			apiUrl = false;
		}
		if (!callback) promise = new Promise((resolve, reject) => {
			callback = shared.callbackPromise(resolve, reject);
		});
		if (ETHEREAL_CACHE && testAccount) {
			setImmediate(() => callback(null, testAccount));
			return promise;
		}
		apiUrl = apiUrl || ETHEREAL_API;
		const chunks = [];
		let chunklen = 0;
		const requestHeaders = {};
		const requestBody = {
			requestor: packageData.name,
			version: packageData.version
		};
		if (ETHEREAL_API_KEY) requestHeaders.Authorization = "Bearer " + ETHEREAL_API_KEY;
		const fetchOptions = {
			contentType: "application/json",
			method: "POST",
			headers: requestHeaders,
			body: Buffer.from(JSON.stringify(requestBody))
		};
		if (/^https:/i.test(apiUrl)) fetchOptions.tls = { rejectUnauthorized: true };
		const req = nmfetch(apiUrl + "/user", fetchOptions);
		req.on("readable", () => {
			let chunk;
			while ((chunk = req.read()) !== null) {
				chunks.push(chunk);
				chunklen += chunk.length;
			}
		});
		req.once("error", (err) => callback(err));
		req.once("end", () => {
			const res = Buffer.concat(chunks, chunklen);
			let data;
			try {
				data = JSON.parse(res.toString());
			} catch (E) {
				return callback(E);
			}
			if (data.status !== "success" || data.error) return callback(new Error(data.error || "Request failed"));
			delete data.status;
			testAccount = data;
			callback(null, testAccount);
		});
		return promise;
	};
	module.exports.getTestMessageUrl = function(info) {
		if (!info || !info.response) return false;
		const infoProps = /* @__PURE__ */ new Map();
		const response = info.response.toString();
		if (response.length > 2 && response.charAt(response.length - 1) === "]") {
			const open = response.indexOf("[", response.lastIndexOf("]", response.length - 2) + 1);
			if (open >= 0 && open < response.length - 2) response.substring(open + 1, response.length - 1).replace(/\b([A-Z0-9]+)=([^\s]+)/g, (m, key, value) => {
				infoProps.set(key, value);
			});
		}
		if (infoProps.has("STATUS") && infoProps.has("MSGID")) return (testAccount.web || ETHEREAL_WEB) + "/message/" + infoProps.get("MSGID");
		return false;
	};
})))(), 1);
var EmailService = class {
	configManager;
	logger;
	constructor(configManager, logger) {
		this.configManager = configManager;
		this.logger = logger;
	}
	async sendEmail(options) {
		try {
			const config = this.configManager.getConfig();
			if (!config.enabled) return {
				success: false,
				error: "邮件通知未启用"
			};
			const validation = this.configManager.validateConfig(config);
			if (!validation.valid) return {
				success: false,
				error: `配置无效：${validation.errors.join(", ")}`
			};
			const info = await this.createTransporter().sendMail({
				from: config.from,
				to: config.to,
				subject: options.subject,
				html: options.html,
				text: options.text
			});
			this.logger?.info("[EmailService] Email sent successfully:", info.messageId);
			return {
				success: true,
				messageId: info.messageId
			};
		} catch (error) {
			const errorMessage = this.getErrorMessage(error);
			this.logger?.error("[EmailService] Failed to send email:", errorMessage);
			return {
				success: false,
				error: errorMessage
			};
		}
	}
	async sendTestEmail() {
		const timestamp = (/* @__PURE__ */ new Date()).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
		const options = this.formatTestEmail(timestamp);
		return this.sendEmail(options);
	}
	async sendOfflineNotification(botInfo, reason) {
		const options = this.formatOfflineEmail(botInfo, reason);
		return this.sendEmail(options);
	}
	createTransporter() {
		const config = this.configManager.getConfig();
		return import_nodemailer.default.createTransport({
			host: config.smtp.host,
			port: config.smtp.port,
			secure: config.smtp.secure,
			auth: {
				user: config.smtp.auth.user,
				pass: config.smtp.auth.pass
			}
		});
	}
	formatOfflineEmail(botInfo, reason) {
		const timestamp = botInfo.timestamp.toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
		return {
			subject: "LLBot 掉线通知",
			html: `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .header { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 20px; border-radius: 8px 8px 0 0; }
        .content { background: #f9f9f9; padding: 20px; border-radius: 0 0 8px 8px; }
        .alert { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 10px 0; }
        .info { background: white; padding: 15px; margin: 10px 0; }
        .footer { text-align: center; margin-top: 20px; color: #666; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h2>⚠️ LLBot 掉线通知</h2>
        </div>
        <div class="content">
            <div class="alert">
                <p><strong>⚠️ QQ 已掉线</strong></p>
            </div>
            <div class="info">
                <p><strong>账号信息:</strong> ${botInfo.nick ? `${botInfo.nick} (${botInfo.uin})` : botInfo.uin}</p>
                <p><strong>掉线时间:</strong> ${timestamp}</p>
            </div>
            <p>您的 QQ 机器人已掉线，请及时检查并重新登录。</p>
            ${reason ? `<div class="info">
                <p><strong>掉线原因:</strong> ${reason}</p>
            </div>` : `<p>可能的原因：</p>
            <ul>
                <li>网络连接中断</li>
                <li>QQ 被强制下线</li>
                <li>程序异常退出</li>
            </ul>`}
        </div>
        <div class="footer">
            <p>此邮件由 LLBot 自动发送，请勿回复</p>
        </div>
    </div>
</body>
</html>
    `.trim()
		};
	}
	formatTestEmail(timestamp) {
		return {
			subject: "LLBot 邮件通知测试",
			html: `
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
        .container { max-width: 600px; margin: 0 auto; padding: 20px; }
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px 8px 0 0; }
        .content { background: #f9f9f9; padding: 20px; border-radius: 0 0 8px 8px; }
        .info { background: white; padding: 15px; border-left: 4px solid #667eea; margin: 10px 0; }
        .footer { text-align: center; margin-top: 20px; color: #666; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h2>🎉 LLBot 邮件通知测试</h2>
        </div>
        <div class="content">
            <p>您好！</p>
            <p>这是一封来自 <strong>LLBot</strong> 的测试邮件。</p>
            <div class="info">
                <p><strong>📧 邮件配置测试成功</strong></p>
                <p>发送时间: ${timestamp}</p>
            </div>
            <p>如果您收到这封邮件，说明邮件通知功能已正常工作。</p>
            <p>当 QQ 掉线时，系统将自动向您发送通知邮件。</p>
        </div>
        <div class="footer">
            <p>此邮件由 LLBot 自动发送，请勿回复</p>
        </div>
    </div>
</body>
</html>
    `.trim()
		};
	}
	getErrorMessage(error) {
		const config = this.configManager.getConfig();
		if (error.code === "ECONNREFUSED" || error.code === "ETIMEDOUT") return `无法连接到 SMTP 服务器：${config.smtp.host}:${config.smtp.port}`;
		if (error.code === "EAUTH" || error.responseCode === 535) return "SMTP 认证失败，请检查用户名和密码";
		if (error.code === "ETIMEDOUT") return "邮件发送超时，请检查网络连接";
		if (error.responseCode === 550 || error.responseCode === 553) return `收件人邮箱地址无效：${config.to}`;
		if (error.responseCode === 421 || error.responseCode === 450) return "邮件发送频率超限，请稍后再试";
		return error.message || "发生未知错误";
	}
};
//#endregion
//#region src/common/emailConfig.ts
var DEFAULT_CONFIG$1 = {
	enabled: false,
	smtp: {
		host: "",
		port: 587,
		secure: false,
		auth: {
			user: "",
			pass: ""
		}
	},
	from: "",
	to: ""
};
var EmailConfigManager = class {
	configPath;
	config = null;
	logger;
	constructor(configPath, logger) {
		this.configPath = configPath;
		this.logger = logger;
	}
	async loadConfig() {
		try {
			if (!existsSync(this.configPath)) {
				this.logger?.info("[EmailConfig] Configuration file not found, creating default");
				await this.createDefaultConfig();
				return { ...DEFAULT_CONFIG$1 };
			}
			const content = await readFile(this.configPath, "utf-8");
			this.config = JSON.parse(content);
			return this.config;
		} catch (error) {
			this.logger?.error("[EmailConfig] Failed to load configuration:", error);
			return { ...DEFAULT_CONFIG$1 };
		}
	}
	async saveConfig(config) {
		try {
			const dir = dirname(this.configPath);
			if (!existsSync(dir)) await mkdir(dir, { recursive: true });
			await writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
			this.config = config;
			this.logger?.info("[EmailConfig] Configuration saved successfully");
		} catch (error) {
			this.logger?.error("[EmailConfig] Failed to save configuration:", error);
			throw error;
		}
	}
	getConfig() {
		return this.config ? { ...this.config } : { ...DEFAULT_CONFIG$1 };
	}
	validateConfig(config) {
		const errors = [];
		if (!config.enabled) return {
			valid: true,
			errors: []
		};
		if (!config.smtp.host || config.smtp.host.trim() === "") errors.push("SMTP 服务器不能为空");
		if (!config.smtp.port || config.smtp.port < 1 || config.smtp.port > 65535) errors.push("端口必须在 1-65535 之间");
		const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
		if (!config.from || !emailRegex.test(config.from)) errors.push("发件人邮箱格式不正确");
		if (!config.to || !emailRegex.test(config.to)) errors.push("收件人邮箱格式不正确");
		return {
			valid: errors.length === 0,
			errors
		};
	}
	async createDefaultConfig() {
		await this.saveConfig(DEFAULT_CONFIG$1);
	}
};
//#endregion
//#region src/common/emailNotification.ts
var EmailNotificationService = class extends Service {
	static inject = ["qqProtocol"];
	emailService;
	configManager;
	notificationSent = false;
	hasLoggedIn = false;
	configPath;
	fileWatcher = null;
	disconnectId = null;
	checkLoginStatus = null;
	constructor(ctx) {
		super(ctx, "emailNotification");
		this.configPath = path.join(DATA_DIR, "email_config.json");
		this.configManager = new EmailConfigManager(this.configPath, ctx.logger);
		this.emailService = new EmailService(this.configManager, ctx.logger);
		this.initializeConfig();
		this.registerEventListeners();
		this.registerDisconnectCallback();
	}
	async [Service.init]() {
		return () => {
			if (this.checkLoginStatus) clearInterval(this.checkLoginStatus);
			if (this.fileWatcher) this.fileWatcher.close();
			if (this.disconnectId) this.ctx.qqProtocol.offDisconnect(this.disconnectId);
		};
	}
	async initializeConfig() {
		try {
			await this.configManager.loadConfig();
			this.watchConfigFile();
		} catch (error) {
			this.ctx.logger.error("[EmailNotification] Failed to initialize:", error);
		}
	}
	registerEventListeners() {
		this.hasLoggedIn = true;
		let wasOffline = false;
		this.ctx.on("nt/kicked-offline", (data) => {
			wasOffline = true;
			this.onOffline(data.tipsDesc || data.tipsTitle);
		});
		this.checkLoginStatus = setInterval(() => {
			if (wasOffline && selfInfo.online) {
				this.notificationSent = false;
				wasOffline = false;
			}
		}, 5e3);
	}
	watchConfigFile() {
		try {
			this.fileWatcher = watch(this.configPath, async (eventType) => {
				if (eventType === "change") {
					await this.configManager.loadConfig();
					this.ctx.parallel("llbot/email-config-updated", this.configManager.getConfig());
				}
			});
		} catch (error) {
			this.ctx.logger.error("[EmailNotification] Failed to watch config file:", error);
		}
	}
	registerDisconnectCallback() {
		this.disconnectId = this.ctx.qqProtocol.onDisconnect(1e4, (duration) => {
			if (!this.notificationSent && this.hasLoggedIn) {
				this.ctx.logger.warn(`[EmailNotification] QQ connection lost for ${duration}ms`);
				this.onOffline("可能 QQ 已经有点死了");
			}
		});
	}
	onOffline(reason) {
		if (!this.hasLoggedIn) return;
		if (this.notificationSent) return;
		this.ctx.logger.info("[EmailNotification] Bot offline, sending notification");
		this.sendOfflineNotification(reason).catch((e) => {
			this.ctx.logger.error("[EmailNotification] sendOfflineNotification error:", e);
		});
	}
	async sendOfflineNotification(reason) {
		if (!this.configManager.getConfig().enabled) {
			this.ctx.logger.debug("[EmailNotification] Email notifications are disabled");
			return;
		}
		const botInfo = {
			uin: selfInfo.uin,
			uid: selfInfo.uid,
			nick: selfInfo.nick,
			timestamp: /* @__PURE__ */ new Date()
		};
		const result = await this.emailService.sendOfflineNotification(botInfo, reason);
		if (result.success) {
			this.notificationSent = true;
			this.ctx.logger.info("[EmailNotification] Offline notification sent successfully");
		} else this.ctx.logger.error("[EmailNotification] Failed to send notification:", result.error);
	}
	getEmailService() {
		return this.emailService;
	}
	getConfigManager() {
		return this.configManager;
	}
};
//#endregion
//#region src/main/qqProtocol/util.ts
function deepStringifyMap(obj) {
	if (typeof obj !== "object" || obj === null) return obj;
	if (Array.isArray(obj)) return obj.map((item) => deepStringifyMap(item));
	if (obj instanceof Map) return {
		__dataType: "Map",
		data: Array.from(obj.entries()).map(([k, v]) => [deepStringifyMap(k), deepStringifyMap(v)])
	};
	const convertedObj = {};
	for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) convertedObj[key] = deepStringifyMap(obj[key]);
	return convertedObj;
}
function deepConvertMap(obj) {
	if (typeof obj !== "object" || obj === null) return obj;
	if (Array.isArray(obj)) return obj.map((item) => deepConvertMap(item));
	const potentialMap = obj;
	if (potentialMap.__dataType === "Map" && "data" in potentialMap) {
		const entries = Array.isArray(potentialMap.data) ? potentialMap.data.map(([k, v]) => [deepConvertMap(k), deepConvertMap(v)]) : [];
		return new Map(entries);
	}
	const convertedObj = {};
	for (const key in obj) if (Object.prototype.hasOwnProperty.call(obj, key)) convertedObj[key] = deepConvertMap(obj[key]);
	return convertedObj;
}
//#endregion
//#region src/main/qqProtocol/direct-lib/connection.ts
var logger$4 = getLogger("qq-conn");
var TcpConnection = class extends EventEmitter {
	socket = null;
	buffer = Buffer.alloc(0);
	connected = false;
	async connect(options = {}) {
		const host = options.useIPv6 ? "msfwifiv6.3g.qq.com" : "msfwifi.3g.qq.com";
		const port = options.useIPv6 ? 14e3 : 8080;
		const addresses = await lookup(host, {
			all: true,
			family: options.useIPv6 ? 6 : 4
		});
		if (addresses.length === 0) throw new Error(`DNS resolution failed for ${host}`);
		const addr = addresses[0];
		return new Promise((resolve, reject) => {
			this.socket = new Socket();
			this.socket.setKeepAlive(true, 3e4);
			logger$4.info(`[QQ Server] Connecting to ${addr.address}:${port} (${host})...`);
			this.socket.on("connect", () => {
				this.connected = true;
				logger$4.info(`[QQ Server] Connected to ${addr.address}:${port}`);
				this.emit("connected");
				resolve();
			});
			this.socket.on("data", (chunk) => {
				this.buffer = Buffer.concat([this.buffer, chunk]);
				this.emit("rawdata", chunk);
				this.processFrames();
			});
			this.socket.on("error", (err) => {
				this.emit("error", err);
				if (!this.connected) reject(err);
			});
			this.socket.on("close", () => {
				this.connected = false;
				this.emit("close");
			});
			this.socket.connect(port, addr.address);
		});
	}
	processFrames() {
		while (this.buffer.length >= 4) {
			const frameLen = this.buffer.readUInt32BE(0);
			if (frameLen > 67108864) {
				this.emit("error", /* @__PURE__ */ new Error(`Frame too large: ${frameLen}`));
				this.disconnect();
				return;
			}
			if (this.buffer.length < frameLen) break;
			const frame = this.buffer.subarray(4, frameLen);
			this.buffer = this.buffer.subarray(frameLen);
			this.emit("packet", Buffer.from(frame));
		}
	}
	send(data) {
		if (!this.socket || !this.connected) throw new Error("Not connected");
		this.emit("send", data);
		this.socket.write(data);
	}
	disconnect() {
		if (this.socket) {
			this.socket.destroy();
			this.socket = null;
		}
		this.connected = false;
	}
	get isConnected() {
		return this.connected;
	}
};
//#endregion
//#region src/main/qqProtocol/direct-lib/tea.ts
/**
* TEA cipher implementation (Tencent QQ variant)
* 16-round TEA with QQ-specific CBC chaining and random padding
*/
var DELTA = 2654435769;
var ROUNDS = 16;
function toUint32(n) {
	return n >>> 0;
}
function teaEncryptBlock(v0, v1, key) {
	let sum = 0;
	for (let i = 0; i < ROUNDS; i++) {
		sum = toUint32(sum + DELTA);
		v0 = toUint32(v0 + toUint32(toUint32(v1 << 4) + key[0] ^ toUint32(v1 + sum) ^ toUint32(v1 >>> 5) + key[1]));
		v1 = toUint32(v1 + toUint32(toUint32(v0 << 4) + key[2] ^ toUint32(v0 + sum) ^ toUint32(v0 >>> 5) + key[3]));
	}
	return [v0, v1];
}
function teaDecryptBlock(v0, v1, key) {
	let sum = toUint32(DELTA * ROUNDS);
	for (let i = 0; i < ROUNDS; i++) {
		v1 = toUint32(v1 - toUint32(toUint32(v0 << 4) + key[2] ^ toUint32(v0 + sum) ^ toUint32(v0 >>> 5) + key[3]));
		v0 = toUint32(v0 - toUint32(toUint32(v1 << 4) + key[0] ^ toUint32(v1 + sum) ^ toUint32(v1 >>> 5) + key[1]));
		sum = toUint32(sum - DELTA);
	}
	return [v0, v1];
}
function readUint32BE(buf, offset) {
	return (buf[offset] << 24 | buf[offset + 1] << 16 | buf[offset + 2] << 8 | buf[offset + 3]) >>> 0;
}
function writeUint32BE(buf, offset, value) {
	buf[offset] = value >>> 24 & 255;
	buf[offset + 1] = value >>> 16 & 255;
	buf[offset + 2] = value >>> 8 & 255;
	buf[offset + 3] = value & 255;
}
function parseKey(key) {
	if (key.length !== 16) throw new Error("TEA key must be 16 bytes");
	return new Uint32Array([
		readUint32BE(key, 0),
		readUint32BE(key, 4),
		readUint32BE(key, 8),
		readUint32BE(key, 12)
	]);
}
function teaEncrypt(data, key) {
	const k = parseKey(key);
	const fill = 10 - (data.length + 1 & 7);
	const totalLen = fill + data.length + 7;
	const plain = new Uint8Array(totalLen);
	for (let i = 0; i < fill; i++) plain[i] = Math.floor(Math.random() * 256);
	plain[0] = fill - 3 & 7 | 248;
	plain.set(data, fill);
	const out = new Uint8Array(totalLen);
	plain.set(data, fill);
	out.set(plain);
	let plainXorHi = 0, plainXorLo = 0;
	let prevXorHi = 0, prevXorLo = 0;
	for (let i = 0; i < totalLen; i += 8) {
		const pHi = readUint32BE(out, i) ^ plainXorHi;
		const pLo = readUint32BE(out, i + 4) ^ plainXorLo;
		const [cHi, cLo] = teaEncryptBlock(pHi, pLo, k);
		plainXorHi = cHi ^ prevXorHi;
		plainXorLo = cLo ^ prevXorLo;
		prevXorHi = pHi;
		prevXorLo = pLo;
		writeUint32BE(out, i, plainXorHi);
		writeUint32BE(out, i + 4, plainXorLo);
	}
	return out;
}
function teaDecrypt(data, key) {
	const k = parseKey(key);
	if (data.length < 16 || data.length % 8 !== 0) throw new Error("TEA decrypt: invalid data length");
	const plain = new Uint8Array(data.length);
	let plainXorHi = 0, plainXorLo = 0;
	let prevXorHi = 0, prevXorLo = 0;
	for (let i = 0; i < data.length; i += 8) {
		const cHi = readUint32BE(data, i);
		const cLo = readUint32BE(data, i + 4);
		plainXorHi ^= cHi;
		plainXorLo ^= cLo;
		const [dHi, dLo] = teaDecryptBlock(plainXorHi, plainXorLo, k);
		plainXorHi = dHi;
		plainXorLo = dLo;
		writeUint32BE(plain, i, plainXorHi ^ prevXorHi);
		writeUint32BE(plain, i + 4, plainXorLo ^ prevXorLo);
		prevXorHi = cHi;
		prevXorLo = cLo;
	}
	const start = (plain[0] & 7) + 3;
	const end = data.length - 7;
	if (start >= end) throw new Error("TEA decrypt: invalid padding");
	return plain.slice(start, end);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/ssoReserved.ts
var HEX_CHARS = "0123456789abcdef";
function randomHex(len) {
	let result = "";
	for (let i = 0; i < len; i++) result += HEX_CHARS[Math.floor(Math.random() * 16)];
	return result;
}
function generateTraceParent() {
	return `01-${randomHex(32)}-${randomHex(16)}-01`;
}
function encodeVarint$1(value) {
	const bytes = [];
	while (value > 127) {
		bytes.push(value & 127 | 128);
		value >>>= 7;
	}
	bytes.push(value & 127);
	return Buffer.from(bytes);
}
function encodeTag(fieldNumber, wireType) {
	return encodeVarint$1(fieldNumber << 3 | wireType);
}
function encodeLengthDelimited(fieldNumber, data) {
	const tag = encodeTag(fieldNumber, 2);
	const len = encodeVarint$1(data.length);
	return Buffer.concat([
		tag,
		len,
		data
	]);
}
function encodeString(fieldNumber, value) {
	return encodeLengthDelimited(fieldNumber, Buffer.from(value, "utf-8"));
}
function buildSsoReservedField(uid, signResult) {
	const parts = [];
	parts.push(encodeString(15, generateTraceParent()));
	if (uid) parts.push(encodeString(16, uid));
	if (signResult) {
		const secParts = [];
		if (signResult.sign.length > 0) secParts.push(encodeLengthDelimited(1, signResult.sign));
		if (signResult.token.length > 0) secParts.push(encodeLengthDelimited(2, signResult.token));
		if (signResult.extra.length > 0) secParts.push(encodeLengthDelimited(3, signResult.extra));
		parts.push(encodeLengthDelimited(24, Buffer.concat(secParts)));
	}
	return Buffer.concat(parts);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/packet.ts
var EncryptType = /* @__PURE__ */ function(EncryptType) {
	EncryptType[EncryptType["NoEncrypt"] = 0] = "NoEncrypt";
	EncryptType[EncryptType["EncryptD2Key"] = 1] = "EncryptD2Key";
	EncryptType[EncryptType["EncryptEmpty"] = 2] = "EncryptEmpty";
	return EncryptType;
}({});
var EMPTY_KEY = Buffer.alloc(16);
var FIXED_HEADER = Buffer.from([
	2,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0
]);
function writeInt32Prefixed(data) {
	const len = Buffer.alloc(4);
	len.writeInt32BE(data.length + 4);
	return Buffer.concat([len, data]);
}
function writeInt32PrefixedString(str) {
	return writeInt32Prefixed(Buffer.from(str));
}
function writeInt16PrefixedString(str) {
	const strBuf = Buffer.from(str);
	const len = Buffer.alloc(2);
	len.writeInt16BE(strBuf.length + 2);
	return Buffer.concat([len, strBuf]);
}
function buildSsoHead12(seq, cmd, ctx, signResult) {
	const parts = [];
	const seqBuf = Buffer.alloc(4);
	seqBuf.writeInt32BE(seq);
	parts.push(seqBuf);
	const subAppBuf = Buffer.alloc(4);
	subAppBuf.writeInt32BE(ctx.subAppId);
	parts.push(subAppBuf);
	const fixed2052 = Buffer.alloc(4);
	fixed2052.writeInt32BE(2052);
	parts.push(fixed2052);
	parts.push(FIXED_HEADER);
	parts.push(writeInt32Prefixed(ctx.tgt));
	parts.push(writeInt32PrefixedString(cmd));
	parts.push(writeInt32Prefixed(Buffer.alloc(0)));
	parts.push(writeInt32PrefixedString(ctx.guid.toString("hex")));
	parts.push(writeInt32Prefixed(Buffer.alloc(0)));
	parts.push(writeInt16PrefixedString(ctx.buildVer));
	const reservedField = buildSsoReservedField(ctx.uid || void 0, signResult);
	parts.push(writeInt32Prefixed(reservedField));
	return writeInt32Prefixed(Buffer.concat(parts));
}
function buildSsoHead13(cmd, ctx) {
	const parts = [];
	parts.push(writeInt32PrefixedString(cmd));
	parts.push(writeInt32Prefixed(Buffer.alloc(0)));
	const reservedField = buildSsoReservedField(ctx.uid || void 0);
	parts.push(writeInt32Prefixed(reservedField));
	return writeInt32Prefixed(Buffer.concat(parts));
}
function buildSsoFrame13(cmd, ctx, payload) {
	const head = buildSsoHead13(cmd, ctx);
	const payloadWithLen = writeInt32Prefixed(payload);
	return Buffer.concat([head, payloadWithLen]);
}
function buildServicePacket13(seq, cmd, ctx, payload, encryptType = 0) {
	const ssoFrame = buildSsoFrame13(cmd, ctx, payload);
	let encrypted;
	switch (encryptType) {
		case 1:
			encrypted = Buffer.from(teaEncrypt(ssoFrame, ctx.d2Key));
			break;
		case 2:
			encrypted = Buffer.from(teaEncrypt(ssoFrame, EMPTY_KEY));
			break;
		default: encrypted = ssoFrame;
	}
	const parts = [];
	const verBuf = Buffer.alloc(4);
	verBuf.writeInt32BE(13);
	parts.push(verBuf);
	parts.push(Buffer.from([encryptType]));
	const seqBuf = Buffer.alloc(4);
	seqBuf.writeInt32BE(seq);
	parts.push(seqBuf);
	parts.push(Buffer.from([0]));
	parts.push(writeInt32PrefixedString(ctx.uin));
	parts.push(encrypted);
	const innerPacket = Buffer.concat(parts);
	const frame = Buffer.alloc(4 + innerPacket.length);
	frame.writeInt32BE(4 + innerPacket.length);
	innerPacket.copy(frame, 4);
	return frame;
}
function buildSsoFrame12(seq, cmd, ctx, payload, signResult) {
	const head = buildSsoHead12(seq, cmd, ctx, signResult);
	const payloadWithLen = writeInt32Prefixed(payload);
	return Buffer.concat([head, payloadWithLen]);
}
function buildServicePacket(seq, cmd, ctx, payload, encryptType = 1, signResult) {
	const ssoFrame = buildSsoFrame12(seq, cmd, ctx, payload, signResult);
	let encrypted;
	switch (encryptType) {
		case 1:
			encrypted = Buffer.from(teaEncrypt(ssoFrame, ctx.d2Key));
			break;
		case 2:
			encrypted = Buffer.from(teaEncrypt(ssoFrame, EMPTY_KEY));
			break;
		case 0: encrypted = ssoFrame;
	}
	const parts = [];
	const verBuf = Buffer.alloc(4);
	verBuf.writeInt32BE(12);
	parts.push(verBuf);
	parts.push(Buffer.from([encryptType]));
	if (encryptType === 1 && ctx.d2.length > 0) parts.push(writeInt32Prefixed(ctx.d2));
	else {
		const emptyD2 = Buffer.alloc(4);
		emptyD2.writeInt32BE(4);
		parts.push(emptyD2);
	}
	parts.push(Buffer.from([0]));
	parts.push(writeInt32PrefixedString(ctx.uin));
	parts.push(encrypted);
	const innerPacket = Buffer.concat(parts);
	const frame = Buffer.alloc(4 + innerPacket.length);
	frame.writeInt32BE(4 + innerPacket.length);
	innerPacket.copy(frame, 4);
	return frame;
}
function parseServicePacket(frame, d2Key) {
	let offset = 0;
	frame.readInt32BE(offset);
	offset += 4;
	const encType = frame.readUInt8(offset);
	offset += 1;
	offset += 1;
	const uinLen = frame.readInt32BE(offset);
	offset += 4;
	if (uinLen > 4) offset += uinLen - 4;
	const encBody = frame.subarray(offset);
	let ssoBody;
	try {
		switch (encType) {
			case 1:
				ssoBody = Buffer.from(teaDecrypt(encBody, d2Key));
				break;
			case 2:
				ssoBody = Buffer.from(teaDecrypt(encBody, EMPTY_KEY));
				break;
			default: ssoBody = Buffer.from(encBody);
		}
	} catch {
		return null;
	}
	return parseSsoFrame12(ssoBody);
}
function parseSsoFrame12(data) {
	let offset = 0;
	if (offset + 4 > data.length) return null;
	const headLen = data.readInt32BE(offset);
	offset += 4;
	const headEnd = offset + headLen - 4;
	if (headEnd > data.length) return null;
	const seq = data.readInt32BE(offset);
	offset += 4;
	const retCode = data.readInt32BE(offset);
	offset += 4;
	if (offset + 4 > headEnd) return null;
	const extraLen = data.readInt32BE(offset);
	offset += 4;
	let extraMsg = "";
	if (extraLen > 4) {
		extraMsg = data.subarray(offset, offset + extraLen - 4).toString("utf8");
		offset += extraLen - 4;
	}
	if (offset + 4 > headEnd) return null;
	const cmdLen = data.readInt32BE(offset);
	offset += 4;
	const cmd = data.subarray(offset, offset + cmdLen - 4).toString();
	offset += cmdLen - 4;
	offset = headEnd;
	if (offset + 4 > data.length) return null;
	const bodyLen = data.readInt32BE(offset);
	offset += 4;
	let payload = Buffer.from(data.subarray(offset, offset + bodyLen - 4));
	if (payload.length >= 2 && payload[0] === 120 && (payload[1] === 1 || payload[1] === 156 || payload[1] === 218)) try {
		const inflated = inflateSync(payload);
		payload = Buffer.from(inflated);
	} catch {}
	return {
		seq,
		cmd,
		payload,
		retCode,
		extraMsg
	};
}
//#endregion
//#region src/main/qqProtocol/direct-lib/ecdh.ts
var SERVER_PUBLIC_KEY_192K1 = Buffer.from([
	4,
	146,
	141,
	136,
	80,
	103,
	48,
	136,
	179,
	67,
	38,
	78,
	12,
	107,
	172,
	184,
	73,
	109,
	105,
	119,
	153,
	243,
	114,
	17,
	222,
	178,
	91,
	183,
	57,
	6,
	203,
	8,
	159,
	234,
	150,
	57,
	180,
	224,
	38,
	4,
	152,
	181,
	26,
	153,
	45,
	80,
	129,
	61,
	168
]);
function generateEcdhKeyPair() {
	const ecdh = createECDH("secp192k1");
	const rawPublicKey = ecdh.generateKeys();
	const publicKey = Buffer.concat([Buffer.from([2]), rawPublicKey.subarray(1, 25)]);
	const sharedSecret = ecdh.computeSecret(SERVER_PUBLIC_KEY_192K1);
	const shareKey = createHash("md5").update(sharedSecret).digest().subarray(0, 16);
	return {
		publicKey,
		privateKey: Buffer.from(ecdh.getPrivateKey()),
		shareKey
	};
}
//#endregion
//#region src/main/qqProtocol/direct-lib/sign-proxy/index.ts
var here = dirname(fileURLToPath(import.meta.url));
var requireBin = createRequire(import.meta.url);
function isMusl() {
	if (process.platform !== "linux") return false;
	try {
		const report = process.report?.getReport?.() ?? {};
		if (report.header && "glibcVersionRuntime" in report.header) return !report.header.glibcVersionRuntime;
	} catch {}
	return existsSync("/etc/alpine-release") || existsSync("/lib/ld-musl-x86_64.so.1") || existsSync("/lib/ld-musl-aarch64.so.1");
}
function pickTriple() {
	const p = process.platform;
	const a = process.arch;
	if (p === "win32" && a === "x64") return "win-x64";
	if (p === "win32" && a === "arm64") return "win-arm64";
	if (p === "linux" && a === "x64") return isMusl() ? "linux-x64-musl" : "linux-x64-glibc";
	if (p === "linux" && a === "arm64") return isMusl() ? "linux-arm64-musl" : "linux-arm64-glibc";
	if (p === "darwin" && a === "x64") return "darwin-x64";
	if (p === "darwin" && a === "arm64") return "darwin-arm64";
	throw new Error(`sign-proxy: unsupported platform ${p}-${a}; rebuild lucky-lillia-sign-proxy on this target and drop the .node into ${here}`);
}
/** 读 sign-proxy 版本号. 版本号塞进 tmpdir 文件名做 .node 热更新缓存 key. */
function pickVersion() {
	try {
		const pkg = JSON.parse(readFileSync(join(here, "sign-proxy.package.json"), "utf-8"));
		if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
	} catch {}
	return "0.0.0";
}
/**
* 把同目录的 .node 拷到 tmpdir/lucky-lillia-sign-proxy/sign-proxy.<triple>.<version>.node 再 require.
*
* 为什么转一道: Bot 跑着时 require 的 .node 文件被 OS 锁定 (Windows 尤甚), 无法被
* `npm run build:dev-bot` / 外部部署脚本覆盖 -- 等于阻止热更新. 转 tmpdir + 把版本号
* 串进文件名后, 升级时 src/ 目录 .node 随便覆盖 (它没被 require), 重启 Bot 时
* version bump -> 新 tmpdir 路径 -> 新文件被复制并 require, 旧 tmpdir 副本留着不影响.
*
* 复制策略 (existsSync 优先, copy 失败 swallow):
*   1. 目标已存在 -> 直接用, 不复制 (这是 99% 的情况, 同一版本第二次起 Bot)
*   2. 不存在 -> copyFileSync; 失败 (e.g. tmpdir 写不进) -> fallback 到原路径加载
*      (开发场景方便; 生产 tmpdir 总该可写)
*/
function ensureLoadablePath(srcPath, version, triple) {
	const cacheRoot = join(tmpdir(), "lucky-lillia-sign-proxy");
	const cachedName = `sign-proxy.${triple}.${version}.node`;
	const cachedPath = join(cacheRoot, cachedName);
	if (existsSync(cachedPath)) return cachedPath;
	try {
		mkdirSync(cacheRoot, { recursive: true });
		copyFileSync(srcPath, cachedPath);
		return cachedPath;
	} catch (e) {
		getLogger("sign-proxy").warn(`[sign-proxy] hot-update copy failed (${e.message}); falling back to ${srcPath}`);
		return srcPath;
	}
}
var triple = pickTriple();
var version = pickVersion();
var loadPath = ensureLoadablePath(join(here, `sign-proxy.${triple}.node`), version, triple);
var native;
function getSignProxy() {
	try {
		native ??= requireBin(loadPath);
		return native;
	} catch (error) {
		const { message } = error;
		throw new Error(`sign-proxy: failed to load ${loadPath}: ${message}`);
	}
}
//#endregion
//#region src/main/qqProtocol/direct-lib/sign.ts
var logger$3 = getLogger("sign");
var inited = false;
var initError;
async function setupSign(opts) {
	if (opts.machineGuid.length !== 16) throw new Error(`setupSign expected 16B machineGuid, got ${opts.machineGuid.length}B`);
	try {
		await getSignProxy().init({
			botVersion: opts.botVersion,
			authToken: opts.authToken,
			machineGuidHex: opts.machineGuid.toString("hex"),
			uin: opts.uin
		}, opts.sendPacket, opts.logger ?? defaultLogger);
		inited = true;
	} catch (error) {
		initError = error;
		throw error;
	}
}
function setSignMachineGuid(guid) {
	if (guid.length !== 16) {
		logger$3.warn(`[Sign] setSignMachineGuid expected 16B GUID, got ${guid.length}B -- skip`);
		return;
	}
	if (!inited) return;
	const { setMachineGuid } = getSignProxy();
	if (typeof setMachineGuid !== "function") {
		logger$3.warn("[Sign] sign-proxy 未导出 setMachineGuid (老版 .node), GUID 切换不会生效.");
		return;
	}
	try {
		setMachineGuid(guid.toString("hex"));
	} catch (e) {
		logger$3.warn(`[Sign] setMachineGuid failed: ${e.message}`);
	}
}
function defaultLogger(log) {
	(log.level === "error" ? logger$3.error : logger$3.warn)(`[Sign/${log.level}] ${log.message}`);
}
async function updateAuthToken(authToken) {
	if (inited) await getSignProxy().setAuthToken(authToken);
}
async function requestSign(cmd, src, seq, guid, qua, uin, protocolToken12B) {
	if (!inited) {
		if (initError) {
			const { message } = initError;
			logger$3.error(`[Sign] sign 未初始化, ${message}`);
		} else logger$3.error("[Sign] sign 未初始化");
		return null;
	}
	try {
		const r = await getSignProxy().signRequest({
			cmd,
			bodyHex: src.toString("hex"),
			seq,
			guidHex: guid?.toString("hex") ?? "",
			qua: qua ?? "",
			uin: uin ?? 0,
			protocolTokenHex: protocolToken12B ? Buffer.from(protocolToken12B, "utf-8").toString("hex") : ""
		});
		logger$3.debug(`${cmd} seq=${seq}: sign=${r.sign.length}B token=${r.token.length}B extra=${r.extra.length}B`);
		return {
			sign: r.sign,
			token: r.token,
			extra: r.extra
		};
	} catch (e) {
		formatNativeSignError(cmd, qua, e);
		return null;
	}
}
async function acquireSignToken(uin, qua) {
	if (!inited) throw new Error("sign not initialized");
	return {
		token: (await getSignProxy().acquireSignToken({
			uin,
			qua
		})).token.toString("utf-8"),
		ttlSecs: 86400
	};
}
function formatNativeSignError(cmd, qua, e) {
	const msg = e.message;
	const m = /^http (\d+):\s*(.*)$/.exec(msg);
	if (m) {
		const code = Number(m[1]);
		const detail = m[2];
		switch (code) {
			case 401:
				logger$3.error(`[Sign] Unauthorized (cmd=${cmd}): ${detail}. auth_token 无效或已撤销, 到 manager 重新生成`);
				return;
			case 403:
				logger$3.error(`[Sign] Forbidden (cmd=${cmd}): ${detail}`);
				authTokenStatus.loginError = detail || "auth_token 无权限 (HTTP 403)";
				return;
			case 502:
				logger$3.error(`[Sign] Bad Gateway (cmd=${cmd}): ${detail}. 上游 sign-service 进程不可用`);
				return;
			case 503:
				logger$3.error(`[Sign] Service Unavailable (cmd=${cmd}): ${detail}. 没有匹配的 sign 后端 (qua=${qua ?? "<empty>"})`);
				return;
			default:
				logger$3.error(`[Sign] HTTP ${code} (cmd=${cmd}): ${detail}`);
				return;
		}
	}
	if (msg.startsWith("network:")) {
		logger$3.error(`[Sign] Network error (cmd=${cmd}): ${msg.slice(9)}`);
		return;
	}
	if (msg === "not initialized; call init() first") {
		logger$3.error(`[Sign] ${msg} (cmd=${cmd})`);
		return;
	}
	if (msg.startsWith("malformed response:")) {
		logger$3.error(`[Sign] Failed to parse response (cmd=${cmd}): ${msg.slice(20)}`);
		return;
	}
	if (msg.startsWith("server returned non-zero code:")) {
		const code = msg.slice(31);
		logger$3.error(`[Sign] Server returned non-zero code ${code} (cmd=${cmd})`);
		return;
	}
	logger$3.error(`[Sign] ${msg} (cmd=${cmd})`);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/client.ts
var logger$2 = getLogger("direct");
var DEFAULT_CONFIG = {
	appId: AppInfo.appId,
	subAppId: AppInfo.subAppId,
	ssoVersion: AppInfo.ssoVersion,
	buildVer: AppInfo.buildVer,
	useIPv6: false
};
var DirectProtocolClient = class extends EventEmitter {
	conn;
	config;
	ecdhKeyPair;
	guid;
	seq = Math.random() * 16777215 >>> 0;
	session = null;
	signSetupDone = false;
	pendingPackets = /* @__PURE__ */ new Map();
	signTokenRefreshInflight = null;
	signTokenLastFetchAt = 0;
	heartbeatAliveTimer = null;
	constructor(config = {}) {
		super();
		this.config = {
			...DEFAULT_CONFIG,
			...config
		};
		this.guid = loadMachineGuidSync();
		this.conn = new TcpConnection();
		this.ecdhKeyPair = generateEcdhKeyPair();
		this.conn.on("packet", (frame) => this.handlePacket(frame));
		this.conn.on("error", (err) => this.emit("error", err));
		this.conn.on("close", () => {
			this.stopHeartbeatAlive();
			this.emit("close");
		});
	}
	/**
	* 起 sign 链路: 建 native Client + 注册 send_packet/logger; 配置里带了 uin 时 await /api/bu bind.
	* native init 是 async, 必须在能 await 的地方跑 (不能塞构造函数) -- 故由 connect() 调.
	* 幂等: 二次调直接返回 (native init 二次也是 no-op). bind 失败时 reject 会从 connect() 冒出去.
	*/
	async ensureSignSetup() {
		if (this.signSetupDone || !this.config.authToken) return;
		this.signSetupDone = true;
		await setupSign({
			botVersion: this.config.botVersion ?? "unknown",
			authToken: this.config.authToken,
			machineGuid: this.guid,
			uin: this.config.uin,
			sendPacket: async ({ cmd, body }) => {
				const resp = (await this.sendCommand(cmd, Buffer.from(body))).payload;
				logger$2.debug(`[relay] ${cmd}: req=${body.length}B resp=${resp.length}B hex=%h`, resp);
				return resp;
			}
		});
	}
	async connect() {
		await this.ensureSignSetup();
		await this.conn.connect({ useIPv6: this.config.useIPv6 });
		this.emit("connected");
		await this.sendHeartbeat();
		this.startHeartbeatAlive();
	}
	/** 周期性发 Heartbeat.Alive 保活连接层. connect() 启动, disconnect()/close 清理. 幂等. */
	startHeartbeatAlive() {
		if (this.heartbeatAliveTimer) return;
		const INTERVAL = 15e3;
		this.heartbeatAliveTimer = setInterval(() => {
			this.sendHeartbeat().catch((e) => {
				logger$2.error("[Heartbeat.Alive] Failed:", e.message);
			});
		}, INTERVAL);
	}
	stopHeartbeatAlive() {
		if (this.heartbeatAliveTimer) {
			clearInterval(this.heartbeatAliveTimer);
			this.heartbeatAliveTimer = null;
		}
	}
	async sendHeartbeat() {
		const seq = this.nextSeq();
		const ctx = this.getPacketContext();
		const payload = Buffer.alloc(4);
		payload.writeUInt32BE(4);
		const packet = buildServicePacket13(seq, "Heartbeat.Alive", ctx, payload, EncryptType.NoEncrypt);
		return new Promise((resolve, reject) => {
			const timer = setTimeout(() => {
				this.pendingPackets.delete(seq);
				resolve();
			}, 5e3);
			this.pendingPackets.set(seq, {
				resolve: () => {
					clearTimeout(timer);
					resolve();
				},
				reject: (err) => {
					clearTimeout(timer);
					reject(err);
				},
				timeout: timer
			});
			this.conn.send(packet);
		});
	}
	disconnect() {
		this.stopHeartbeatAlive();
		this.conn.disconnect();
		for (const [, pending] of this.pendingPackets) {
			clearTimeout(pending.timeout);
			pending.reject(/* @__PURE__ */ new Error("Disconnected"));
		}
		this.pendingPackets.clear();
	}
	nextSeq() {
		return this.seq++;
	}
	getPacketContext() {
		return {
			uin: this.session?.uin || "0",
			uid: this.session?.uid || "",
			d2: this.session?.d2 || Buffer.alloc(0),
			d2Key: this.session?.d2Key || Buffer.alloc(16),
			tgt: this.session?.tgt || Buffer.alloc(0),
			guid: this.guid,
			appId: this.config.appId,
			subAppId: this.config.subAppId,
			buildVer: this.config.buildVer
		};
	}
	SIGN_ALLOWLIST = /* @__PURE__ */ new Set([
		"AvatarInfoSvr.QQHeadUrlReq",
		"CertifiedAccountSvc.certified_account_read.GetFollowList",
		"ConfigPushSvc.PushResp",
		"ConnAuthSvr.fast_qq_login",
		"ConnAuthSvr.get_app_info",
		"ConnAuthSvr.get_app_info_emp",
		"ConnAuthSvr.get_auth_api_list",
		"ConnAuthSvr.get_auth_api_list_emp",
		"ConnAuthSvr.sdk_auth_api",
		"ConnAuthSvr.sdk_auth_api_emp",
		"FeedCloudSvr.trpc.circlesearch.exhibition.ExhibitionSvr.ExhibitionSuggestion",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetBusiInfo",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetCommentList",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetFeedList",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetMainPageBasicData",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetMainPageCommData",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetRelationGroupList",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetReplyList",
		"FeedCloudSvr.trpc.feedcloud.commreader.ComReader.GetRerankedFeedList",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoBarrage",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoComment",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoFollow",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoLike",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoPush",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoReply",
		"FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.PublishFeed",
		"FeedCloudSvr.trpc.videocircle.circleprofile.CircleProfile.SetProfile",
		"GameCenterMsg.GetUserInfo",
		"HttpConn.0x6ff_501",
		"IncreaseURLSvr.QQHeadUrlReq",
		"LightAppSvc.mini_app_cloudstorage.GetUserCloudStorage",
		"LightAppSvc.mini_app_privacy.GetPrivacyInfo",
		"LightAppSvc.mini_app_userapp.GetDropdownAppList",
		"MQUpdateSvc_com_qq_qzone_act.web.OidbSvcTrpcJsapiTcp.0x9377_0",
		"MQUpdateSvc_com_qq_ti.web.OidbSvcTrpcJsapiTcp.0x9044_0",
		"MQUpdateSvc_com_qq_ti.web.OidbSvcTrpcJsapiTcp.0x9047_0",
		"MQUpdateSvc_com_qq_ti.web.OidbSvcTrpcJsapiTcp.0x9172_0",
		"MessageSvc.PbBindUinGetMsg",
		"MessageSvc.PbGetGroupMsg",
		"MessageSvc.PbGetMsg",
		"MessageSvc.PbGetRoamMsg",
		"MessageSvc.PbSendMsg",
		"MsgProxy.SendMsg",
		"NowSummaryCard.NearbyMiniCardReq",
		"OidbSvc.0x42d",
		"OidbSvc.0x42d_4",
		"OidbSvc.0x480_9",
		"OidbSvc.0x480_9_IMCore",
		"OidbSvc.0x4ff_9",
		"OidbSvc.0x4ff_9_IMCore",
		"OidbSvc.0x515_2",
		"OidbSvc.0x53c_2",
		"OidbSvc.0x56c_6",
		"OidbSvc.0x570_8",
		"OidbSvc.0x580_1",
		"OidbSvc.0x587_123",
		"OidbSvc.0x587_normalNightSet",
		"OidbSvc.0x58b",
		"OidbSvc.0x592",
		"OidbSvc.0x592_1",
		"OidbSvc.0x592_10",
		"OidbSvc.0x592_11",
		"OidbSvc.0x592_12",
		"OidbSvc.0x592_13",
		"OidbSvc.0x592_15",
		"OidbSvc.0x592_16",
		"OidbSvc.0x592_17",
		"OidbSvc.0x592_18",
		"OidbSvc.0x592_19",
		"OidbSvc.0x592_2",
		"OidbSvc.0x592_3",
		"OidbSvc.0x592_4",
		"OidbSvc.0x592_5",
		"OidbSvc.0x592_6",
		"OidbSvc.0x592_7",
		"OidbSvc.0x592_8",
		"OidbSvc.0x592_9",
		"OidbSvc.0x59f",
		"OidbSvc.0x5d0_1",
		"OidbSvc.0x5eb_15",
		"OidbSvc.0x5eb_22",
		"OidbSvc.0x5eb_42073",
		"OidbSvc.0x5eb_42261",
		"OidbSvc.0x5eb_43",
		"OidbSvc.0x5eb_96",
		"OidbSvc.0x5eb_99",
		"OidbSvc.0x5eb_ForTheme",
		"OidbSvc.0x5eb_cn_switch",
		"OidbSvc.0x5eb_common",
		"OidbSvc.0x6d6_0",
		"OidbSvc.0x6d6_2",
		"OidbSvc.0x6d6_3",
		"OidbSvc.0x6d7_0",
		"OidbSvc.0x6d9_4",
		"OidbSvc.0x6de",
		"OidbSvc.0x758",
		"OidbSvc.0x758_0",
		"OidbSvc.0x758_1",
		"OidbSvc.0x787_0",
		"OidbSvc.0x787_1",
		"OidbSvc.0x787_11",
		"OidbSvc.0x7a2_0",
		"OidbSvc.0x7df_3",
		"OidbSvc.0x852_35",
		"OidbSvc.0x852_48",
		"OidbSvc.0x88d_0",
		"OidbSvc.0x88d_1",
		"OidbSvc.0x88d_1_2",
		"OidbSvc.0x88d_7",
		"OidbSvc.0x899_0",
		"OidbSvc.0x899_9",
		"OidbSvc.0x89a_0",
		"OidbSvc.0x89b_1",
		"OidbSvc.0x8a0_0",
		"OidbSvc.0x8a1_0",
		"OidbSvc.0x8a1_7",
		"OidbSvc.0x8a4",
		"OidbSvc.0x8a8",
		"OidbSvc.0x8ba",
		"OidbSvc.0x8f1",
		"OidbSvc.0x9fa",
		"OidbSvc.0xb3c",
		"OidbSvc.0xb3c_1",
		"OidbSvc.0xb3c_2",
		"OidbSvc.0xb3c_3",
		"OidbSvc.0xb3c_4",
		"OidbSvc.0xb3c_5",
		"OidbSvc.0xb3c_6",
		"OidbSvc.0xb3c_7",
		"OidbSvc.0xb3c_8",
		"OidbSvc.0xb3c_add",
		"OidbSvc.0xb3c_delete",
		"OidbSvc.0xb3c_get_by_id",
		"OidbSvc.0xb3c_get_done",
		"OidbSvc.0xb3c_get_done_count",
		"OidbSvc.0xb3c_get_undone",
		"OidbSvc.0xb3c_share",
		"OidbSvc.0xb3c_update",
		"OidbSvc.0xb3c_update_5",
		"OidbSvc.0xb77_34",
		"OidbSvc.0xb77_46",
		"OidbSvc.0xb77_48",
		"OidbSvc.0xb77_9",
		"OidbSvc.0xbbb",
		"OidbSvc.0xbcb",
		"OidbSvc.0xbe8",
		"OidbSvc.0xc26_0",
		"OidbSvc.0xc33_42220",
		"OidbSvc.0xc6b",
		"OidbSvc.0xcd5",
		"OidbSvc.0xcdd",
		"OidbSvc.0xd69",
		"OidbSvc.0xdc2_34",
		"OidbSvc.0xdc2_9",
		"OidbSvc.0xe27",
		"OidbSvc.0xe3e",
		"OidbSvc.0xe61",
		"OidbSvc.0xe63_1",
		"OidbSvc.0xe72",
		"OidbSvc.0xef0_1",
		"OidbSvc.0xf7e_1",
		"OidbSvc.oidb_0x758",
		"OidbSvcTRPCTcp.0x758_1",
		"OidbSvcTRPCTcp.0xf67_1",
		"OidbSvcTcp.0x102a",
		"OidbSvcTcp.0x88d_0",
		"OidbSvcTcp.0x88d_1",
		"OidbSvcTcp.0xef0_1",
		"OidbSvcTrpcTcp.0x1017_1",
		"OidbSvcTrpcTcp.0x101b_1",
		"OidbSvcTrpcTcp.0x101e_1",
		"OidbSvcTrpcTcp.0x101e_2",
		"OidbSvcTrpcTcp.0x102a_0",
		"OidbSvcTrpcTcp.0x102a_1",
		"OidbSvcTrpcTcp.0x102a_3",
		"OidbSvcTrpcTcp.0x105b_1",
		"OidbSvcTrpcTcp.0x1092_0",
		"OidbSvcTrpcTcp.0x10c0_1",
		"OidbSvcTrpcTcp.0x10c0_2",
		"OidbSvcTrpcTcp.0x10c8_1",
		"OidbSvcTrpcTcp.0x10c8_2",
		"OidbSvcTrpcTcp.0x10d8_1",
		"OidbSvcTrpcTcp.0x10db_1",
		"OidbSvcTrpcTcp.0x10e4_1",
		"OidbSvcTrpcTcp.0x10ed_1",
		"OidbSvcTrpcTcp.0x10f4_1",
		"OidbSvcTrpcTcp.0x1100_1",
		"OidbSvcTrpcTcp.0x1102_1",
		"OidbSvcTrpcTcp.0x1103_1",
		"OidbSvcTrpcTcp.0x1105_1",
		"OidbSvcTrpcTcp.0x1107_1",
		"OidbSvcTrpcTcp.0x110d_1",
		"OidbSvcTrpcTcp.0x112a_1",
		"OidbSvcTrpcTcp.0x112a_2",
		"OidbSvcTrpcTcp.0x112e_1",
		"OidbSvcTrpcTcp.0x1130_1",
		"OidbSvcTrpcTcp.0x116c_1",
		"OidbSvcTrpcTcp.0x116d_1",
		"OidbSvcTrpcTcp.0x1194_1",
		"OidbSvcTrpcTcp.0x11c4_100",
		"OidbSvcTrpcTcp.0x11c4_200",
		"OidbSvcTrpcTcp.0x11c5_100",
		"OidbSvcTrpcTcp.0x11c5_200",
		"OidbSvcTrpcTcp.0x11e9_100",
		"OidbSvcTrpcTcp.0x11e9_200",
		"OidbSvcTrpcTcp.0x11ea_200",
		"OidbSvcTrpcTcp.0x11ec_1",
		"OidbSvcTrpcTcp.0x121e_0",
		"OidbSvcTrpcTcp.0x1224_0",
		"OidbSvcTrpcTcp.0x1225_0",
		"OidbSvcTrpcTcp.0x123c_1",
		"OidbSvcTrpcTcp.0x1250_0",
		"OidbSvcTrpcTcp.0x1258_1",
		"OidbSvcTrpcTcp.0x125b_500",
		"OidbSvcTrpcTcp.0x1262_19",
		"OidbSvcTrpcTcp.0x126d_200",
		"OidbSvcTrpcTcp.0x126e_200",
		"OidbSvcTrpcTcp.0x1277_0",
		"OidbSvcTrpcTcp.0x127a_0",
		"OidbSvcTrpcTcp.0x1289_1",
		"OidbSvcTrpcTcp.0x12a9_200",
		"OidbSvcTrpcTcp.0x12b1_0",
		"OidbSvcTrpcTcp.0x55f_0",
		"OidbSvcTrpcTcp.0x587_74",
		"OidbSvcTrpcTcp.0x5cf_11",
		"OidbSvcTrpcTcp.0x644_1",
		"OidbSvcTrpcTcp.0x6d6_2",
		"OidbSvcTrpcTcp.0x6d6_3",
		"OidbSvcTrpcTcp.0x6d8_1",
		"OidbSvcTrpcTcp.0x6d9_2",
		"OidbSvcTrpcTcp.0x6d9_4",
		"OidbSvcTrpcTcp.0x758_1",
		"OidbSvcTrpcTcp.0x787_1",
		"OidbSvcTrpcTcp.0x7c1_1",
		"OidbSvcTrpcTcp.0x7c2_5",
		"OidbSvcTrpcTcp.0x88d_0",
		"OidbSvcTrpcTcp.0x88d_111",
		"OidbSvcTrpcTcp.0x88d_14",
		"OidbSvcTrpcTcp.0x899_0",
		"OidbSvcTrpcTcp.0x899_1",
		"OidbSvcTrpcTcp.0x899_9",
		"OidbSvcTrpcTcp.0x89a_0",
		"OidbSvcTrpcTcp.0x89a_15",
		"OidbSvcTrpcTcp.0x8a0_1",
		"OidbSvcTrpcTcp.0x8a1_7",
		"OidbSvcTrpcTcp.0x8f9_14",
		"OidbSvcTrpcTcp.0x8fc_3",
		"OidbSvcTrpcTcp.0x901f_1",
		"OidbSvcTrpcTcp.0x902e_1",
		"OidbSvcTrpcTcp.0x9076_1",
		"OidbSvcTrpcTcp.0x9078_1",
		"OidbSvcTrpcTcp.0x9079_1",
		"OidbSvcTrpcTcp.0x911a_19",
		"OidbSvcTrpcTcp.0x911a_22",
		"OidbSvcTrpcTcp.0x9124_0",
		"OidbSvcTrpcTcp.0x9127_1",
		"OidbSvcTrpcTcp.0x9144_1",
		"OidbSvcTrpcTcp.0x9176_1",
		"OidbSvcTrpcTcp.0x917b_1",
		"OidbSvcTrpcTcp.0x91b6_1",
		"OidbSvcTrpcTcp.0x929b_0",
		"OidbSvcTrpcTcp.0x92d5_0",
		"OidbSvcTrpcTcp.0x92e3_0",
		"OidbSvcTrpcTcp.0x92e4_0",
		"OidbSvcTrpcTcp.0x92eb_0",
		"OidbSvcTrpcTcp.0x930d_0",
		"OidbSvcTrpcTcp.0x930e_0",
		"OidbSvcTrpcTcp.0x93d7_1",
		"OidbSvcTrpcTcp.0x9409_10",
		"OidbSvcTrpcTcp.0x9409_11",
		"OidbSvcTrpcTcp.0x9409_12",
		"OidbSvcTrpcTcp.0x9409_13",
		"OidbSvcTrpcTcp.0x9409_14",
		"OidbSvcTrpcTcp.0x9409_15",
		"OidbSvcTrpcTcp.0x9409_16",
		"OidbSvcTrpcTcp.0x9409_18",
		"OidbSvcTrpcTcp.0x9409_7",
		"OidbSvcTrpcTcp.0x9559_0",
		"OidbSvcTrpcTcp.0x955f_1",
		"OidbSvcTrpcTcp.0x9560_1",
		"OidbSvcTrpcTcp.0x962a_1",
		"OidbSvcTrpcTcp.0x9689_1",
		"OidbSvcTrpcTcp.0x972_6",
		"OidbSvcTrpcTcp.0x9a2_12",
		"OidbSvcTrpcTcp.0x9a2_8",
		"OidbSvcTrpcTcp.0xa80_1",
		"OidbSvcTrpcTcp.0xaf6_0",
		"OidbSvcTrpcTcp.0xb77_57",
		"OidbSvcTrpcTcp.0xcd5",
		"OidbSvcTrpcTcp.0xdc2_34",
		"OidbSvcTrpcTcp.0xe37_1200",
		"OidbSvcTrpcTcp.0xe37_1700",
		"OidbSvcTrpcTcp.0xe37_700",
		"OidbSvcTrpcTcp.0xe37_800",
		"OidbSvcTrpcTcp.0xf55_1",
		"OidbSvcTrpcTcp.0xf57_1",
		"OidbSvcTrpcTcp.0xf57_106",
		"OidbSvcTrpcTcp.0xf57_9",
		"OidbSvcTrpcTcp.0xf59_1",
		"OidbSvcTrpcTcp.0xf59_2",
		"OidbSvcTrpcTcp.0xf5b_1",
		"OidbSvcTrpcTcp.0xf5d_1",
		"OidbSvcTrpcTcp.0xf5d_11",
		"OidbSvcTrpcTcp.0xf65_1",
		"OidbSvcTrpcTcp.0xf65_10",
		"OidbSvcTrpcTcp.0xf67_1",
		"OidbSvcTrpcTcp.0xf67_5",
		"OidbSvcTrpcTcp.0xf6e_1",
		"OidbSvcTrpcTcp.0xf88_1",
		"OidbSvcTrpcTcp.0xf89_1",
		"OidbSvcTrpcTcp.0xfa5_1",
		"OidbSvcTrpcTcp.0xfc9_1",
		"OidbSvcTrpcTcp.0xfd4_1",
		"OidbSvcTrpcTcp.0xfe1",
		"OidbSvcTrpcTcp.0xfe1_2",
		"OidbSvcTrpcTcp.0xfe1_8",
		"OidbSvcTrpcTcp.0xfe4_2",
		"OidbSvcTrpcTcp.0xfe5_2",
		"OidbSvcTrpcTcp.0xfe7_2",
		"OidbSvcTrpcTcp.0xfe7_3",
		"OidbSvcTrpcTcp.0xfe7_4",
		"OidbSvc_device.0x633",
		"OidbSvc_device.0x9f5",
		"PbMessageSvc.PbUnReadMsgSeq",
		"ProfileService.GetSimpleInfo",
		"ProfileService.GroupMngReq",
		"ProfileService.Pb.ReqSystemMsgAction.Group",
		"ProfileService.Pb.ReqSystemMsgNew.Group",
		"ProfileService.ReqBatchProcess",
		"ProfileService.SimpleInfo",
		"ProfileService.getGroupInfoReq",
		"PttStore.GroupPttDown",
		"PubAccountSvc.get_follow_list",
		"PushService.settoken",
		"QChannelSvr.trpc.qchannel.commreader.ComReader.BatchGetFeedDetail",
		"QChannelSvr.trpc.qchannel.commwriter.ComWriter.DoComment",
		"QChannelSvr.trpc.qchannel.commwriter.ComWriter.DoReply",
		"QChannelSvr.trpc.qchannel.commwriter.ComWriter.PublishFeed",
		"QQAIOMediaSvc.share_trans_check",
		"QQConnectLogin.auth",
		"QQConnectLogin.auth_emp",
		"QQConnectLogin.get_promote_page",
		"QQConnectLogin.get_promote_page_emp",
		"QQConnectLogin.pre_auth",
		"QQConnectLogin.pre_auth_emp",
		"QQConnectLogin.submit_promote_page",
		"QQConnectLogin.submit_promote_page_emp",
		"QQLBSShareSvc.room_operation",
		"QQRTCSvc.RoomManager-GetRoomInfo",
		"QQStranger.FeedPlazaSvr.SsoFeedPublish",
		"QQStranger.FeedSvr.SsoFeedPublish",
		"QQStranger.InteractiveMsgSvr.SsoSendInterMsg",
		"QQStranger.UserInfo.SsoBatchGetMiniUserInfo",
		"QQStranger.UserInfo.SsoGetMiniUserInfo",
		"QQStranger.UserInfo.SsoSetMiniUserInfo",
		"QQStranger.login_svr.SsoLoginInfoReport",
		"QSec.AVEng",
		"RegPrxySvc.infoLogin",
		"RegPrxySvc.infoSync",
		"ResourceConfig.ClientReq",
		"ResourceConfig.GetResourceReq",
		"SQQzoneSvc.Custom.getFacade",
		"SQQzoneSvc.GetCate",
		"SQQzoneSvc.addComment",
		"SQQzoneSvc.addReply",
		"SQQzoneSvc.elaborateFeedReport",
		"SQQzoneSvc.forward",
		"SQQzoneSvc.get",
		"SQQzoneSvc.getAIONewestFeeds",
		"SQQzoneSvc.getActiveFeeds",
		"SQQzoneSvc.getMainPage",
		"SQQzoneSvc.getPhotoComment",
		"SQQzoneSvc.getPhotoWall",
		"SQQzoneSvc.getProfile",
		"SQQzoneSvc.getProfileFeeds",
		"SQQzoneSvc.getUndealCount",
		"SQQzoneSvc.getVisitorNotify",
		"SQQzoneSvc.get_all_feedsphoto_ex",
		"SQQzoneSvc.like",
		"SQQzoneSvc.mobileqboss.get",
		"SQQzoneSvc.photo",
		"SQQzoneSvc.preGetPassiveFeeds",
		"SQQzoneSvc.publishmood",
		"SQQzoneSvc.shuoshuo",
		"SecuritySvc.GetConfig",
		"SsoSnsSession.Cmd0x3_SubCmd0x1_FuncGetBlockList",
		"StatSvc.GetDevLoginInfo",
		"StatSvc.GetOnlineStatus",
		"StatSvc.SetStatusFromClient",
		"StatSvc.SimpleGet",
		"StatSvc.register",
		"SummaryCard.ReqSummaryCard",
		"VisitorSvc.ReqDeleteVisitorRecord",
		"VisitorSvc.ReqFavorite",
		"WalletGestureSvc.GetPassword",
		"WalletGestureSvc.GetSignV2",
		"WalletGestureSvc.SetPassword",
		"account.RequestQueryQQMobileContactsV3",
		"friendlist.AddFriendReq",
		"friendlist.GetFriendListReq",
		"friendlist.GetLastLoginInfoReq",
		"friendlist.GetMultiTroopInfoReq",
		"friendlist.GetSimpleOnlineFriendInfoReq",
		"friendlist.GetTroopAppointRemarkReq",
		"friendlist.GetTroopListReqV2",
		"friendlist.GetTroopMemberList",
		"friendlist.GetTroopMemberListReq",
		"friendlist.ModifyGroupInfoReq",
		"friendlist.addFriend",
		"friendlist.getFriendGroupList",
		"friendlist.getTroopMemberList",
		"gcbindgroupsso.get_appid",
		"gcbindgroupsso.unbind_group",
		"group_member_card.get_group_member_card_info",
		"group_member_statistic.get_group_member_statistic",
		"miniapp.trpc.minigame.sdk_qgroup_svr.sdk_qgroup_svr.JoinGroup",
		"oidb_0x42e_3",
		"oidb_0x43c_4",
		"oidb_0x43c_5",
		"oidb_0x5d0_1",
		"oidb_0x5d6_19",
		"oidb_0x5d6_21",
		"oidb_0x7a2_0",
		"oidb_0x7c4_0",
		"oidb_0x7df_3",
		"oidb_0x9045_1",
		"oidb_0x9072_0",
		"oidb_0xcf3_0",
		"oidb_0xcf4_0",
		"oidb_0xd9c_11",
		"oidb_0xdc2_34",
		"oidb_0xe37_1200",
		"oidb_0xe37_800",
		"oidb_0xe61_1",
		"oidb_0xe8c_0",
		"oidb_0xeb1_1",
		"oidb_0xf7e_1",
		"oidb_0xfd4_1",
		"qidianservice.135",
		"qidianservice.207",
		"qidianservice.269",
		"qidianservice.290",
		"qzoneh5.h5.wnshtml",
		"trpc.QQService.CommonLogic.StatusService.SsoGetLikeList",
		"trpc.commercial.dataworks.UserActionReport_sso.SsoReport",
		"trpc.down.intercept.Intercept.SsoGetDownloadTips",
		"trpc.down.intercept.Intercept.SsoGetInterceptFile",
		"trpc.down.joint_operation_game_intercept.JointOperationGameIntercept.SsoCheck",
		"trpc.down.joint_operation_game_intercept.JointOperationGameIntercept.SsoQueryConfig",
		"trpc.ecom.api_gateway.ApiGateway.SsoForward",
		"trpc.g_qqrtc.qq_mav_room_state_read.GetRoomState.SsoGetInfoByUin",
		"trpc.gc_indust.device_report.SsoHome.SsoHomeReport",
		"trpc.group.long_msg_interface.MsgService.SsoRecvLongMsg",
		"trpc.group.long_msg_interface.MsgService.SsoSendLongMsg",
		"trpc.group_pro.msgproxy.sendmsg",
		"trpc.group_pro.synclogic.SyncLogic.SyncFirstView",
		"trpc.login.ecdh.EcdhService.SsoKeyExchange",
		"trpc.login.ecdh.EcdhService.SsoNTLoginAuthCodeLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginAuthLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginAuthNewDevice",
		"trpc.login.ecdh.EcdhService.SsoNTLoginCheckA1List",
		"trpc.login.ecdh.EcdhService.SsoNTLoginCheckGateWayCode",
		"trpc.login.ecdh.EcdhService.SsoNTLoginCheckSms",
		"trpc.login.ecdh.EcdhService.SsoNTLoginCheckThirdCode",
		"trpc.login.ecdh.EcdhService.SsoNTLoginEasyLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginEasyLoginUnusualDevice",
		"trpc.login.ecdh.EcdhService.SsoNTLoginGetSaltList",
		"trpc.login.ecdh.EcdhService.SsoNTLoginGetSms",
		"trpc.login.ecdh.EcdhService.SsoNTLoginOptimusLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginPasswordLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginPasswordLoginNewDevice",
		"trpc.login.ecdh.EcdhService.SsoNTLoginPasswordLoginUnusualDevice",
		"trpc.login.ecdh.EcdhService.SsoNTLoginRapidLogin",
		"trpc.login.ecdh.EcdhService.SsoNTLoginRefreshA2",
		"trpc.login.ecdh.EcdhService.SsoNTLoginRefreshTicket",
		"trpc.login.ecdh.EcdhService.SsoNTLoginTGTExchangeFastLogin",
		"trpc.login.ecdh.EcdhService.SsoOIDB0x916a",
		"trpc.login.ecdh.EcdhService.SsoOIDB0x916b",
		"trpc.login.ecdh.EcdhService.SsoOIDB0x916c",
		"trpc.login.ecdh.EcdhService.SsoOIDB0x916d",
		"trpc.login.ecdh.EcdhService.SsoQRLoginAuthQr",
		"trpc.login.ecdh.EcdhService.SsoQRLoginCancleQr",
		"trpc.login.ecdh.EcdhService.SsoQRLoginGenQr",
		"trpc.login.ecdh.EcdhService.SsoQRLoginRejectQr",
		"trpc.login.ecdh.EcdhService.SsoQRLoginScanQr",
		"trpc.lplan.feed_svr.StatusWrite.SsoComment",
		"trpc.lplan.feed_svr.StatusWrite.SsoPostStatus",
		"trpc.lplan.feed_svr.StatusWrite.SsoReply",
		"trpc.lplan.like_svr.Like.SsoDoLike",
		"trpc.lplan.map_svr.Map.SsoReportLocation",
		"trpc.lplan.user_manager_svr.User.SsoLogin",
		"trpc.lplan.user_manager_svr.User.SsoSetProfile",
		"trpc.metaverse.mob_proxy_svr.MobProxy.SsoHandle",
		"trpc.msg.msg_svc.MsgService.SsoC2CRecallMsg",
		"trpc.msg.msg_svc.MsgService.SsoGetPeerSeq",
		"trpc.msg.msg_svc.MsgService.SsoReadedReport",
		"trpc.msg.olpush.OlPushService.SsoPushAck",
		"trpc.msg.register_proxy.RegisterProxy.PushParams",
		"trpc.msg.register_proxy.RegisterProxy.SsoInfoSync",
		"trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey",
		"trpc.o3.ecdh_access.EcdhAccess.SsoSecureA2Access",
		"trpc.o3.ecdh_access.EcdhAccess.SsoSecureA2Establish",
		"trpc.o3.ecdh_access.EcdhAccess.SsoSecureAccess",
		"trpc.o3.report.Report.SsoReport",
		"trpc.passwd.manager.PasswdManager.SetPasswd",
		"trpc.passwd.manager.PasswdManager.VerifyPasswd",
		"trpc.qlive.qlive_proxy_svr.TrpcProxy.*",
		"trpc.qlive.relationchain_svr.RelationchainSvr.Follow",
		"trpc.qlive.word_svr.WordSvr.NewPublicChat",
		"trpc.qmeta.mob_proxy_svr.MobProxy.SsoHandle",
		"trpc.qpay.encryptedtransfer.Encryption.SsoUINEncrypt",
		"trpc.qpay.midas_order.Order.SsoMakeOrder",
		"trpc.qpay.red_pack_skin.Skin.SsoAddSkin",
		"trpc.qpay.sso.web.Do",
		"trpc.qq_new_tech.status_svc.StatusService.Register",
		"trpc.qq_new_tech.status_svc.StatusService.SetStatus",
		"trpc.qq_new_tech.status_svc.StatusService.SsoHeartBeat",
		"trpc.qq_new_tech.status_svc.StatusService.UnRegister",
		"trpc.qqhb.qqhb_proxy.Handler.sso_handle",
		"trpc.qqstranger.common_proxy.CommonProxy.SsoHandle",
		"trpc.qqva.vipdata.Vipdata.SsoGetUserData",
		"trpc.springfestival.redpacket.LuckyBag.SsoSubmitGrade",
		"wtlogin.device_lock",
		"wtlogin.exchange_emp",
		"wtlogin.log_report",
		"wtlogin.login",
		"wtlogin.name2uin",
		"wtlogin.qrlogin",
		"wtlogin.register",
		"wtlogin.trans_emp",
		"wtlogin_device.login",
		"wtlogin_device.tran_sim_emp"
	]);
	async sendCommand(cmd, payload, encryptType, timeout = 15e3) {
		const seq = this.nextSeq();
		const ctx = this.getPacketContext();
		const enc = encryptType ?? (this.session ? EncryptType.EncryptD2Key : EncryptType.EncryptEmpty);
		let signResult = null;
		if (this.config.authToken && this.SIGN_ALLOWLIST.has(cmd)) {
			const uin = this.session?.uin ? Number(this.session.uin) : this.config.uin || void 0;
			await this.ensureSignTokenFresh(uin);
			signResult = await requestSign(cmd, payload, seq, this.guid, AppInfo.qua, uin, this.session?.signToken12B);
			if (signResult?.token.length === 0) signResult.token = Buffer.from(this.session?.signToken12B ?? "");
			logger$2.debug(`[sign] ${cmd} seq=${seq}: result=${signResult ? `sign=${signResult.sign.length}B token=${signResult.token.length}B extra=${signResult.extra.length}B` : "null"}`);
			if (!signResult) throw new Error(`sign failed for ${cmd}; see [Sign] log above`);
		}
		const packet = buildServicePacket(seq, cmd, ctx, payload, enc, signResult);
		if (cmd.includes("o3.ecdh_access") || cmd === "wtlogin.login" || cmd === "wtlogin.trans_emp") logger$2.debug(`[SSO send] ${cmd} seq=${seq} frame=${packet.length}B hex=%h`, packet);
		return new Promise((resolve, reject) => {
			const timer = setTimeout(() => {
				this.pendingPackets.delete(seq);
				reject(/* @__PURE__ */ new Error(`Command ${cmd} timed out after ${timeout}ms`));
			}, timeout);
			this.pendingPackets.set(seq, {
				resolve,
				reject,
				timeout: timer
			});
			this.conn.send(packet);
		});
	}
	handlePacket(frame) {
		const parsed = parseServicePacket(frame, this.session?.d2Key || Buffer.alloc(16));
		if (!parsed) {
			this.emit("error", /* @__PURE__ */ new Error("Failed to parse incoming packet"));
			return;
		}
		const pending = this.pendingPackets.get(parsed.seq);
		if (pending) {
			clearTimeout(pending.timeout);
			this.pendingPackets.delete(parsed.seq);
			if (parsed.retCode && parsed.retCode !== 0) pending.reject(/* @__PURE__ */ new Error(`SSO ${parsed.cmd} failed: retCode=${parsed.retCode}, extraMsg=${parsed.extraMsg || ""}`));
			else pending.resolve(parsed);
			return;
		}
		this.emit("push", parsed);
	}
	get isConnected() {
		return this.conn.isConnected;
	}
	get isLoggedIn() {
		return this.session !== null;
	}
	getGuid() {
		return this.guid;
	}
	setGuid(guid) {
		this.guid = guid;
		setSignMachineGuid(guid);
	}
	/**
	* 复用同一 client 时热更新配置 (换 token / 换账号 uin). native sign 是进程单例, relay 只绑首个
	* client, 所以不能靠重建 client 换配置 -- 只能在活着的这一个上原地更新. 见 direct doInitDirectClient.
	*/
	setAuthToken(token) {
		this.config.authToken = token;
	}
	setUin(uin) {
		this.config.uin = uin;
	}
	getSession() {
		return this.session;
	}
	getEcdhPublicKey() {
		return this.ecdhKeyPair.publicKey;
	}
	getEcdhShareKey() {
		return this.ecdhKeyPair.shareKey;
	}
	setSession(session) {
		this.session = session;
		this.emit("login", session);
		this.tryAcquireSignToken();
	}
	/**
	* 登录后主动拉一次 sign-token. 转给 ensureSignTokenFresh 走共享 in-flight lock,
	* 避免启动期跟首次 sendCommand 并发开两个 acquire。
	*/
	async tryAcquireSignToken() {
		if (!this.session || !this.config.authToken) return;
		const uin = Number(this.session.uin);
		if (!Number.isFinite(uin) || uin <= 0) return;
		await this.ensureSignTokenFresh(uin);
	}
	/**
	* sendCommand 前调. 按服务端下发的 TTL 续期:
	*   1. 没 session / 没 uin -> noop
	*   2. 从没拉过 (expiresAt undefined) -> 首拉一次
	*   3. 有非空 token 且未过期 -> 复用不刷
	*   4. 有非空 token 但已过期 -> 重新 acquire 续期 (续期失败按 lastFetchAt 限最小重试间隔)
	*   5. 空 token (403 软降级) -> 不刷, 免得 403 情况每次发包都去重试 acquire
	* signToken12B/expiresAt 不落盘 (见 session.ts), 每次启动/恢复都从 undefined 起,
	* 故登录后 tryAcquireSignToken 必首拉一次。in-flight lock 防并发雪崩。
	*/
	async ensureSignTokenFresh(uin) {
		if (!this.session || !uin || !this.config.authToken) return;
		if (this.session.signTokenExpiresAt) {
			const expired = Date.now() >= this.session.signTokenExpiresAt;
			if (!this.session.signToken12B || !expired) return;
			if (Date.now() - this.signTokenLastFetchAt < 3e4) return;
		}
		if (this.signTokenRefreshInflight) return;
		this.signTokenRefreshInflight = (async () => {
			try {
				this.signTokenLastFetchAt = Date.now();
				const { token, ttlSecs } = await acquireSignToken(uin, AppInfo.qua);
				if (this.session) {
					this.session.signToken12B = token;
					this.session.signTokenExpiresAt = Date.now() + ttlSecs * 1e3;
					logger$2.info(`[SignToken] acquired "${token}" ttl=${ttlSecs}s`);
				}
			} catch (e) {
				logger$2.warn(`[SignToken] acquire failed: ${e.message}`);
			} finally {
				this.signTokenRefreshInflight = null;
			}
		})();
		await this.signTokenRefreshInflight;
	}
	clearSession() {
		this.session = null;
	}
};
//#endregion
//#region src/main/qqProtocol/direct-lib/tlv.ts
var TlvWriter = class {
	parts = [];
	count = 0;
	addTlv(tag, data) {
		const header = Buffer.alloc(4);
		header.writeUInt16BE(tag, 0);
		header.writeUInt16BE(data.length, 2);
		this.parts.push(header);
		this.parts.push(data);
		this.count++;
	}
	addTlvUint8(tag, value) {
		const buf = Buffer.alloc(1);
		buf.writeUInt8(value);
		this.addTlv(tag, buf);
	}
	addTlvUint16(tag, value) {
		const buf = Buffer.alloc(2);
		buf.writeUInt16BE(value);
		this.addTlv(tag, buf);
	}
	addTlvUint32(tag, value) {
		const buf = Buffer.alloc(4);
		buf.writeUInt32BE(value);
		this.addTlv(tag, buf);
	}
	build() {
		const countBuf = Buffer.alloc(2);
		countBuf.writeUInt16BE(this.count);
		return Buffer.concat([countBuf, ...this.parts]);
	}
};
function tlvUnpack(data) {
	const result = /* @__PURE__ */ new Map();
	let offset = 0;
	if (data.length < 2) return result;
	const count = data.readUInt16BE(offset);
	offset += 2;
	for (let i = 0; i < count && offset + 4 <= data.length; i++) {
		const tag = data.readUInt16BE(offset);
		offset += 2;
		const len = data.readUInt16BE(offset);
		offset += 2;
		if (offset + len > data.length) break;
		result.set(tag, Buffer.from(data.subarray(offset, offset + len)));
		offset += len;
	}
	return result;
}
function writeString16(str) {
	const strBuf = Buffer.from(str, "utf-8");
	const header = Buffer.alloc(2);
	header.writeUInt16BE(strBuf.length);
	return Buffer.concat([header, strBuf]);
}
function writeBytes16(data) {
	const header = Buffer.alloc(2);
	header.writeUInt16BE(data.length);
	return Buffer.concat([header, data]);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/login.ts
var logger$1 = getLogger("login");
var QrCodeState = /* @__PURE__ */ function(QrCodeState) {
	QrCodeState[QrCodeState["Confirmed"] = 0] = "Confirmed";
	QrCodeState[QrCodeState["Expired"] = 17] = "Expired";
	QrCodeState[QrCodeState["WaitingForScan"] = 48] = "WaitingForScan";
	QrCodeState[QrCodeState["WaitingForConfirm"] = 53] = "WaitingForConfirm";
	QrCodeState[QrCodeState["Cancelled"] = 54] = "Cancelled";
	return QrCodeState;
}({});
var BUF16 = Buffer.alloc(16);
var BUF3 = Buffer.alloc(3);
var BUF21 = Buffer.alloc(21);
function buildWtLoginFrame(uin, command, body, ecdhPublicKey, shareKey) {
	const encrypted = Buffer.from(teaEncrypt(body, shareKey));
	const cmdId = command === "wtlogin.login" ? 2064 : 2066;
	const header = Buffer.alloc(47 + ecdhPublicKey.length);
	let off = 0;
	header.writeUInt16BE(8001, off);
	off += 2;
	header.writeUInt16BE(cmdId, off);
	off += 2;
	header.writeUInt16BE(0, off);
	off += 2;
	header.writeUInt32BE(uin, off);
	off += 4;
	header.writeUInt8(3, off);
	off += 1;
	header.writeUInt8(135, off);
	off += 1;
	header.writeUInt32BE(0, off);
	off += 4;
	header.writeUInt8(19, off);
	off += 1;
	header.writeUInt16BE(0, off);
	off += 2;
	header.writeUInt16BE(AppInfo.appClientVersion, off);
	off += 2;
	header.writeUInt32BE(0, off);
	off += 4;
	header.writeUInt8(1, off);
	off += 1;
	header.writeUInt8(1, off);
	off += 1;
	BUF16.copy(header, off);
	off += 16;
	header.writeUInt16BE(258, off);
	off += 2;
	header.writeUInt16BE(ecdhPublicKey.length, off);
	off += 2;
	ecdhPublicKey.copy(header, off);
	off += ecdhPublicKey.length;
	const innerBody = Buffer.concat([
		header.subarray(0, off),
		encrypted,
		Buffer.from([3])
	]);
	const frame = Buffer.alloc(3 + innerBody.length);
	frame.writeUInt8(2, 0);
	frame.writeUInt16BE(innerBody.length + 3, 1);
	innerBody.copy(frame, 3);
	return frame;
}
function buildCode2dPacket(subCommand, tlv) {
	const timestamp = Math.floor(Date.now() / 1e3);
	const requestBody = Buffer.alloc(49 + tlv.length + 1);
	let off = 0;
	requestBody.writeUInt32BE(timestamp, off);
	off += 4;
	requestBody.writeUInt8(2, off);
	off += 1;
	requestBody.writeUInt16BE(46 + tlv.length, off);
	off += 2;
	requestBody.writeUInt16BE(subCommand, off);
	off += 2;
	BUF21.copy(requestBody, off);
	off += 21;
	requestBody.writeUInt8(3, off);
	off += 1;
	requestBody.writeInt32BE(50, off);
	off += 4;
	requestBody.writeInt16BE(0, off);
	off += 2;
	requestBody.writeUInt32BE(0, off);
	off += 4;
	requestBody.writeBigUInt64BE(0n, off);
	off += 8;
	tlv.copy(requestBody, off);
	off += tlv.length;
	requestBody.writeUInt8(3, off);
	off += 1;
	const outerSize = 14 + requestBody.length;
	const outer = Buffer.alloc(outerSize);
	let oOff = 0;
	outer.writeUInt8(0, oOff);
	oOff += 1;
	outer.writeUInt16BE(requestBody.length, oOff);
	oOff += 2;
	outer.writeUInt32BE(AppInfo.appId, oOff);
	oOff += 4;
	outer.writeUInt32BE(114, oOff);
	oOff += 4;
	BUF3.copy(outer, oOff);
	oOff += 3;
	requestBody.copy(outer, oOff);
	return outer;
}
async function fetchQrCode(client) {
	const tlv = new TlvWriter();
	tlv.addTlv(22, buildTlv16(client));
	const tlv1B = Buffer.alloc(30);
	tlv1B.writeUInt32BE(0, 0);
	tlv1B.writeUInt32BE(0, 4);
	tlv1B.writeUInt32BE(3, 8);
	tlv1B.writeUInt32BE(4, 12);
	tlv1B.writeUInt32BE(72, 16);
	tlv1B.writeUInt32BE(2, 20);
	tlv1B.writeUInt32BE(2, 24);
	tlv1B.writeUInt16BE(0, 28);
	tlv.addTlv(27, tlv1B);
	const tlv1D = Buffer.alloc(10);
	tlv1D.writeUInt8(1, 0);
	tlv1D.writeUInt32BE(AppInfo.mainSigMap, 1);
	tlv1D.writeUInt32BE(0, 5);
	tlv1D.writeUInt8(0, 9);
	tlv.addTlv(29, tlv1D);
	tlv.addTlv(51, client.getGuid());
	tlv.addTlvUint32(53, AppInfo.ssoVersion);
	tlv.addTlvUint32(102, AppInfo.ssoVersion);
	tlv.addTlv(209, buildTlvD1());
	const bodyParts = [];
	const appIdBuf = Buffer.alloc(4);
	appIdBuf.writeUInt32BE(AppInfo.appId);
	bodyParts.push(appIdBuf);
	bodyParts.push(Buffer.alloc(8));
	bodyParts.push(Buffer.from([0]));
	bodyParts.push(Buffer.from([0, 0]));
	bodyParts.push(tlv.build());
	const wtLogin = buildWtLoginFrame(0, "wtlogin.trans_emp", buildCode2dPacket(49, Buffer.concat(bodyParts)), client.getEcdhPublicKey(), client.getEcdhShareKey());
	return parseTransEmp31Response((await client.sendCommand("wtlogin.trans_emp", wtLogin, EncryptType.EncryptEmpty, 1e4)).payload, client.getEcdhShareKey());
}
async function pollQrCode(client, sig) {
	const bodySize = 6 + sig.length + 8 + 4 + 1 + 1;
	const body = Buffer.alloc(bodySize);
	let off = 0;
	body.writeUInt32BE(AppInfo.appId, off);
	off += 4;
	body.writeUInt16BE(sig.length, off);
	off += 2;
	sig.copy(body, off);
	off += sig.length;
	body.writeBigUInt64BE(0n, off);
	off += 8;
	body.writeUInt32BE(0, off);
	off += 4;
	body.writeUInt8(0, off);
	off += 1;
	body.writeUInt8(3, off);
	off += 1;
	const wtLogin = buildWtLoginFrame(0, "wtlogin.trans_emp", buildCode2dPacket(18, body), client.getEcdhPublicKey(), client.getEcdhShareKey());
	return parseTransEmp12Response((await client.sendCommand("wtlogin.trans_emp", wtLogin, EncryptType.EncryptEmpty, 1e4)).payload, client.getEcdhShareKey());
}
async function loginWithQrResult(client, qrResult) {
	if (!qrResult.tempPassword || !qrResult.tgtgtKey || !qrResult.noPicSig || !qrResult.uin) throw new Error("QR poll result incomplete");
	const uin = Number(qrResult.uin);
	const tlv = new TlvWriter();
	tlv.addTlv(262, qrResult.tempPassword);
	const innerTlv = new TlvWriter();
	innerTlv.addTlv(366, Buffer.from(DeviceInfo.devName));
	innerTlv.addTlv(327, buildTlv147());
	innerTlv.addTlv(296, buildTlv128(client));
	innerTlv.addTlv(292, buildTlv124());
	const encrypted144 = Buffer.from(teaEncrypt(innerTlv.build(), qrResult.tgtgtKey));
	tlv.addTlv(324, encrypted144);
	tlv.addTlv(278, buildTlv116());
	const tlv142Parts = [];
	const tlv142Header = Buffer.alloc(2);
	tlv142Header.writeUInt16BE(0);
	tlv142Parts.push(tlv142Header);
	tlv142Parts.push(writeString16(AppInfo.packageName));
	tlv.addTlv(322, Buffer.concat(tlv142Parts));
	tlv.addTlv(325, client.getGuid());
	tlv.addTlv(24, buildTlv018(uin));
	tlv.addTlv(321, buildTlv141());
	tlv.addTlv(375, buildTlv177());
	tlv.addTlvUint8(401, 0);
	tlv.addTlv(256, buildTlv100());
	const tlv107 = Buffer.alloc(6);
	tlv107.writeUInt16BE(1, 0);
	tlv107.writeUInt8(0, 2);
	tlv107.writeUInt16BE(13, 3);
	tlv107.writeUInt8(1, 5);
	tlv.addTlv(263, tlv107);
	tlv.addTlv(792, Buffer.alloc(0));
	tlv.addTlv(362, qrResult.noPicSig);
	tlv.addTlvUint8(358, 5);
	const tlv521Parts = [];
	const tlv521Header = Buffer.alloc(4);
	tlv521Header.writeUInt32BE(19);
	tlv521Parts.push(tlv521Header);
	tlv521Parts.push(writeString16("basicim"));
	tlv.addTlv(1313, Buffer.concat(tlv521Parts));
	const cmdPrefix = Buffer.alloc(2);
	cmdPrefix.writeUInt16BE(9);
	const wtLogin = buildWtLoginFrame(uin, "wtlogin.login", Buffer.concat([cmdPrefix, tlv.build()]), client.getEcdhPublicKey(), client.getEcdhShareKey());
	const result = parseLoginResponse((await client.sendCommand("wtlogin.login", wtLogin, EncryptType.EncryptEmpty, 15e3)).payload, client.getEcdhShareKey(), qrResult.tgtgtKey);
	if (result.success) client.setSession({
		uin: qrResult.uin,
		uid: result.uid,
		d2: result.d2,
		d2Key: result.d2Key,
		tgt: result.tgt,
		a2: result.tgt,
		a2Key: result.a2Key,
		sKey: Buffer.alloc(0)
	});
	return result;
}
function buildTlv16(client) {
	const parts = [];
	const header = Buffer.alloc(12);
	header.writeUInt32BE(0, 0);
	header.writeUInt32BE(AppInfo.appId, 4);
	header.writeUInt32BE(AppInfo.subAppId, 8);
	parts.push(header);
	parts.push(client.getGuid());
	parts.push(writeString16(AppInfo.packageName));
	parts.push(writeString16(AppInfo.ptVersion));
	parts.push(writeString16(AppInfo.packageName));
	return Buffer.concat(parts);
}
function buildTlv147() {
	const parts = [];
	const header = Buffer.alloc(4);
	header.writeUInt32BE(AppInfo.appId);
	parts.push(header);
	parts.push(writeString16(AppInfo.ptVersion));
	parts.push(writeString16(AppInfo.packageName));
	return Buffer.concat(parts);
}
function buildTlv128(client) {
	const parts = [];
	const header = Buffer.alloc(9);
	header.writeUInt16BE(0, 0);
	header.writeUInt8(0, 2);
	header.writeUInt8(1, 3);
	header.writeUInt8(0, 4);
	header.writeUInt32BE(0, 5);
	parts.push(header);
	parts.push(writeString16(AppInfo.os));
	parts.push(writeBytes16(client.getGuid()));
	parts.push(writeString16(""));
	return Buffer.concat(parts);
}
function buildTlv124() {
	return Buffer.alloc(12);
}
function buildTlv116() {
	const buf = Buffer.alloc(10);
	buf.writeUInt8(0, 0);
	buf.writeUInt32BE(12058620, 1);
	buf.writeUInt32BE(AppInfo.subSigMap, 5);
	buf.writeUInt8(0, 9);
	return buf;
}
function buildTlv018(uin = 0) {
	const buf = Buffer.alloc(22);
	let off = 0;
	buf.writeUInt16BE(0, off);
	off += 2;
	buf.writeUInt32BE(5, off);
	off += 4;
	buf.writeUInt32BE(0, off);
	off += 4;
	buf.writeUInt32BE(8001, off);
	off += 4;
	buf.writeUInt32BE(uin, off);
	off += 4;
	buf.writeUInt16BE(0, off);
	off += 2;
	buf.writeUInt16BE(0, off);
	off += 2;
	return buf;
}
function buildTlv141() {
	const parts = [];
	const unknown = Buffer.from("Unknown");
	const f0Len = Buffer.alloc(4);
	f0Len.writeUInt32BE(unknown.length);
	parts.push(f0Len);
	parts.push(unknown);
	const netType = Buffer.alloc(2);
	netType.writeUInt16BE(0);
	parts.push(netType);
	parts.push(writeString16(""));
	return Buffer.concat(parts);
}
function buildTlv177() {
	const parts = [];
	const header = Buffer.alloc(5);
	header.writeUInt8(1, 0);
	header.writeUInt32BE(0, 1);
	parts.push(header);
	parts.push(writeString16(AppInfo.wtLoginSdk));
	return Buffer.concat(parts);
}
function buildTlv100() {
	const buf = Buffer.alloc(22);
	let off = 0;
	buf.writeUInt16BE(0, off);
	off += 2;
	buf.writeUInt32BE(5, off);
	off += 4;
	buf.writeUInt32BE(AppInfo.appId, off);
	off += 4;
	buf.writeUInt32BE(AppInfo.subAppId, off);
	off += 4;
	buf.writeUInt32BE(AppInfo.appClientVersion, off);
	off += 4;
	buf.writeUInt32BE(AppInfo.mainSigMap, off);
	off += 4;
	return buf;
}
function buildTlvD1() {
	const devType = Buffer.from(DeviceInfo.devType);
	const devName = Buffer.from(DeviceInfo.devName);
	const systemParts = [];
	systemParts.push(encodeProtoString(1, devType));
	systemParts.push(encodeProtoString(2, devName));
	const system = Buffer.concat(systemParts);
	const parts = [];
	parts.push(encodeProtoBytes(1, system));
	parts.push(encodeProtoBytes(4, Buffer.from([48, 1])));
	return Buffer.concat(parts);
}
function encodeProtoString(fieldNum, data) {
	return encodeProtoBytes(fieldNum, data);
}
function encodeProtoBytes(fieldNum, data) {
	const tagBuf = encodeVarintBuf(fieldNum << 3 | 2);
	const lenBuf = encodeVarintBuf(data.length);
	return Buffer.concat([
		tagBuf,
		lenBuf,
		data
	]);
}
function encodeVarintBuf(value) {
	const bytes = [];
	while (value > 127) {
		bytes.push(value & 127 | 128);
		value >>>= 7;
	}
	bytes.push(value & 127);
	return Buffer.from(bytes);
}
function parseTransEmp31Response(data, shareKey) {
	if (data[0] !== 2 || data[data.length - 1] !== 3) throw new Error("Invalid WtLogin response frame");
	const encrypted = data.subarray(16, data.length - 1);
	let decrypted;
	try {
		decrypted = Buffer.from(teaDecrypt(encrypted, shareKey));
	} catch {
		throw new Error("Failed to decrypt TransEmp31 response");
	}
	let offset = 0;
	offset += 8;
	decrypted.readUInt16BE(offset);
	offset += 2;
	offset += 40;
	decrypted.readUInt32BE(offset);
	offset += 4;
	const transEmpData = decrypted.subarray(offset);
	let dOff = 0;
	transEmpData.readUInt8(dOff);
	dOff += 1;
	const sigLen = transEmpData.readUInt16BE(dOff);
	dOff += 2;
	const sig = Buffer.from(transEmpData.subarray(dOff, dOff + sigLen));
	dOff += sigLen;
	const tlvs = tlvUnpack(transEmpData.subarray(dOff));
	let url = "";
	const tlvD1 = tlvs.get(209);
	if (tlvD1) {
		const str = tlvD1.toString("latin1");
		const urlStart = str.indexOf("https://");
		if (urlStart >= 0) {
			let urlEnd = urlStart;
			while (urlEnd < str.length && str.charCodeAt(urlEnd) >= 32 && str.charCodeAt(urlEnd) < 127) urlEnd++;
			url = str.slice(urlStart, urlEnd);
		}
	}
	const image = tlvs.get(23) || Buffer.alloc(0);
	return {
		url,
		image,
		sig,
		tgtgtKey: shareKey
	};
}
function parseTransEmp12Response(data, shareKey) {
	if (data[0] !== 2 || data[data.length - 1] !== 3) throw new Error("Invalid WtLogin response frame");
	const encrypted = data.subarray(16, data.length - 1);
	let decrypted;
	try {
		decrypted = Buffer.from(teaDecrypt(encrypted, shareKey));
	} catch {
		throw new Error("Failed to decrypt TransEmp12 response");
	}
	let offset = 0;
	offset += 8;
	offset += 2;
	offset += 40;
	offset += 4;
	const transEmpData = decrypted.subarray(offset);
	let dOff = 0;
	const state = transEmpData.readUInt8(dOff);
	dOff += 1;
	if (state !== 0) return { state };
	dOff += 12;
	const tlvs = tlvUnpack(transEmpData.subarray(dOff));
	return {
		state,
		uin: "",
		tgtgtKey: tlvs.get(30),
		noPicSig: tlvs.get(25),
		tempPassword: tlvs.get(24)
	};
}
function parseLoginResponse(data, shareKey, tgtgtKey) {
	if (data[0] !== 2 || data[data.length - 1] !== 3) throw new Error("Invalid WtLogin response frame");
	const encrypted = data.subarray(16, data.length - 1);
	let decrypted;
	try {
		decrypted = Buffer.from(teaDecrypt(encrypted, shareKey));
	} catch (e) {
		throw new Error(`Failed to decrypt login response: ${e.message}`);
	}
	let offset = 0;
	decrypted.readUInt16BE(offset);
	offset += 2;
	const state = decrypted.readUInt8(offset);
	offset += 1;
	if (state !== 0) {
		const errBuf = tlvUnpack(decrypted.subarray(offset)).get(326);
		if (errBuf && errBuf.length > 6) {
			let eOff = 4;
			const tagLen = errBuf.readUInt16BE(eOff);
			eOff += 2;
			const tag = errBuf.subarray(eOff, eOff + tagLen).toString();
			eOff += tagLen;
			const msgLen = errBuf.readUInt16BE(eOff);
			eOff += 2;
			return {
				success: false,
				state,
				tag,
				message: errBuf.subarray(eOff, eOff + msgLen).toString()
			};
		}
		return {
			success: false,
			state
		};
	}
	const tlv119 = tlvUnpack(decrypted.subarray(offset)).get(281);
	if (!tlv119) throw new Error("Login response missing TLV 0x119");
	const nestedTlvs = tlvUnpack(Buffer.from(teaDecrypt(tlv119, tgtgtKey)));
	const d2 = nestedTlvs.get(323) || Buffer.alloc(0);
	const d2Key = nestedTlvs.get(773) || Buffer.alloc(16);
	const tgt = nestedTlvs.get(266) || Buffer.alloc(0);
	const tempPassword = nestedTlvs.get(262) || Buffer.alloc(0);
	{
		const lines = [`nested TLVs in 0x119: ${Array.from(nestedTlvs.keys()).sort((a, b) => a - b).map((x) => "0x" + x.toString(16)).join(", ")}`];
		for (const cand of [
			268,
			269,
			270,
			355,
			362,
			365,
			370,
			366
		]) {
			const v = nestedTlvs.get(cand);
			if (v) lines.push(`  TLV 0x${cand.toString(16)}: ${v.length}B = ${v.subarray(0, Math.min(32, v.length)).toString("hex")}${v.length > 32 ? "..." : ""}`);
		}
		logger$1.debug(lines.join("\n"));
	}
	const a2Key = nestedTlvs.get(269) || Buffer.alloc(16);
	let nick = "", age = 0, gender = 0;
	const tlv11a = nestedTlvs.get(282);
	if (tlv11a && tlv11a.length >= 5) {
		age = tlv11a.readUInt8(2);
		gender = tlv11a.readUInt8(3);
		const nickLen = tlv11a.readUInt8(4);
		if (5 + nickLen <= tlv11a.length) nick = tlv11a.subarray(5, 5 + nickLen).toString("utf-8");
	}
	let uid = "";
	const tlv543 = nestedTlvs.get(1347);
	if (tlv543) uid = parseUidFromTlv543(tlv543);
	return {
		success: true,
		uid,
		d2,
		d2Key,
		tgt,
		tempPassword,
		nick,
		age,
		gender,
		a2Key
	};
}
function parseUidFromTlv543(data) {
	try {
		const layer1 = decodeProtoField(data, 9);
		if (!layer1) return "";
		const layer2 = decodeProtoField(layer1, 11);
		if (!layer2) return "";
		const uidBuf = decodeProtoField(layer2, 1);
		if (!uidBuf) return "";
		return uidBuf.toString("utf-8");
	} catch {
		return "";
	}
}
function decodeProtoField(data, targetField) {
	let offset = 0;
	while (offset < data.length) {
		data[offset];
		let tag = 0;
		let shift = 0;
		let pos = offset;
		while (pos < data.length) {
			const b = data[pos];
			tag |= (b & 127) << shift;
			pos++;
			if ((b & 128) === 0) break;
			shift += 7;
		}
		offset = pos;
		const fieldNumber = tag >>> 3;
		const wireType = tag & 7;
		if (wireType === 0) {
			while (offset < data.length && (data[offset] & 128) !== 0) offset++;
			offset++;
		} else if (wireType === 2) {
			let len = 0;
			let lenShift = 0;
			while (offset < data.length) {
				const b = data[offset];
				len |= (b & 127) << lenShift;
				offset++;
				if ((b & 128) === 0) break;
				lenShift += 7;
			}
			if (fieldNumber === targetField) return data.subarray(offset, offset + len);
			offset += len;
		} else if (wireType === 5) offset += 4;
		else if (wireType === 1) offset += 8;
		else break;
	}
	return null;
}
async function getCorrectUin(appId, qrSig) {
	return (await (await fetch("https://ntlogin.qq.com/qr/getFace", {
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({
			appid: appId,
			faceUpdateTime: 0,
			qrsig: qrSig
		})
	})).json()).uin;
}
//#endregion
//#region src/main/qqProtocol/direct-lib/online.ts
function encodeVarint(value) {
	const bytes = [];
	let v = typeof value === "bigint" ? value : BigInt(value);
	if (v === 0n) bytes.push(0);
	else while (v > 0n) {
		const b = Number(v & 127n);
		v >>= 7n;
		bytes.push(v > 0n ? b | 128 : b);
	}
	return Buffer.from(bytes);
}
function protoTag(field, wireType) {
	return encodeVarint(field << 3 | wireType);
}
function protoVarintField(field, value) {
	return Buffer.concat([protoTag(field, 0), encodeVarint(value)]);
}
function protoStringField(field, value) {
	const data = Buffer.from(value, "utf-8");
	return Buffer.concat([
		protoTag(field, 2),
		encodeVarint(data.length),
		data
	]);
}
function protoBytesField(field, data) {
	return Buffer.concat([
		protoTag(field, 2),
		encodeVarint(data.length),
		data
	]);
}
function protoMessageField(field, content) {
	return protoBytesField(field, content);
}
function buildSsoHeartBeat() {
	return protoVarintField(1, 1);
}
function buildRegisterDeviceInfo() {
	const parts = [];
	parts.push(protoStringField(1, DeviceInfo.devName));
	parts.push(protoStringField(2, AppInfo.kernel));
	parts.push(protoStringField(3, "5.15.0"));
	parts.push(protoStringField(4, ""));
	parts.push(protoStringField(5, AppInfo.vendorOs));
	return Buffer.concat(parts);
}
function buildRegisterInfo(guid, isFirstOnline = true) {
	const parts = [];
	parts.push(protoStringField(1, guid.toString("hex")));
	parts.push(protoVarintField(2, 0));
	parts.push(protoStringField(3, AppInfo.currentVersion));
	parts.push(protoVarintField(4, isFirstOnline ? 1 : 0));
	parts.push(protoVarintField(5, 2052));
	parts.push(protoMessageField(6, buildRegisterDeviceInfo()));
	parts.push(protoVarintField(7, 0));
	parts.push(protoVarintField(8, 6));
	parts.push(protoVarintField(9, 0));
	const bizInfo = Buffer.concat([protoVarintField(1, 1), protoVarintField(2, 1)]);
	parts.push(protoMessageField(10, bizInfo));
	parts.push(protoVarintField(11, 0));
	parts.push(protoVarintField(12, 1));
	return Buffer.concat(parts);
}
function buildC2cMsgCookie() {
	return protoVarintField(1, 0n);
}
function buildSsoInfoSync(guid, isFirstOnline = true) {
	const parts = [];
	parts.push(protoVarintField(1, 735));
	parts.push(protoVarintField(2, Math.floor(Math.random() * 4294967295)));
	parts.push(protoVarintField(4, 2));
	parts.push(protoVarintField(5, 0n));
	const c2cSync = Buffer.concat([
		protoMessageField(1, buildC2cMsgCookie()),
		protoVarintField(2, 0n),
		protoMessageField(3, buildC2cMsgCookie())
	]);
	parts.push(protoMessageField(6, c2cSync));
	parts.push(protoMessageField(9, buildRegisterInfo(guid, isFirstOnline)));
	const unknown = Buffer.concat([protoVarintField(1, 0), protoVarintField(2, 2)]);
	parts.push(protoMessageField(10, unknown));
	const appState = Buffer.concat([
		protoVarintField(1, 0),
		protoVarintField(2, 0),
		protoVarintField(3, 0)
	]);
	parts.push(protoMessageField(11, appState));
	return Buffer.concat(parts);
}
function parseRegisterResponse(data) {
	const field7 = decodeProtoLenDelim(data, 7);
	if (!field7) return null;
	const msgBuf = decodeProtoLenDelim(field7, 2);
	if (!msgBuf) return null;
	return msgBuf.toString("utf-8");
}
function decodeProtoLenDelim(data, targetField) {
	let offset = 0;
	while (offset < data.length) {
		let tag = 0;
		let shift = 0;
		while (offset < data.length) {
			const b = data[offset++];
			tag |= (b & 127) << shift;
			if ((b & 128) === 0) break;
			shift += 7;
		}
		const fieldNumber = tag >>> 3;
		const wireType = tag & 7;
		if (wireType === 0) {
			while (offset < data.length && (data[offset] & 128) !== 0) offset++;
			offset++;
		} else if (wireType === 2) {
			let len = 0;
			let lenShift = 0;
			while (offset < data.length) {
				const b = data[offset++];
				len |= (b & 127) << lenShift;
				if ((b & 128) === 0) break;
				lenShift += 7;
			}
			if (fieldNumber === targetField) return data.subarray(offset, offset + len);
			offset += len;
		} else if (wireType === 5) offset += 4;
		else if (wireType === 1) offset += 8;
		else break;
	}
	return null;
}
async function registerOnline(client) {
	const payload = buildSsoInfoSync(client.getGuid());
	return parseRegisterResponse((await client.sendCommand("trpc.msg.register_proxy.RegisterProxy.SsoInfoSync", payload, void 0, 1e4)).payload) || "ok";
}
async function sendHeartbeat(client) {
	const payload = buildSsoHeartBeat();
	await client.sendCommand("trpc.qq_new_tech.status_svc.StatusService.SsoHeartBeat", payload, void 0, 5e3);
}
function startHeartbeat(client) {
	const timer = setInterval(async () => {
		try {
			await sendHeartbeat(client);
		} catch (e) {
			getLogger("heartbeat").error("[Heartbeat] Failed:", e.message);
		}
	}, 27e4);
	return () => clearInterval(timer);
}
//#endregion
//#region src/main/qqProtocol/direct-lib/session.ts
var _machineKey = null;
function getMachineKey() {
	if (_machineKey) return _machineKey;
	let machineId = "";
	try {
		if (isDockerEnvironment()) machineId = loadMachineGuidSync().toString("hex");
		else if (process.platform === "win32") {
			const m = execSync("reg query \"HKLM\\SOFTWARE\\Microsoft\\Cryptography\" /v MachineGuid", {
				encoding: "utf-8",
				windowsHide: true
			}).match(/MachineGuid\s+REG_SZ\s+([^\s]+)/);
			machineId = m ? m[1].trim() : "";
		} else if (process.platform === "linux") machineId = readFileSync("/etc/machine-id", "utf-8").trim();
		else if (process.platform === "darwin") {
			const m = execSync("ioreg -rd1 -c IOPlatformExpertDevice", { encoding: "utf-8" }).match(/IOPlatformUUID"\s*=\s*"([^"]+)"/);
			machineId = m ? m[1].trim() : "";
		}
	} catch {}
	if (!machineId) machineId = process.env.COMPUTERNAME || process.env.HOSTNAME || "luckylillia-fallback";
	_machineKey = createHash("sha256").update("luckylillia-session-v1|" + machineId).digest();
	return _machineKey;
}
function encryptSensitive(fields) {
	const key = getMachineKey();
	const iv = randomBytes(12);
	const cipher = createCipheriv("aes-256-gcm", key, iv);
	const enc = Buffer.concat([cipher.update(JSON.stringify(fields), "utf8"), cipher.final()]);
	const tag = cipher.getAuthTag();
	return Buffer.concat([
		iv,
		tag,
		enc
	]).toString("base64");
}
function decryptSensitive(b64) {
	const key = getMachineKey();
	const data = Buffer.from(b64, "base64");
	const iv = data.subarray(0, 12);
	const tag = data.subarray(12, 28);
	const enc = data.subarray(28);
	const decipher = createDecipheriv("aes-256-gcm", key, iv);
	decipher.setAuthTag(tag);
	const plain = Buffer.concat([decipher.update(enc), decipher.final()]).toString("utf8");
	return JSON.parse(plain);
}
/** session 文件统一按 uin 命名为 qq-session-<uin>.json。 */
function getSessionFilePathForUin(uin) {
	return join(DATA_DIR, `qq-session-${uin}.json`);
}
/**
* 把 session 写入 qq-session-<uin>.json（按 session 自身的 uin）。
* 敏感登录凭证加密进 enc, uin/uid/guid/nick 保持明文 (供外部展示快速登录列表)。
*/
function saveSession(session, tgtgtKey, guid, tempPassword, nick = "") {
	const sensitive = {
		d2: session.d2.toString("hex"),
		d2Key: session.d2Key.toString("hex"),
		tgt: session.tgt.toString("hex"),
		tempPassword: tempPassword.toString("hex"),
		tgtgtKey: tgtgtKey.toString("hex")
	};
	const data = {
		uin: session.uin,
		uid: session.uid,
		guid: guid.toString("hex"),
		nick,
		savedAt: Date.now(),
		enc: encryptSensitive(sensitive)
	};
	const path = getSessionFilePathForUin(session.uin);
	writeFileSync(path, JSON.stringify(data, null, 2));
}
/**
* 加载 session:
* - 传了 uin (WebUI 快速登录) 或 argv 里有 -q <uin> → 尝试对应 qq-session-<uin>.json
* - 两者都没有 → 返回 null, 调用方走扫码登录
* - 文件不存在 / 解析失败 / 解密失败 (换机器) → 返回 null
*/
function loadSession(uinArg) {
	const specifiedUin = uinArg || getSpecifiedUin();
	if (!specifiedUin) return null;
	const path = getSessionFilePathForUin(specifiedUin);
	if (!existsSync(path)) return null;
	try {
		const raw = readFileSync(path, "utf-8");
		const data = JSON.parse(raw);
		if (!data.enc) return null;
		try {
			const s = decryptSensitive(data.enc);
			data.d2 = s.d2;
			data.d2Key = s.d2Key;
			data.tgt = s.tgt;
			data.tempPassword = s.tempPassword;
			data.tgtgtKey = s.tgtgtKey;
		} catch {
			return null;
		}
		if (!data.uin || !data.d2 || !data.d2Key) return null;
		return data;
	} catch {
		return null;
	}
}
/**
* 扫 data/qq-session-*.json, 返回可用快速登录账号的明文元数据 (uin/uid/nick).
* 只列**有 enc** 的 session (旧明文/无凭证的一律跳过, 快速登录用不上); 不做实际解密,
* 换机后不能 quick-login 但会展示 -- 用户选到后 registerOnline 阶段会失败并 fallback 扫码.
*/
function listAvailableSessions() {
	let entries;
	try {
		entries = readdirSync(DATA_DIR);
	} catch {
		return [];
	}
	const out = [];
	for (const name of entries) {
		if (!/^qq-session-(\d+)\.json$/.exec(name)) continue;
		try {
			const raw = readFileSync(join(DATA_DIR, name), "utf-8");
			const data = JSON.parse(raw);
			if (!data.enc || !data.uin) continue;
			out.push({
				uin: data.uin,
				uid: data.uid || "",
				nick: data.nick || "",
				savedAt: data.savedAt || 0
			});
		} catch {}
	}
	return out.sort((a, b) => b.savedAt - a.savedAt);
}
/** 删除 qq-session-<uin>.json. 异地登录顶号后清掉失效凭证, 强制重新扫码. */
function deleteSession(uin) {
	try {
		unlinkSync(getSessionFilePathForUin(uin));
	} catch {}
}
function persistedToSessionInfo(persisted) {
	return {
		uin: persisted.uin,
		uid: persisted.uid,
		d2: Buffer.from(persisted.d2 ?? "", "hex"),
		d2Key: Buffer.from(persisted.d2Key ?? "", "hex"),
		tgt: Buffer.from(persisted.tgt ?? "", "hex"),
		a2: Buffer.from(persisted.tgt ?? "", "hex"),
		a2Key: Buffer.alloc(16),
		sKey: Buffer.alloc(0)
	};
}
//#endregion
//#region node_modules/qrcode/lib/can-promise.js
var require_can_promise = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = function() {
		return typeof Promise === "function" && Promise.prototype && Promise.prototype.then;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/utils.js
var require_utils$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
	var toSJISFunction;
	var CODEWORDS_COUNT = [
		0,
		26,
		44,
		70,
		100,
		134,
		172,
		196,
		242,
		292,
		346,
		404,
		466,
		532,
		581,
		655,
		733,
		815,
		901,
		991,
		1085,
		1156,
		1258,
		1364,
		1474,
		1588,
		1706,
		1828,
		1921,
		2051,
		2185,
		2323,
		2465,
		2611,
		2761,
		2876,
		3034,
		3196,
		3362,
		3532,
		3706
	];
	/**
	* Returns the QR Code size for the specified version
	*
	* @param  {Number} version QR Code version
	* @return {Number}         size of QR code
	*/
	exports.getSymbolSize = function getSymbolSize(version) {
		if (!version) throw new Error("\"version\" cannot be null or undefined");
		if (version < 1 || version > 40) throw new Error("\"version\" should be in range from 1 to 40");
		return version * 4 + 17;
	};
	/**
	* Returns the total number of codewords used to store data and EC information.
	*
	* @param  {Number} version QR Code version
	* @return {Number}         Data length in bits
	*/
	exports.getSymbolTotalCodewords = function getSymbolTotalCodewords(version) {
		return CODEWORDS_COUNT[version];
	};
	/**
	* Encode data with Bose-Chaudhuri-Hocquenghem
	*
	* @param  {Number} data Value to encode
	* @return {Number}      Encoded value
	*/
	exports.getBCHDigit = function(data) {
		let digit = 0;
		while (data !== 0) {
			digit++;
			data >>>= 1;
		}
		return digit;
	};
	exports.setToSJISFunction = function setToSJISFunction(f) {
		if (typeof f !== "function") throw new Error("\"toSJISFunc\" is not a valid function.");
		toSJISFunction = f;
	};
	exports.isKanjiModeEnabled = function() {
		return typeof toSJISFunction !== "undefined";
	};
	exports.toSJIS = function toSJIS(kanji) {
		return toSJISFunction(kanji);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/error-correction-level.js
var require_error_correction_level = /* @__PURE__ */ __commonJSMin(((exports) => {
	exports.L = { bit: 1 };
	exports.M = { bit: 0 };
	exports.Q = { bit: 3 };
	exports.H = { bit: 2 };
	function fromString(string) {
		if (typeof string !== "string") throw new Error("Param is not a string");
		switch (string.toLowerCase()) {
			case "l":
			case "low": return exports.L;
			case "m":
			case "medium": return exports.M;
			case "q":
			case "quartile": return exports.Q;
			case "h":
			case "high": return exports.H;
			default: throw new Error("Unknown EC Level: " + string);
		}
	}
	exports.isValid = function isValid(level) {
		return level && typeof level.bit !== "undefined" && level.bit >= 0 && level.bit < 4;
	};
	exports.from = function from(value, defaultValue) {
		if (exports.isValid(value)) return value;
		try {
			return fromString(value);
		} catch (e) {
			return defaultValue;
		}
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/bit-buffer.js
var require_bit_buffer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	function BitBuffer() {
		this.buffer = [];
		this.length = 0;
	}
	BitBuffer.prototype = {
		get: function(index) {
			const bufIndex = Math.floor(index / 8);
			return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) === 1;
		},
		put: function(num, length) {
			for (let i = 0; i < length; i++) this.putBit((num >>> length - i - 1 & 1) === 1);
		},
		getLengthInBits: function() {
			return this.length;
		},
		putBit: function(bit) {
			const bufIndex = Math.floor(this.length / 8);
			if (this.buffer.length <= bufIndex) this.buffer.push(0);
			if (bit) this.buffer[bufIndex] |= 128 >>> this.length % 8;
			this.length++;
		}
	};
	module.exports = BitBuffer;
}));
//#endregion
//#region node_modules/qrcode/lib/core/bit-matrix.js
var require_bit_matrix = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/**
	* Helper class to handle QR Code symbol modules
	*
	* @param {Number} size Symbol size
	*/
	function BitMatrix(size) {
		if (!size || size < 1) throw new Error("BitMatrix size must be defined and greater than 0");
		this.size = size;
		this.data = new Uint8Array(size * size);
		this.reservedBit = new Uint8Array(size * size);
	}
	/**
	* Set bit value at specified location
	* If reserved flag is set, this bit will be ignored during masking process
	*
	* @param {Number}  row
	* @param {Number}  col
	* @param {Boolean} value
	* @param {Boolean} reserved
	*/
	BitMatrix.prototype.set = function(row, col, value, reserved) {
		const index = row * this.size + col;
		this.data[index] = value;
		if (reserved) this.reservedBit[index] = true;
	};
	/**
	* Returns bit value at specified location
	*
	* @param  {Number}  row
	* @param  {Number}  col
	* @return {Boolean}
	*/
	BitMatrix.prototype.get = function(row, col) {
		return this.data[row * this.size + col];
	};
	/**
	* Applies xor operator at specified location
	* (used during masking process)
	*
	* @param {Number}  row
	* @param {Number}  col
	* @param {Boolean} value
	*/
	BitMatrix.prototype.xor = function(row, col, value) {
		this.data[row * this.size + col] ^= value;
	};
	/**
	* Check if bit at specified location is reserved
	*
	* @param {Number}   row
	* @param {Number}   col
	* @return {Boolean}
	*/
	BitMatrix.prototype.isReserved = function(row, col) {
		return this.reservedBit[row * this.size + col];
	};
	module.exports = BitMatrix;
}));
//#endregion
//#region node_modules/qrcode/lib/core/alignment-pattern.js
var require_alignment_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
	/**
	* Alignment pattern are fixed reference pattern in defined positions
	* in a matrix symbology, which enables the decode software to re-synchronise
	* the coordinate mapping of the image modules in the event of moderate amounts
	* of distortion of the image.
	*
	* Alignment patterns are present only in QR Code symbols of version 2 or larger
	* and their number depends on the symbol version.
	*/
	var getSymbolSize = require_utils$1().getSymbolSize;
	/**
	* Calculate the row/column coordinates of the center module of each alignment pattern
	* for the specified QR Code version.
	*
	* The alignment patterns are positioned symmetrically on either side of the diagonal
	* running from the top left corner of the symbol to the bottom right corner.
	*
	* Since positions are simmetrical only half of the coordinates are returned.
	* Each item of the array will represent in turn the x and y coordinate.
	* @see {@link getPositions}
	*
	* @param  {Number} version QR Code version
	* @return {Array}          Array of coordinate
	*/
	exports.getRowColCoords = function getRowColCoords(version) {
		if (version === 1) return [];
		const posCount = Math.floor(version / 7) + 2;
		const size = getSymbolSize(version);
		const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2;
		const positions = [size - 7];
		for (let i = 1; i < posCount - 1; i++) positions[i] = positions[i - 1] - intervals;
		positions.push(6);
		return positions.reverse();
	};
	/**
	* Returns an array containing the positions of each alignment pattern.
	* Each array's element represent the center point of the pattern as (x, y) coordinates
	*
	* Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
	* and filtering out the items that overlaps with finder pattern
	*
	* @example
	* For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
	* The alignment patterns, therefore, are to be centered on (row, column)
	* positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
	* Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
	* and are not therefore used for alignment patterns.
	*
	* let pos = getPositions(7)
	* // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
	*
	* @param  {Number} version QR Code version
	* @return {Array}          Array of coordinates
	*/
	exports.getPositions = function getPositions(version) {
		const coords = [];
		const pos = exports.getRowColCoords(version);
		const posLength = pos.length;
		for (let i = 0; i < posLength; i++) for (let j = 0; j < posLength; j++) {
			if (i === 0 && j === 0 || i === 0 && j === posLength - 1 || i === posLength - 1 && j === 0) continue;
			coords.push([pos[i], pos[j]]);
		}
		return coords;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/finder-pattern.js
var require_finder_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
	var getSymbolSize = require_utils$1().getSymbolSize;
	var FINDER_PATTERN_SIZE = 7;
	/**
	* Returns an array containing the positions of each finder pattern.
	* Each array's element represent the top-left point of the pattern as (x, y) coordinates
	*
	* @param  {Number} version QR Code version
	* @return {Array}          Array of coordinates
	*/
	exports.getPositions = function getPositions(version) {
		const size = getSymbolSize(version);
		return [
			[0, 0],
			[size - FINDER_PATTERN_SIZE, 0],
			[0, size - FINDER_PATTERN_SIZE]
		];
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/mask-pattern.js
var require_mask_pattern = /* @__PURE__ */ __commonJSMin(((exports) => {
	/**
	* Data mask pattern reference
	* @type {Object}
	*/
	exports.Patterns = {
		PATTERN000: 0,
		PATTERN001: 1,
		PATTERN010: 2,
		PATTERN011: 3,
		PATTERN100: 4,
		PATTERN101: 5,
		PATTERN110: 6,
		PATTERN111: 7
	};
	/**
	* Weighted penalty scores for the undesirable features
	* @type {Object}
	*/
	var PenaltyScores = {
		N1: 3,
		N2: 3,
		N3: 40,
		N4: 10
	};
	/**
	* Check if mask pattern value is valid
	*
	* @param  {Number}  mask    Mask pattern
	* @return {Boolean}         true if valid, false otherwise
	*/
	exports.isValid = function isValid(mask) {
		return mask != null && mask !== "" && !isNaN(mask) && mask >= 0 && mask <= 7;
	};
	/**
	* Returns mask pattern from a value.
	* If value is not valid, returns undefined
	*
	* @param  {Number|String} value        Mask pattern value
	* @return {Number}                     Valid mask pattern or undefined
	*/
	exports.from = function from(value) {
		return exports.isValid(value) ? parseInt(value, 10) : void 0;
	};
	/**
	* Find adjacent modules in row/column with the same color
	* and assign a penalty value.
	*
	* Points: N1 + i
	* i is the amount by which the number of adjacent modules of the same color exceeds 5
	*/
	exports.getPenaltyN1 = function getPenaltyN1(data) {
		const size = data.size;
		let points = 0;
		let sameCountCol = 0;
		let sameCountRow = 0;
		let lastCol = null;
		let lastRow = null;
		for (let row = 0; row < size; row++) {
			sameCountCol = sameCountRow = 0;
			lastCol = lastRow = null;
			for (let col = 0; col < size; col++) {
				let module$1 = data.get(row, col);
				if (module$1 === lastCol) sameCountCol++;
				else {
					if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5);
					lastCol = module$1;
					sameCountCol = 1;
				}
				module$1 = data.get(col, row);
				if (module$1 === lastRow) sameCountRow++;
				else {
					if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5);
					lastRow = module$1;
					sameCountRow = 1;
				}
			}
			if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5);
			if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5);
		}
		return points;
	};
	/**
	* Find 2x2 blocks with the same color and assign a penalty value
	*
	* Points: N2 * (m - 1) * (n - 1)
	*/
	exports.getPenaltyN2 = function getPenaltyN2(data) {
		const size = data.size;
		let points = 0;
		for (let row = 0; row < size - 1; row++) for (let col = 0; col < size - 1; col++) {
			const last = data.get(row, col) + data.get(row, col + 1) + data.get(row + 1, col) + data.get(row + 1, col + 1);
			if (last === 4 || last === 0) points++;
		}
		return points * PenaltyScores.N2;
	};
	/**
	* Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,
	* preceded or followed by light area 4 modules wide
	*
	* Points: N3 * number of pattern found
	*/
	exports.getPenaltyN3 = function getPenaltyN3(data) {
		const size = data.size;
		let points = 0;
		let bitsCol = 0;
		let bitsRow = 0;
		for (let row = 0; row < size; row++) {
			bitsCol = bitsRow = 0;
			for (let col = 0; col < size; col++) {
				bitsCol = bitsCol << 1 & 2047 | data.get(row, col);
				if (col >= 10 && (bitsCol === 1488 || bitsCol === 93)) points++;
				bitsRow = bitsRow << 1 & 2047 | data.get(col, row);
				if (col >= 10 && (bitsRow === 1488 || bitsRow === 93)) points++;
			}
		}
		return points * PenaltyScores.N3;
	};
	/**
	* Calculate proportion of dark modules in entire symbol
	*
	* Points: N4 * k
	*
	* k is the rating of the deviation of the proportion of dark modules
	* in the symbol from 50% in steps of 5%
	*/
	exports.getPenaltyN4 = function getPenaltyN4(data) {
		let darkCount = 0;
		const modulesCount = data.data.length;
		for (let i = 0; i < modulesCount; i++) darkCount += data.data[i];
		return Math.abs(Math.ceil(darkCount * 100 / modulesCount / 5) - 10) * PenaltyScores.N4;
	};
	/**
	* Return mask value at given position
	*
	* @param  {Number} maskPattern Pattern reference value
	* @param  {Number} i           Row
	* @param  {Number} j           Column
	* @return {Boolean}            Mask value
	*/
	function getMaskAt(maskPattern, i, j) {
		switch (maskPattern) {
			case exports.Patterns.PATTERN000: return (i + j) % 2 === 0;
			case exports.Patterns.PATTERN001: return i % 2 === 0;
			case exports.Patterns.PATTERN010: return j % 3 === 0;
			case exports.Patterns.PATTERN011: return (i + j) % 3 === 0;
			case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0;
			case exports.Patterns.PATTERN101: return i * j % 2 + i * j % 3 === 0;
			case exports.Patterns.PATTERN110: return (i * j % 2 + i * j % 3) % 2 === 0;
			case exports.Patterns.PATTERN111: return (i * j % 3 + (i + j) % 2) % 2 === 0;
			default: throw new Error("bad maskPattern:" + maskPattern);
		}
	}
	/**
	* Apply a mask pattern to a BitMatrix
	*
	* @param  {Number}    pattern Pattern reference number
	* @param  {BitMatrix} data    BitMatrix data
	*/
	exports.applyMask = function applyMask(pattern, data) {
		const size = data.size;
		for (let col = 0; col < size; col++) for (let row = 0; row < size; row++) {
			if (data.isReserved(row, col)) continue;
			data.xor(row, col, getMaskAt(pattern, row, col));
		}
	};
	/**
	* Returns the best mask pattern for data
	*
	* @param  {BitMatrix} data
	* @return {Number} Mask pattern reference number
	*/
	exports.getBestMask = function getBestMask(data, setupFormatFunc) {
		const numPatterns = Object.keys(exports.Patterns).length;
		let bestPattern = 0;
		let lowerPenalty = Infinity;
		for (let p = 0; p < numPatterns; p++) {
			setupFormatFunc(p);
			exports.applyMask(p, data);
			const penalty = exports.getPenaltyN1(data) + exports.getPenaltyN2(data) + exports.getPenaltyN3(data) + exports.getPenaltyN4(data);
			exports.applyMask(p, data);
			if (penalty < lowerPenalty) {
				lowerPenalty = penalty;
				bestPattern = p;
			}
		}
		return bestPattern;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/error-correction-code.js
var require_error_correction_code = /* @__PURE__ */ __commonJSMin(((exports) => {
	var ECLevel = require_error_correction_level();
	var EC_BLOCKS_TABLE = [
		1,
		1,
		1,
		1,
		1,
		1,
		1,
		1,
		1,
		1,
		2,
		2,
		1,
		2,
		2,
		4,
		1,
		2,
		4,
		4,
		2,
		4,
		4,
		4,
		2,
		4,
		6,
		5,
		2,
		4,
		6,
		6,
		2,
		5,
		8,
		8,
		4,
		5,
		8,
		8,
		4,
		5,
		8,
		11,
		4,
		8,
		10,
		11,
		4,
		9,
		12,
		16,
		4,
		9,
		16,
		16,
		6,
		10,
		12,
		18,
		6,
		10,
		17,
		16,
		6,
		11,
		16,
		19,
		6,
		13,
		18,
		21,
		7,
		14,
		21,
		25,
		8,
		16,
		20,
		25,
		8,
		17,
		23,
		25,
		9,
		17,
		23,
		34,
		9,
		18,
		25,
		30,
		10,
		20,
		27,
		32,
		12,
		21,
		29,
		35,
		12,
		23,
		34,
		37,
		12,
		25,
		34,
		40,
		13,
		26,
		35,
		42,
		14,
		28,
		38,
		45,
		15,
		29,
		40,
		48,
		16,
		31,
		43,
		51,
		17,
		33,
		45,
		54,
		18,
		35,
		48,
		57,
		19,
		37,
		51,
		60,
		19,
		38,
		53,
		63,
		20,
		40,
		56,
		66,
		21,
		43,
		59,
		70,
		22,
		45,
		62,
		74,
		24,
		47,
		65,
		77,
		25,
		49,
		68,
		81
	];
	var EC_CODEWORDS_TABLE = [
		7,
		10,
		13,
		17,
		10,
		16,
		22,
		28,
		15,
		26,
		36,
		44,
		20,
		36,
		52,
		64,
		26,
		48,
		72,
		88,
		36,
		64,
		96,
		112,
		40,
		72,
		108,
		130,
		48,
		88,
		132,
		156,
		60,
		110,
		160,
		192,
		72,
		130,
		192,
		224,
		80,
		150,
		224,
		264,
		96,
		176,
		260,
		308,
		104,
		198,
		288,
		352,
		120,
		216,
		320,
		384,
		132,
		240,
		360,
		432,
		144,
		280,
		408,
		480,
		168,
		308,
		448,
		532,
		180,
		338,
		504,
		588,
		196,
		364,
		546,
		650,
		224,
		416,
		600,
		700,
		224,
		442,
		644,
		750,
		252,
		476,
		690,
		816,
		270,
		504,
		750,
		900,
		300,
		560,
		810,
		960,
		312,
		588,
		870,
		1050,
		336,
		644,
		952,
		1110,
		360,
		700,
		1020,
		1200,
		390,
		728,
		1050,
		1260,
		420,
		784,
		1140,
		1350,
		450,
		812,
		1200,
		1440,
		480,
		868,
		1290,
		1530,
		510,
		924,
		1350,
		1620,
		540,
		980,
		1440,
		1710,
		570,
		1036,
		1530,
		1800,
		570,
		1064,
		1590,
		1890,
		600,
		1120,
		1680,
		1980,
		630,
		1204,
		1770,
		2100,
		660,
		1260,
		1860,
		2220,
		720,
		1316,
		1950,
		2310,
		750,
		1372,
		2040,
		2430
	];
	/**
	* Returns the number of error correction block that the QR Code should contain
	* for the specified version and error correction level.
	*
	* @param  {Number} version              QR Code version
	* @param  {Number} errorCorrectionLevel Error correction level
	* @return {Number}                      Number of error correction blocks
	*/
	exports.getBlocksCount = function getBlocksCount(version, errorCorrectionLevel) {
		switch (errorCorrectionLevel) {
			case ECLevel.L: return EC_BLOCKS_TABLE[(version - 1) * 4 + 0];
			case ECLevel.M: return EC_BLOCKS_TABLE[(version - 1) * 4 + 1];
			case ECLevel.Q: return EC_BLOCKS_TABLE[(version - 1) * 4 + 2];
			case ECLevel.H: return EC_BLOCKS_TABLE[(version - 1) * 4 + 3];
			default: return;
		}
	};
	/**
	* Returns the number of error correction codewords to use for the specified
	* version and error correction level.
	*
	* @param  {Number} version              QR Code version
	* @param  {Number} errorCorrectionLevel Error correction level
	* @return {Number}                      Number of error correction codewords
	*/
	exports.getTotalCodewordsCount = function getTotalCodewordsCount(version, errorCorrectionLevel) {
		switch (errorCorrectionLevel) {
			case ECLevel.L: return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0];
			case ECLevel.M: return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1];
			case ECLevel.Q: return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2];
			case ECLevel.H: return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3];
			default: return;
		}
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/galois-field.js
var require_galois_field = /* @__PURE__ */ __commonJSMin(((exports) => {
	var EXP_TABLE = /* @__PURE__ */ new Uint8Array(512);
	var LOG_TABLE = /* @__PURE__ */ new Uint8Array(256);
	(function initTables() {
		let x = 1;
		for (let i = 0; i < 255; i++) {
			EXP_TABLE[i] = x;
			LOG_TABLE[x] = i;
			x <<= 1;
			if (x & 256) x ^= 285;
		}
		for (let i = 255; i < 512; i++) EXP_TABLE[i] = EXP_TABLE[i - 255];
	})();
	/**
	* Returns log value of n inside Galois Field
	*
	* @param  {Number} n
	* @return {Number}
	*/
	exports.log = function log(n) {
		if (n < 1) throw new Error("log(" + n + ")");
		return LOG_TABLE[n];
	};
	/**
	* Returns anti-log value of n inside Galois Field
	*
	* @param  {Number} n
	* @return {Number}
	*/
	exports.exp = function exp(n) {
		return EXP_TABLE[n];
	};
	/**
	* Multiplies two number inside Galois Field
	*
	* @param  {Number} x
	* @param  {Number} y
	* @return {Number}
	*/
	exports.mul = function mul(x, y) {
		if (x === 0 || y === 0) return 0;
		return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]];
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/polynomial.js
var require_polynomial = /* @__PURE__ */ __commonJSMin(((exports) => {
	var GF = require_galois_field();
	/**
	* Multiplies two polynomials inside Galois Field
	*
	* @param  {Uint8Array} p1 Polynomial
	* @param  {Uint8Array} p2 Polynomial
	* @return {Uint8Array}    Product of p1 and p2
	*/
	exports.mul = function mul(p1, p2) {
		const coeff = new Uint8Array(p1.length + p2.length - 1);
		for (let i = 0; i < p1.length; i++) for (let j = 0; j < p2.length; j++) coeff[i + j] ^= GF.mul(p1[i], p2[j]);
		return coeff;
	};
	/**
	* Calculate the remainder of polynomials division
	*
	* @param  {Uint8Array} divident Polynomial
	* @param  {Uint8Array} divisor  Polynomial
	* @return {Uint8Array}          Remainder
	*/
	exports.mod = function mod(divident, divisor) {
		let result = new Uint8Array(divident);
		while (result.length - divisor.length >= 0) {
			const coeff = result[0];
			for (let i = 0; i < divisor.length; i++) result[i] ^= GF.mul(divisor[i], coeff);
			let offset = 0;
			while (offset < result.length && result[offset] === 0) offset++;
			result = result.slice(offset);
		}
		return result;
	};
	/**
	* Generate an irreducible generator polynomial of specified degree
	* (used by Reed-Solomon encoder)
	*
	* @param  {Number} degree Degree of the generator polynomial
	* @return {Uint8Array}    Buffer containing polynomial coefficients
	*/
	exports.generateECPolynomial = function generateECPolynomial(degree) {
		let poly = new Uint8Array([1]);
		for (let i = 0; i < degree; i++) poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]));
		return poly;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/reed-solomon-encoder.js
var require_reed_solomon_encoder = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Polynomial = require_polynomial();
	function ReedSolomonEncoder(degree) {
		this.genPoly = void 0;
		this.degree = degree;
		if (this.degree) this.initialize(this.degree);
	}
	/**
	* Initialize the encoder.
	* The input param should correspond to the number of error correction codewords.
	*
	* @param  {Number} degree
	*/
	ReedSolomonEncoder.prototype.initialize = function initialize(degree) {
		this.degree = degree;
		this.genPoly = Polynomial.generateECPolynomial(this.degree);
	};
	/**
	* Encodes a chunk of data
	*
	* @param  {Uint8Array} data Buffer containing input data
	* @return {Uint8Array}      Buffer containing encoded data
	*/
	ReedSolomonEncoder.prototype.encode = function encode(data) {
		if (!this.genPoly) throw new Error("Encoder not initialized");
		const paddedData = new Uint8Array(data.length + this.degree);
		paddedData.set(data);
		const remainder = Polynomial.mod(paddedData, this.genPoly);
		const start = this.degree - remainder.length;
		if (start > 0) {
			const buff = new Uint8Array(this.degree);
			buff.set(remainder, start);
			return buff;
		}
		return remainder;
	};
	module.exports = ReedSolomonEncoder;
}));
//#endregion
//#region node_modules/qrcode/lib/core/version-check.js
var require_version_check = /* @__PURE__ */ __commonJSMin(((exports) => {
	/**
	* Check if QR Code version is valid
	*
	* @param  {Number}  version QR Code version
	* @return {Boolean}         true if valid version, false otherwise
	*/
	exports.isValid = function isValid(version) {
		return !isNaN(version) && version >= 1 && version <= 40;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/regex.js
var require_regex = /* @__PURE__ */ __commonJSMin(((exports) => {
	var numeric = "[0-9]+";
	var alphanumeric = "[A-Z $%*+\\-./:]+";
	var kanji = "(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+";
	kanji = kanji.replace(/u/g, "\\u");
	var byte = "(?:(?![A-Z0-9 $%*+\\-./:]|" + kanji + ")(?:.|[\r\n]))+";
	exports.KANJI = new RegExp(kanji, "g");
	exports.BYTE_KANJI = /* @__PURE__ */ new RegExp("[^A-Z0-9 $%*+\\-./:]+", "g");
	exports.BYTE = new RegExp(byte, "g");
	exports.NUMERIC = new RegExp(numeric, "g");
	exports.ALPHANUMERIC = new RegExp(alphanumeric, "g");
	var TEST_KANJI = new RegExp("^" + kanji + "$");
	var TEST_NUMERIC = /* @__PURE__ */ new RegExp("^[0-9]+$");
	var TEST_ALPHANUMERIC = /* @__PURE__ */ new RegExp("^[A-Z0-9 $%*+\\-./:]+$");
	exports.testKanji = function testKanji(str) {
		return TEST_KANJI.test(str);
	};
	exports.testNumeric = function testNumeric(str) {
		return TEST_NUMERIC.test(str);
	};
	exports.testAlphanumeric = function testAlphanumeric(str) {
		return TEST_ALPHANUMERIC.test(str);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/mode.js
var require_mode = /* @__PURE__ */ __commonJSMin(((exports) => {
	var VersionCheck = require_version_check();
	var Regex = require_regex();
	/**
	* Numeric mode encodes data from the decimal digit set (0 - 9)
	* (byte values 30HEX to 39HEX).
	* Normally, 3 data characters are represented by 10 bits.
	*
	* @type {Object}
	*/
	exports.NUMERIC = {
		id: "Numeric",
		bit: 1,
		ccBits: [
			10,
			12,
			14
		]
	};
	/**
	* Alphanumeric mode encodes data from a set of 45 characters,
	* i.e. 10 numeric digits (0 - 9),
	*      26 alphabetic characters (A - Z),
	*   and 9 symbols (SP, $, %, *, +, -, ., /, :).
	* Normally, two input characters are represented by 11 bits.
	*
	* @type {Object}
	*/
	exports.ALPHANUMERIC = {
		id: "Alphanumeric",
		bit: 2,
		ccBits: [
			9,
			11,
			13
		]
	};
	/**
	* In byte mode, data is encoded at 8 bits per character.
	*
	* @type {Object}
	*/
	exports.BYTE = {
		id: "Byte",
		bit: 4,
		ccBits: [
			8,
			16,
			16
		]
	};
	/**
	* The Kanji mode efficiently encodes Kanji characters in accordance with
	* the Shift JIS system based on JIS X 0208.
	* The Shift JIS values are shifted from the JIS X 0208 values.
	* JIS X 0208 gives details of the shift coded representation.
	* Each two-byte character value is compacted to a 13-bit binary codeword.
	*
	* @type {Object}
	*/
	exports.KANJI = {
		id: "Kanji",
		bit: 8,
		ccBits: [
			8,
			10,
			12
		]
	};
	/**
	* Mixed mode will contain a sequences of data in a combination of any of
	* the modes described above
	*
	* @type {Object}
	*/
	exports.MIXED = { bit: -1 };
	/**
	* Returns the number of bits needed to store the data length
	* according to QR Code specifications.
	*
	* @param  {Mode}   mode    Data mode
	* @param  {Number} version QR Code version
	* @return {Number}         Number of bits
	*/
	exports.getCharCountIndicator = function getCharCountIndicator(mode, version) {
		if (!mode.ccBits) throw new Error("Invalid mode: " + mode);
		if (!VersionCheck.isValid(version)) throw new Error("Invalid version: " + version);
		if (version >= 1 && version < 10) return mode.ccBits[0];
		else if (version < 27) return mode.ccBits[1];
		return mode.ccBits[2];
	};
	/**
	* Returns the most efficient mode to store the specified data
	*
	* @param  {String} dataStr Input data string
	* @return {Mode}           Best mode
	*/
	exports.getBestModeForData = function getBestModeForData(dataStr) {
		if (Regex.testNumeric(dataStr)) return exports.NUMERIC;
		else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC;
		else if (Regex.testKanji(dataStr)) return exports.KANJI;
		else return exports.BYTE;
	};
	/**
	* Return mode name as string
	*
	* @param {Mode} mode Mode object
	* @returns {String}  Mode name
	*/
	exports.toString = function toString(mode) {
		if (mode && mode.id) return mode.id;
		throw new Error("Invalid mode");
	};
	/**
	* Check if input param is a valid mode object
	*
	* @param   {Mode}    mode Mode object
	* @returns {Boolean} True if valid mode, false otherwise
	*/
	exports.isValid = function isValid(mode) {
		return mode && mode.bit && mode.ccBits;
	};
	/**
	* Get mode object from its name
	*
	* @param   {String} string Mode name
	* @returns {Mode}          Mode object
	*/
	function fromString(string) {
		if (typeof string !== "string") throw new Error("Param is not a string");
		switch (string.toLowerCase()) {
			case "numeric": return exports.NUMERIC;
			case "alphanumeric": return exports.ALPHANUMERIC;
			case "kanji": return exports.KANJI;
			case "byte": return exports.BYTE;
			default: throw new Error("Unknown mode: " + string);
		}
	}
	/**
	* Returns mode from a value.
	* If value is not a valid mode, returns defaultValue
	*
	* @param  {Mode|String} value        Encoding mode
	* @param  {Mode}        defaultValue Fallback value
	* @return {Mode}                     Encoding mode
	*/
	exports.from = function from(value, defaultValue) {
		if (exports.isValid(value)) return value;
		try {
			return fromString(value);
		} catch (e) {
			return defaultValue;
		}
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/version.js
var require_version = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils$1();
	var ECCode = require_error_correction_code();
	var ECLevel = require_error_correction_level();
	var Mode = require_mode();
	var VersionCheck = require_version_check();
	var G18 = 7973;
	var G18_BCH = Utils.getBCHDigit(G18);
	function getBestVersionForDataLength(mode, length, errorCorrectionLevel) {
		for (let currentVersion = 1; currentVersion <= 40; currentVersion++) if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) return currentVersion;
	}
	function getReservedBitsCount(mode, version) {
		return Mode.getCharCountIndicator(mode, version) + 4;
	}
	function getTotalBitsFromDataArray(segments, version) {
		let totalBits = 0;
		segments.forEach(function(data) {
			const reservedBits = getReservedBitsCount(data.mode, version);
			totalBits += reservedBits + data.getBitsLength();
		});
		return totalBits;
	}
	function getBestVersionForMixedData(segments, errorCorrectionLevel) {
		for (let currentVersion = 1; currentVersion <= 40; currentVersion++) if (getTotalBitsFromDataArray(segments, currentVersion) <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) return currentVersion;
	}
	/**
	* Returns version number from a value.
	* If value is not a valid version, returns defaultValue
	*
	* @param  {Number|String} value        QR Code version
	* @param  {Number}        defaultValue Fallback value
	* @return {Number}                     QR Code version number
	*/
	exports.from = function from(value, defaultValue) {
		if (VersionCheck.isValid(value)) return parseInt(value, 10);
		return defaultValue;
	};
	/**
	* Returns how much data can be stored with the specified QR code version
	* and error correction level
	*
	* @param  {Number} version              QR Code version (1-40)
	* @param  {Number} errorCorrectionLevel Error correction level
	* @param  {Mode}   mode                 Data mode
	* @return {Number}                      Quantity of storable data
	*/
	exports.getCapacity = function getCapacity(version, errorCorrectionLevel, mode) {
		if (!VersionCheck.isValid(version)) throw new Error("Invalid QR Code version");
		if (typeof mode === "undefined") mode = Mode.BYTE;
		const dataTotalCodewordsBits = (Utils.getSymbolTotalCodewords(version) - ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)) * 8;
		if (mode === Mode.MIXED) return dataTotalCodewordsBits;
		const usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version);
		switch (mode) {
			case Mode.NUMERIC: return Math.floor(usableBits / 10 * 3);
			case Mode.ALPHANUMERIC: return Math.floor(usableBits / 11 * 2);
			case Mode.KANJI: return Math.floor(usableBits / 13);
			case Mode.BYTE:
			default: return Math.floor(usableBits / 8);
		}
	};
	/**
	* Returns the minimum version needed to contain the amount of data
	*
	* @param  {Segment} data                    Segment of data
	* @param  {Number} [errorCorrectionLevel=H] Error correction level
	* @param  {Mode} mode                       Data mode
	* @return {Number}                          QR Code version
	*/
	exports.getBestVersionForData = function getBestVersionForData(data, errorCorrectionLevel) {
		let seg;
		const ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M);
		if (Array.isArray(data)) {
			if (data.length > 1) return getBestVersionForMixedData(data, ecl);
			if (data.length === 0) return 1;
			seg = data[0];
		} else seg = data;
		return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl);
	};
	/**
	* Returns version information with relative error correction bits
	*
	* The version information is included in QR Code symbols of version 7 or larger.
	* It consists of an 18-bit sequence containing 6 data bits,
	* with 12 error correction bits calculated using the (18, 6) Golay code.
	*
	* @param  {Number} version QR Code version
	* @return {Number}         Encoded version info bits
	*/
	exports.getEncodedBits = function getEncodedBits(version) {
		if (!VersionCheck.isValid(version) || version < 7) throw new Error("Invalid QR Code version");
		let d = version << 12;
		while (Utils.getBCHDigit(d) - G18_BCH >= 0) d ^= G18 << Utils.getBCHDigit(d) - G18_BCH;
		return version << 12 | d;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/format-info.js
var require_format_info = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils$1();
	var G15 = 1335;
	var G15_MASK = 21522;
	var G15_BCH = Utils.getBCHDigit(G15);
	/**
	* Returns format information with relative error correction bits
	*
	* The format information is a 15-bit sequence containing 5 data bits,
	* with 10 error correction bits calculated using the (15, 5) BCH code.
	*
	* @param  {Number} errorCorrectionLevel Error correction level
	* @param  {Number} mask                 Mask pattern
	* @return {Number}                      Encoded format information bits
	*/
	exports.getEncodedBits = function getEncodedBits(errorCorrectionLevel, mask) {
		const data = errorCorrectionLevel.bit << 3 | mask;
		let d = data << 10;
		while (Utils.getBCHDigit(d) - G15_BCH >= 0) d ^= G15 << Utils.getBCHDigit(d) - G15_BCH;
		return (data << 10 | d) ^ G15_MASK;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/numeric-data.js
var require_numeric_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Mode = require_mode();
	function NumericData(data) {
		this.mode = Mode.NUMERIC;
		this.data = data.toString();
	}
	NumericData.getBitsLength = function getBitsLength(length) {
		return 10 * Math.floor(length / 3) + (length % 3 ? length % 3 * 3 + 1 : 0);
	};
	NumericData.prototype.getLength = function getLength() {
		return this.data.length;
	};
	NumericData.prototype.getBitsLength = function getBitsLength() {
		return NumericData.getBitsLength(this.data.length);
	};
	NumericData.prototype.write = function write(bitBuffer) {
		let i, group, value;
		for (i = 0; i + 3 <= this.data.length; i += 3) {
			group = this.data.substr(i, 3);
			value = parseInt(group, 10);
			bitBuffer.put(value, 10);
		}
		const remainingNum = this.data.length - i;
		if (remainingNum > 0) {
			group = this.data.substr(i);
			value = parseInt(group, 10);
			bitBuffer.put(value, remainingNum * 3 + 1);
		}
	};
	module.exports = NumericData;
}));
//#endregion
//#region node_modules/qrcode/lib/core/alphanumeric-data.js
var require_alphanumeric_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Mode = require_mode();
	/**
	* Array of characters available in alphanumeric mode
	*
	* As per QR Code specification, to each character
	* is assigned a value from 0 to 44 which in this case coincides
	* with the array index
	*
	* @type {Array}
	*/
	var ALPHA_NUM_CHARS = [
		"0",
		"1",
		"2",
		"3",
		"4",
		"5",
		"6",
		"7",
		"8",
		"9",
		"A",
		"B",
		"C",
		"D",
		"E",
		"F",
		"G",
		"H",
		"I",
		"J",
		"K",
		"L",
		"M",
		"N",
		"O",
		"P",
		"Q",
		"R",
		"S",
		"T",
		"U",
		"V",
		"W",
		"X",
		"Y",
		"Z",
		" ",
		"$",
		"%",
		"*",
		"+",
		"-",
		".",
		"/",
		":"
	];
	function AlphanumericData(data) {
		this.mode = Mode.ALPHANUMERIC;
		this.data = data;
	}
	AlphanumericData.getBitsLength = function getBitsLength(length) {
		return 11 * Math.floor(length / 2) + 6 * (length % 2);
	};
	AlphanumericData.prototype.getLength = function getLength() {
		return this.data.length;
	};
	AlphanumericData.prototype.getBitsLength = function getBitsLength() {
		return AlphanumericData.getBitsLength(this.data.length);
	};
	AlphanumericData.prototype.write = function write(bitBuffer) {
		let i;
		for (i = 0; i + 2 <= this.data.length; i += 2) {
			let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45;
			value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1]);
			bitBuffer.put(value, 11);
		}
		if (this.data.length % 2) bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6);
	};
	module.exports = AlphanumericData;
}));
//#endregion
//#region node_modules/qrcode/lib/core/byte-data.js
var require_byte_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Mode = require_mode();
	function ByteData(data) {
		this.mode = Mode.BYTE;
		if (typeof data === "string") this.data = new TextEncoder().encode(data);
		else this.data = new Uint8Array(data);
	}
	ByteData.getBitsLength = function getBitsLength(length) {
		return length * 8;
	};
	ByteData.prototype.getLength = function getLength() {
		return this.data.length;
	};
	ByteData.prototype.getBitsLength = function getBitsLength() {
		return ByteData.getBitsLength(this.data.length);
	};
	ByteData.prototype.write = function(bitBuffer) {
		for (let i = 0, l = this.data.length; i < l; i++) bitBuffer.put(this.data[i], 8);
	};
	module.exports = ByteData;
}));
//#endregion
//#region node_modules/qrcode/lib/core/kanji-data.js
var require_kanji_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var Mode = require_mode();
	var Utils = require_utils$1();
	function KanjiData(data) {
		this.mode = Mode.KANJI;
		this.data = data;
	}
	KanjiData.getBitsLength = function getBitsLength(length) {
		return length * 13;
	};
	KanjiData.prototype.getLength = function getLength() {
		return this.data.length;
	};
	KanjiData.prototype.getBitsLength = function getBitsLength() {
		return KanjiData.getBitsLength(this.data.length);
	};
	KanjiData.prototype.write = function(bitBuffer) {
		let i;
		for (i = 0; i < this.data.length; i++) {
			let value = Utils.toSJIS(this.data[i]);
			if (value >= 33088 && value <= 40956) value -= 33088;
			else if (value >= 57408 && value <= 60351) value -= 49472;
			else throw new Error("Invalid SJIS character: " + this.data[i] + "\nMake sure your charset is UTF-8");
			value = (value >>> 8 & 255) * 192 + (value & 255);
			bitBuffer.put(value, 13);
		}
	};
	module.exports = KanjiData;
}));
//#endregion
//#region node_modules/dijkstrajs/dijkstra.js
var require_dijkstra = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	/******************************************************************************
	* Created 2008-08-19.
	*
	* Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
	*
	* Copyright (C) 2008
	*   Wyatt Baldwin <self@wyattbaldwin.com>
	*   All rights reserved
	*
	* Licensed under the MIT license.
	*
	*   http://www.opensource.org/licenses/mit-license.php
	*
	* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	* THE SOFTWARE.
	*****************************************************************************/
	var dijkstra = {
		single_source_shortest_paths: function(graph, s, d) {
			var predecessors = {};
			var costs = {};
			costs[s] = 0;
			var open = dijkstra.PriorityQueue.make();
			open.push(s, 0);
			var closest, u, v, cost_of_s_to_u, adjacent_nodes, cost_of_e, cost_of_s_to_u_plus_cost_of_e, cost_of_s_to_v, first_visit;
			while (!open.empty()) {
				closest = open.pop();
				u = closest.value;
				cost_of_s_to_u = closest.cost;
				adjacent_nodes = graph[u] || {};
				for (v in adjacent_nodes) if (adjacent_nodes.hasOwnProperty(v)) {
					cost_of_e = adjacent_nodes[v];
					cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;
					cost_of_s_to_v = costs[v];
					first_visit = typeof costs[v] === "undefined";
					if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
						costs[v] = cost_of_s_to_u_plus_cost_of_e;
						open.push(v, cost_of_s_to_u_plus_cost_of_e);
						predecessors[v] = u;
					}
				}
			}
			if (typeof d !== "undefined" && typeof costs[d] === "undefined") {
				var msg = [
					"Could not find a path from ",
					s,
					" to ",
					d,
					"."
				].join("");
				throw new Error(msg);
			}
			return predecessors;
		},
		extract_shortest_path_from_predecessor_list: function(predecessors, d) {
			var nodes = [];
			var u = d;
			while (u) {
				nodes.push(u);
				predecessors[u];
				u = predecessors[u];
			}
			nodes.reverse();
			return nodes;
		},
		find_path: function(graph, s, d) {
			var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
			return dijkstra.extract_shortest_path_from_predecessor_list(predecessors, d);
		},
		/**
		* A very naive priority queue implementation.
		*/
		PriorityQueue: {
			make: function(opts) {
				var T = dijkstra.PriorityQueue, t = {}, key;
				opts = opts || {};
				for (key in T) if (T.hasOwnProperty(key)) t[key] = T[key];
				t.queue = [];
				t.sorter = opts.sorter || T.default_sorter;
				return t;
			},
			default_sorter: function(a, b) {
				return a.cost - b.cost;
			},
			/**
			* Add a new item to the queue and ensure the highest priority element
			* is at the front of the queue.
			*/
			push: function(value, cost) {
				var item = {
					value,
					cost
				};
				this.queue.push(item);
				this.queue.sort(this.sorter);
			},
			/**
			* Return the highest priority element in the queue.
			*/
			pop: function() {
				return this.queue.shift();
			},
			empty: function() {
				return this.queue.length === 0;
			}
		}
	};
	if (typeof module !== "undefined") module.exports = dijkstra;
}));
//#endregion
//#region node_modules/qrcode/lib/core/segments.js
var require_segments = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Mode = require_mode();
	var NumericData = require_numeric_data();
	var AlphanumericData = require_alphanumeric_data();
	var ByteData = require_byte_data();
	var KanjiData = require_kanji_data();
	var Regex = require_regex();
	var Utils = require_utils$1();
	var dijkstra = require_dijkstra();
	/**
	* Returns UTF8 byte length
	*
	* @param  {String} str Input string
	* @return {Number}     Number of byte
	*/
	function getStringByteLength(str) {
		return unescape(encodeURIComponent(str)).length;
	}
	/**
	* Get a list of segments of the specified mode
	* from a string
	*
	* @param  {Mode}   mode Segment mode
	* @param  {String} str  String to process
	* @return {Array}       Array of object with segments data
	*/
	function getSegments(regex, mode, str) {
		const segments = [];
		let result;
		while ((result = regex.exec(str)) !== null) segments.push({
			data: result[0],
			index: result.index,
			mode,
			length: result[0].length
		});
		return segments;
	}
	/**
	* Extracts a series of segments with the appropriate
	* modes from a string
	*
	* @param  {String} dataStr Input string
	* @return {Array}          Array of object with segments data
	*/
	function getSegmentsFromString(dataStr) {
		const numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr);
		const alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr);
		let byteSegs;
		let kanjiSegs;
		if (Utils.isKanjiModeEnabled()) {
			byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr);
			kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr);
		} else {
			byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr);
			kanjiSegs = [];
		}
		return numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs).sort(function(s1, s2) {
			return s1.index - s2.index;
		}).map(function(obj) {
			return {
				data: obj.data,
				mode: obj.mode,
				length: obj.length
			};
		});
	}
	/**
	* Returns how many bits are needed to encode a string of
	* specified length with the specified mode
	*
	* @param  {Number} length String length
	* @param  {Mode} mode     Segment mode
	* @return {Number}        Bit length
	*/
	function getSegmentBitsLength(length, mode) {
		switch (mode) {
			case Mode.NUMERIC: return NumericData.getBitsLength(length);
			case Mode.ALPHANUMERIC: return AlphanumericData.getBitsLength(length);
			case Mode.KANJI: return KanjiData.getBitsLength(length);
			case Mode.BYTE: return ByteData.getBitsLength(length);
		}
	}
	/**
	* Merges adjacent segments which have the same mode
	*
	* @param  {Array} segs Array of object with segments data
	* @return {Array}      Array of object with segments data
	*/
	function mergeSegments(segs) {
		return segs.reduce(function(acc, curr) {
			const prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null;
			if (prevSeg && prevSeg.mode === curr.mode) {
				acc[acc.length - 1].data += curr.data;
				return acc;
			}
			acc.push(curr);
			return acc;
		}, []);
	}
	/**
	* Generates a list of all possible nodes combination which
	* will be used to build a segments graph.
	*
	* Nodes are divided by groups. Each group will contain a list of all the modes
	* in which is possible to encode the given text.
	*
	* For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.
	* The group for '12345' will contain then 3 objects, one for each
	* possible encoding mode.
	*
	* Each node represents a possible segment.
	*
	* @param  {Array} segs Array of object with segments data
	* @return {Array}      Array of object with segments data
	*/
	function buildNodes(segs) {
		const nodes = [];
		for (let i = 0; i < segs.length; i++) {
			const seg = segs[i];
			switch (seg.mode) {
				case Mode.NUMERIC:
					nodes.push([
						seg,
						{
							data: seg.data,
							mode: Mode.ALPHANUMERIC,
							length: seg.length
						},
						{
							data: seg.data,
							mode: Mode.BYTE,
							length: seg.length
						}
					]);
					break;
				case Mode.ALPHANUMERIC:
					nodes.push([seg, {
						data: seg.data,
						mode: Mode.BYTE,
						length: seg.length
					}]);
					break;
				case Mode.KANJI:
					nodes.push([seg, {
						data: seg.data,
						mode: Mode.BYTE,
						length: getStringByteLength(seg.data)
					}]);
					break;
				case Mode.BYTE: nodes.push([{
					data: seg.data,
					mode: Mode.BYTE,
					length: getStringByteLength(seg.data)
				}]);
			}
		}
		return nodes;
	}
	/**
	* Builds a graph from a list of nodes.
	* All segments in each node group will be connected with all the segments of
	* the next group and so on.
	*
	* At each connection will be assigned a weight depending on the
	* segment's byte length.
	*
	* @param  {Array} nodes    Array of object with segments data
	* @param  {Number} version QR Code version
	* @return {Object}         Graph of all possible segments
	*/
	function buildGraph(nodes, version) {
		const table = {};
		const graph = { start: {} };
		let prevNodeIds = ["start"];
		for (let i = 0; i < nodes.length; i++) {
			const nodeGroup = nodes[i];
			const currentNodeIds = [];
			for (let j = 0; j < nodeGroup.length; j++) {
				const node = nodeGroup[j];
				const key = "" + i + j;
				currentNodeIds.push(key);
				table[key] = {
					node,
					lastCount: 0
				};
				graph[key] = {};
				for (let n = 0; n < prevNodeIds.length; n++) {
					const prevNodeId = prevNodeIds[n];
					if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
						graph[prevNodeId][key] = getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) - getSegmentBitsLength(table[prevNodeId].lastCount, node.mode);
						table[prevNodeId].lastCount += node.length;
					} else {
						if (table[prevNodeId]) table[prevNodeId].lastCount = node.length;
						graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) + 4 + Mode.getCharCountIndicator(node.mode, version);
					}
				}
			}
			prevNodeIds = currentNodeIds;
		}
		for (let n = 0; n < prevNodeIds.length; n++) graph[prevNodeIds[n]].end = 0;
		return {
			map: graph,
			table
		};
	}
	/**
	* Builds a segment from a specified data and mode.
	* If a mode is not specified, the more suitable will be used.
	*
	* @param  {String} data             Input data
	* @param  {Mode | String} modesHint Data mode
	* @return {Segment}                 Segment
	*/
	function buildSingleSegment(data, modesHint) {
		let mode;
		const bestMode = Mode.getBestModeForData(data);
		mode = Mode.from(modesHint, bestMode);
		if (mode !== Mode.BYTE && mode.bit < bestMode.bit) throw new Error("\"" + data + "\" cannot be encoded with mode " + Mode.toString(mode) + ".\n Suggested mode is: " + Mode.toString(bestMode));
		if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) mode = Mode.BYTE;
		switch (mode) {
			case Mode.NUMERIC: return new NumericData(data);
			case Mode.ALPHANUMERIC: return new AlphanumericData(data);
			case Mode.KANJI: return new KanjiData(data);
			case Mode.BYTE: return new ByteData(data);
		}
	}
	/**
	* Builds a list of segments from an array.
	* Array can contain Strings or Objects with segment's info.
	*
	* For each item which is a string, will be generated a segment with the given
	* string and the more appropriate encoding mode.
	*
	* For each item which is an object, will be generated a segment with the given
	* data and mode.
	* Objects must contain at least the property "data".
	* If property "mode" is not present, the more suitable mode will be used.
	*
	* @param  {Array} array Array of objects with segments data
	* @return {Array}       Array of Segments
	*/
	exports.fromArray = function fromArray(array) {
		return array.reduce(function(acc, seg) {
			if (typeof seg === "string") acc.push(buildSingleSegment(seg, null));
			else if (seg.data) acc.push(buildSingleSegment(seg.data, seg.mode));
			return acc;
		}, []);
	};
	/**
	* Builds an optimized sequence of segments from a string,
	* which will produce the shortest possible bitstream.
	*
	* @param  {String} data    Input string
	* @param  {Number} version QR Code version
	* @return {Array}          Array of segments
	*/
	exports.fromString = function fromString(data, version) {
		const graph = buildGraph(buildNodes(getSegmentsFromString(data, Utils.isKanjiModeEnabled())), version);
		const path = dijkstra.find_path(graph.map, "start", "end");
		const optimizedSegs = [];
		for (let i = 1; i < path.length - 1; i++) optimizedSegs.push(graph.table[path[i]].node);
		return exports.fromArray(mergeSegments(optimizedSegs));
	};
	/**
	* Splits a string in various segments with the modes which
	* best represent their content.
	* The produced segments are far from being optimized.
	* The output of this function is only used to estimate a QR Code version
	* which may contain the data.
	*
	* @param  {string} data Input string
	* @return {Array}       Array of segments
	*/
	exports.rawSplit = function rawSplit(data) {
		return exports.fromArray(getSegmentsFromString(data, Utils.isKanjiModeEnabled()));
	};
}));
//#endregion
//#region node_modules/qrcode/lib/core/qrcode.js
var require_qrcode = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils$1();
	var ECLevel = require_error_correction_level();
	var BitBuffer = require_bit_buffer();
	var BitMatrix = require_bit_matrix();
	var AlignmentPattern = require_alignment_pattern();
	var FinderPattern = require_finder_pattern();
	var MaskPattern = require_mask_pattern();
	var ECCode = require_error_correction_code();
	var ReedSolomonEncoder = require_reed_solomon_encoder();
	var Version = require_version();
	var FormatInfo = require_format_info();
	var Mode = require_mode();
	var Segments = require_segments();
	/**
	* QRCode for JavaScript
	*
	* modified by Ryan Day for nodejs support
	* Copyright (c) 2011 Ryan Day
	*
	* Licensed under the MIT license:
	*   http://www.opensource.org/licenses/mit-license.php
	*
	//---------------------------------------------------------------------
	// QRCode for JavaScript
	//
	// Copyright (c) 2009 Kazuhiko Arase
	//
	// URL: http://www.d-project.com/
	//
	// Licensed under the MIT license:
	//   http://www.opensource.org/licenses/mit-license.php
	//
	// The word "QR Code" is registered trademark of
	// DENSO WAVE INCORPORATED
	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
	//
	//---------------------------------------------------------------------
	*/
	/**
	* Add finder patterns bits to matrix
	*
	* @param  {BitMatrix} matrix  Modules matrix
	* @param  {Number}    version QR Code version
	*/
	function setupFinderPattern(matrix, version) {
		const size = matrix.size;
		const pos = FinderPattern.getPositions(version);
		for (let i = 0; i < pos.length; i++) {
			const row = pos[i][0];
			const col = pos[i][1];
			for (let r = -1; r <= 7; r++) {
				if (row + r <= -1 || size <= row + r) continue;
				for (let c = -1; c <= 7; c++) {
					if (col + c <= -1 || size <= col + c) continue;
					if (r >= 0 && r <= 6 && (c === 0 || c === 6) || c >= 0 && c <= 6 && (r === 0 || r === 6) || r >= 2 && r <= 4 && c >= 2 && c <= 4) matrix.set(row + r, col + c, true, true);
					else matrix.set(row + r, col + c, false, true);
				}
			}
		}
	}
	/**
	* Add timing pattern bits to matrix
	*
	* Note: this function must be called before {@link setupAlignmentPattern}
	*
	* @param  {BitMatrix} matrix Modules matrix
	*/
	function setupTimingPattern(matrix) {
		const size = matrix.size;
		for (let r = 8; r < size - 8; r++) {
			const value = r % 2 === 0;
			matrix.set(r, 6, value, true);
			matrix.set(6, r, value, true);
		}
	}
	/**
	* Add alignment patterns bits to matrix
	*
	* Note: this function must be called after {@link setupTimingPattern}
	*
	* @param  {BitMatrix} matrix  Modules matrix
	* @param  {Number}    version QR Code version
	*/
	function setupAlignmentPattern(matrix, version) {
		const pos = AlignmentPattern.getPositions(version);
		for (let i = 0; i < pos.length; i++) {
			const row = pos[i][0];
			const col = pos[i][1];
			for (let r = -2; r <= 2; r++) for (let c = -2; c <= 2; c++) if (r === -2 || r === 2 || c === -2 || c === 2 || r === 0 && c === 0) matrix.set(row + r, col + c, true, true);
			else matrix.set(row + r, col + c, false, true);
		}
	}
	/**
	* Add version info bits to matrix
	*
	* @param  {BitMatrix} matrix  Modules matrix
	* @param  {Number}    version QR Code version
	*/
	function setupVersionInfo(matrix, version) {
		const size = matrix.size;
		const bits = Version.getEncodedBits(version);
		let row, col, mod;
		for (let i = 0; i < 18; i++) {
			row = Math.floor(i / 3);
			col = i % 3 + size - 8 - 3;
			mod = (bits >> i & 1) === 1;
			matrix.set(row, col, mod, true);
			matrix.set(col, row, mod, true);
		}
	}
	/**
	* Add format info bits to matrix
	*
	* @param  {BitMatrix} matrix               Modules matrix
	* @param  {ErrorCorrectionLevel}    errorCorrectionLevel Error correction level
	* @param  {Number}    maskPattern          Mask pattern reference value
	*/
	function setupFormatInfo(matrix, errorCorrectionLevel, maskPattern) {
		const size = matrix.size;
		const bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern);
		let i, mod;
		for (i = 0; i < 15; i++) {
			mod = (bits >> i & 1) === 1;
			if (i < 6) matrix.set(i, 8, mod, true);
			else if (i < 8) matrix.set(i + 1, 8, mod, true);
			else matrix.set(size - 15 + i, 8, mod, true);
			if (i < 8) matrix.set(8, size - i - 1, mod, true);
			else if (i < 9) matrix.set(8, 15 - i - 1 + 1, mod, true);
			else matrix.set(8, 15 - i - 1, mod, true);
		}
		matrix.set(size - 8, 8, 1, true);
	}
	/**
	* Add encoded data bits to matrix
	*
	* @param  {BitMatrix}  matrix Modules matrix
	* @param  {Uint8Array} data   Data codewords
	*/
	function setupData(matrix, data) {
		const size = matrix.size;
		let inc = -1;
		let row = size - 1;
		let bitIndex = 7;
		let byteIndex = 0;
		for (let col = size - 1; col > 0; col -= 2) {
			if (col === 6) col--;
			while (true) {
				for (let c = 0; c < 2; c++) if (!matrix.isReserved(row, col - c)) {
					let dark = false;
					if (byteIndex < data.length) dark = (data[byteIndex] >>> bitIndex & 1) === 1;
					matrix.set(row, col - c, dark);
					bitIndex--;
					if (bitIndex === -1) {
						byteIndex++;
						bitIndex = 7;
					}
				}
				row += inc;
				if (row < 0 || size <= row) {
					row -= inc;
					inc = -inc;
					break;
				}
			}
		}
	}
	/**
	* Create encoded codewords from data input
	*
	* @param  {Number}   version              QR Code version
	* @param  {ErrorCorrectionLevel}   errorCorrectionLevel Error correction level
	* @param  {ByteData} data                 Data input
	* @return {Uint8Array}                    Buffer containing encoded codewords
	*/
	function createData(version, errorCorrectionLevel, segments) {
		const buffer = new BitBuffer();
		segments.forEach(function(data) {
			buffer.put(data.mode.bit, 4);
			buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version));
			data.write(buffer);
		});
		const dataTotalCodewordsBits = (Utils.getSymbolTotalCodewords(version) - ECCode.getTotalCodewordsCount(version, errorCorrectionLevel)) * 8;
		if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) buffer.put(0, 4);
		while (buffer.getLengthInBits() % 8 !== 0) buffer.putBit(0);
		const remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8;
		for (let i = 0; i < remainingByte; i++) buffer.put(i % 2 ? 17 : 236, 8);
		return createCodewords(buffer, version, errorCorrectionLevel);
	}
	/**
	* Encode input data with Reed-Solomon and return codewords with
	* relative error correction bits
	*
	* @param  {BitBuffer} bitBuffer            Data to encode
	* @param  {Number}    version              QR Code version
	* @param  {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
	* @return {Uint8Array}                     Buffer containing encoded codewords
	*/
	function createCodewords(bitBuffer, version, errorCorrectionLevel) {
		const totalCodewords = Utils.getSymbolTotalCodewords(version);
		const dataTotalCodewords = totalCodewords - ECCode.getTotalCodewordsCount(version, errorCorrectionLevel);
		const ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel);
		const blocksInGroup1 = ecTotalBlocks - totalCodewords % ecTotalBlocks;
		const totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks);
		const dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks);
		const dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1;
		const ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1;
		const rs = new ReedSolomonEncoder(ecCount);
		let offset = 0;
		const dcData = new Array(ecTotalBlocks);
		const ecData = new Array(ecTotalBlocks);
		let maxDataSize = 0;
		const buffer = new Uint8Array(bitBuffer.buffer);
		for (let b = 0; b < ecTotalBlocks; b++) {
			const dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2;
			dcData[b] = buffer.slice(offset, offset + dataSize);
			ecData[b] = rs.encode(dcData[b]);
			offset += dataSize;
			maxDataSize = Math.max(maxDataSize, dataSize);
		}
		const data = new Uint8Array(totalCodewords);
		let index = 0;
		let i, r;
		for (i = 0; i < maxDataSize; i++) for (r = 0; r < ecTotalBlocks; r++) if (i < dcData[r].length) data[index++] = dcData[r][i];
		for (i = 0; i < ecCount; i++) for (r = 0; r < ecTotalBlocks; r++) data[index++] = ecData[r][i];
		return data;
	}
	/**
	* Build QR Code symbol
	*
	* @param  {String} data                 Input string
	* @param  {Number} version              QR Code version
	* @param  {ErrorCorretionLevel} errorCorrectionLevel Error level
	* @param  {MaskPattern} maskPattern     Mask pattern
	* @return {Object}                      Object containing symbol data
	*/
	function createSymbol(data, version, errorCorrectionLevel, maskPattern) {
		let segments;
		if (Array.isArray(data)) segments = Segments.fromArray(data);
		else if (typeof data === "string") {
			let estimatedVersion = version;
			if (!estimatedVersion) {
				const rawSegments = Segments.rawSplit(data);
				estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel);
			}
			segments = Segments.fromString(data, estimatedVersion || 40);
		} else throw new Error("Invalid data");
		const bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel);
		if (!bestVersion) throw new Error("The amount of data is too big to be stored in a QR Code");
		if (!version) version = bestVersion;
		else if (version < bestVersion) throw new Error("\nThe chosen QR Code version cannot contain this amount of data.\nMinimum version required to store current data is: " + bestVersion + ".\n");
		const dataBits = createData(version, errorCorrectionLevel, segments);
		const modules = new BitMatrix(Utils.getSymbolSize(version));
		setupFinderPattern(modules, version);
		setupTimingPattern(modules);
		setupAlignmentPattern(modules, version);
		setupFormatInfo(modules, errorCorrectionLevel, 0);
		if (version >= 7) setupVersionInfo(modules, version);
		setupData(modules, dataBits);
		if (isNaN(maskPattern)) maskPattern = MaskPattern.getBestMask(modules, setupFormatInfo.bind(null, modules, errorCorrectionLevel));
		MaskPattern.applyMask(maskPattern, modules);
		setupFormatInfo(modules, errorCorrectionLevel, maskPattern);
		return {
			modules,
			version,
			errorCorrectionLevel,
			maskPattern,
			segments
		};
	}
	/**
	* QR Code
	*
	* @param {String | Array} data                 Input data
	* @param {Object} options                      Optional configurations
	* @param {Number} options.version              QR Code version
	* @param {String} options.errorCorrectionLevel Error correction level
	* @param {Function} options.toSJISFunc         Helper func to convert utf8 to sjis
	*/
	exports.create = function create(data, options) {
		if (typeof data === "undefined" || data === "") throw new Error("No input text");
		let errorCorrectionLevel = ECLevel.M;
		let version;
		let mask;
		if (typeof options !== "undefined") {
			errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M);
			version = Version.from(options.version);
			mask = MaskPattern.from(options.maskPattern);
			if (options.toSJISFunc) Utils.setToSJISFunction(options.toSJISFunc);
		}
		return createSymbol(data, version, errorCorrectionLevel, mask);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/chunkstream.js
var require_chunkstream = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var util$5 = __require("util");
	var Stream$2 = __require("stream");
	var ChunkStream = module.exports = function() {
		Stream$2.call(this);
		this._buffers = [];
		this._buffered = 0;
		this._reads = [];
		this._paused = false;
		this._encoding = "utf8";
		this.writable = true;
	};
	util$5.inherits(ChunkStream, Stream$2);
	ChunkStream.prototype.read = function(length, callback) {
		this._reads.push({
			length: Math.abs(length),
			allowLess: length < 0,
			func: callback
		});
		process.nextTick(function() {
			this._process();
			if (this._paused && this._reads && this._reads.length > 0) {
				this._paused = false;
				this.emit("drain");
			}
		}.bind(this));
	};
	ChunkStream.prototype.write = function(data, encoding) {
		if (!this.writable) {
			this.emit("error", /* @__PURE__ */ new Error("Stream not writable"));
			return false;
		}
		let dataBuffer;
		if (Buffer.isBuffer(data)) dataBuffer = data;
		else dataBuffer = Buffer.from(data, encoding || this._encoding);
		this._buffers.push(dataBuffer);
		this._buffered += dataBuffer.length;
		this._process();
		if (this._reads && this._reads.length === 0) this._paused = true;
		return this.writable && !this._paused;
	};
	ChunkStream.prototype.end = function(data, encoding) {
		if (data) this.write(data, encoding);
		this.writable = false;
		if (!this._buffers) return;
		if (this._buffers.length === 0) this._end();
		else {
			this._buffers.push(null);
			this._process();
		}
	};
	ChunkStream.prototype.destroySoon = ChunkStream.prototype.end;
	ChunkStream.prototype._end = function() {
		if (this._reads.length > 0) this.emit("error", /* @__PURE__ */ new Error("Unexpected end of input"));
		this.destroy();
	};
	ChunkStream.prototype.destroy = function() {
		if (!this._buffers) return;
		this.writable = false;
		this._reads = null;
		this._buffers = null;
		this.emit("close");
	};
	ChunkStream.prototype._processReadAllowingLess = function(read) {
		this._reads.shift();
		let smallerBuf = this._buffers[0];
		if (smallerBuf.length > read.length) {
			this._buffered -= read.length;
			this._buffers[0] = smallerBuf.slice(read.length);
			read.func.call(this, smallerBuf.slice(0, read.length));
		} else {
			this._buffered -= smallerBuf.length;
			this._buffers.shift();
			read.func.call(this, smallerBuf);
		}
	};
	ChunkStream.prototype._processRead = function(read) {
		this._reads.shift();
		let pos = 0;
		let count = 0;
		let data = Buffer.alloc(read.length);
		while (pos < read.length) {
			let buf = this._buffers[count++];
			let len = Math.min(buf.length, read.length - pos);
			buf.copy(data, pos, 0, len);
			pos += len;
			if (len !== buf.length) this._buffers[--count] = buf.slice(len);
		}
		if (count > 0) this._buffers.splice(0, count);
		this._buffered -= read.length;
		read.func.call(this, data);
	};
	ChunkStream.prototype._process = function() {
		try {
			while (this._buffered > 0 && this._reads && this._reads.length > 0) {
				let read = this._reads[0];
				if (read.allowLess) this._processReadAllowingLess(read);
				else if (this._buffered >= read.length) this._processRead(read);
				else break;
			}
			if (this._buffers && !this.writable) this._end();
		} catch (ex) {
			this.emit("error", ex);
		}
	};
}));
//#endregion
//#region node_modules/pngjs/lib/interlace.js
var require_interlace = /* @__PURE__ */ __commonJSMin(((exports) => {
	var imagePasses = [
		{
			x: [0],
			y: [0]
		},
		{
			x: [4],
			y: [0]
		},
		{
			x: [0, 4],
			y: [4]
		},
		{
			x: [2, 6],
			y: [0, 4]
		},
		{
			x: [
				0,
				2,
				4,
				6
			],
			y: [2, 6]
		},
		{
			x: [
				1,
				3,
				5,
				7
			],
			y: [
				0,
				2,
				4,
				6
			]
		},
		{
			x: [
				0,
				1,
				2,
				3,
				4,
				5,
				6,
				7
			],
			y: [
				1,
				3,
				5,
				7
			]
		}
	];
	exports.getImagePasses = function(width, height) {
		let images = [];
		let xLeftOver = width % 8;
		let yLeftOver = height % 8;
		let xRepeats = (width - xLeftOver) / 8;
		let yRepeats = (height - yLeftOver) / 8;
		for (let i = 0; i < imagePasses.length; i++) {
			let pass = imagePasses[i];
			let passWidth = xRepeats * pass.x.length;
			let passHeight = yRepeats * pass.y.length;
			for (let j = 0; j < pass.x.length; j++) if (pass.x[j] < xLeftOver) passWidth++;
			else break;
			for (let j = 0; j < pass.y.length; j++) if (pass.y[j] < yLeftOver) passHeight++;
			else break;
			if (passWidth > 0 && passHeight > 0) images.push({
				width: passWidth,
				height: passHeight,
				index: i
			});
		}
		return images;
	};
	exports.getInterlaceIterator = function(width) {
		return function(x, y, pass) {
			let outerXLeftOver = x % imagePasses[pass].x.length;
			let outerX = (x - outerXLeftOver) / imagePasses[pass].x.length * 8 + imagePasses[pass].x[outerXLeftOver];
			let outerYLeftOver = y % imagePasses[pass].y.length;
			let outerY = (y - outerYLeftOver) / imagePasses[pass].y.length * 8 + imagePasses[pass].y[outerYLeftOver];
			return outerX * 4 + outerY * width * 4;
		};
	};
}));
//#endregion
//#region node_modules/pngjs/lib/paeth-predictor.js
var require_paeth_predictor = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = function paethPredictor(left, above, upLeft) {
		let paeth = left + above - upLeft;
		let pLeft = Math.abs(paeth - left);
		let pAbove = Math.abs(paeth - above);
		let pUpLeft = Math.abs(paeth - upLeft);
		if (pLeft <= pAbove && pLeft <= pUpLeft) return left;
		if (pAbove <= pUpLeft) return above;
		return upLeft;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/filter-parse.js
var require_filter_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var interlaceUtils = require_interlace();
	var paethPredictor = require_paeth_predictor();
	function getByteWidth(width, bpp, depth) {
		let byteWidth = width * bpp;
		if (depth !== 8) byteWidth = Math.ceil(byteWidth / (8 / depth));
		return byteWidth;
	}
	var Filter = module.exports = function(bitmapInfo, dependencies) {
		let width = bitmapInfo.width;
		let height = bitmapInfo.height;
		let interlace = bitmapInfo.interlace;
		let bpp = bitmapInfo.bpp;
		let depth = bitmapInfo.depth;
		this.read = dependencies.read;
		this.write = dependencies.write;
		this.complete = dependencies.complete;
		this._imageIndex = 0;
		this._images = [];
		if (interlace) {
			let passes = interlaceUtils.getImagePasses(width, height);
			for (let i = 0; i < passes.length; i++) this._images.push({
				byteWidth: getByteWidth(passes[i].width, bpp, depth),
				height: passes[i].height,
				lineIndex: 0
			});
		} else this._images.push({
			byteWidth: getByteWidth(width, bpp, depth),
			height,
			lineIndex: 0
		});
		if (depth === 8) this._xComparison = bpp;
		else if (depth === 16) this._xComparison = bpp * 2;
		else this._xComparison = 1;
	};
	Filter.prototype.start = function() {
		this.read(this._images[this._imageIndex].byteWidth + 1, this._reverseFilterLine.bind(this));
	};
	Filter.prototype._unFilterType1 = function(rawData, unfilteredLine, byteWidth) {
		let xComparison = this._xComparison;
		let xBiggerThan = xComparison - 1;
		for (let x = 0; x < byteWidth; x++) {
			let rawByte = rawData[1 + x];
			let f1Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
			unfilteredLine[x] = rawByte + f1Left;
		}
	};
	Filter.prototype._unFilterType2 = function(rawData, unfilteredLine, byteWidth) {
		let lastLine = this._lastLine;
		for (let x = 0; x < byteWidth; x++) {
			let rawByte = rawData[1 + x];
			let f2Up = lastLine ? lastLine[x] : 0;
			unfilteredLine[x] = rawByte + f2Up;
		}
	};
	Filter.prototype._unFilterType3 = function(rawData, unfilteredLine, byteWidth) {
		let xComparison = this._xComparison;
		let xBiggerThan = xComparison - 1;
		let lastLine = this._lastLine;
		for (let x = 0; x < byteWidth; x++) {
			let rawByte = rawData[1 + x];
			let f3Up = lastLine ? lastLine[x] : 0;
			let f3Left = x > xBiggerThan ? unfilteredLine[x - xComparison] : 0;
			let f3Add = Math.floor((f3Left + f3Up) / 2);
			unfilteredLine[x] = rawByte + f3Add;
		}
	};
	Filter.prototype._unFilterType4 = function(rawData, unfilteredLine, byteWidth) {
		let xComparison = this._xComparison;
		let xBiggerThan = xComparison - 1;
		let lastLine = this._lastLine;
		for (let x = 0; x < byteWidth; x++) {
			let rawByte = rawData[1 + x];
			let f4Up = lastLine ? lastLine[x] : 0;
			let f4Add = paethPredictor(x > xBiggerThan ? unfilteredLine[x - xComparison] : 0, f4Up, x > xBiggerThan && lastLine ? lastLine[x - xComparison] : 0);
			unfilteredLine[x] = rawByte + f4Add;
		}
	};
	Filter.prototype._reverseFilterLine = function(rawData) {
		let filter = rawData[0];
		let unfilteredLine;
		let currentImage = this._images[this._imageIndex];
		let byteWidth = currentImage.byteWidth;
		if (filter === 0) unfilteredLine = rawData.slice(1, byteWidth + 1);
		else {
			unfilteredLine = Buffer.alloc(byteWidth);
			switch (filter) {
				case 1:
					this._unFilterType1(rawData, unfilteredLine, byteWidth);
					break;
				case 2:
					this._unFilterType2(rawData, unfilteredLine, byteWidth);
					break;
				case 3:
					this._unFilterType3(rawData, unfilteredLine, byteWidth);
					break;
				case 4:
					this._unFilterType4(rawData, unfilteredLine, byteWidth);
					break;
				default: throw new Error("Unrecognised filter type - " + filter);
			}
		}
		this.write(unfilteredLine);
		currentImage.lineIndex++;
		if (currentImage.lineIndex >= currentImage.height) {
			this._lastLine = null;
			this._imageIndex++;
			currentImage = this._images[this._imageIndex];
		} else this._lastLine = unfilteredLine;
		if (currentImage) this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this));
		else {
			this._lastLine = null;
			this.complete();
		}
	};
}));
//#endregion
//#region node_modules/pngjs/lib/filter-parse-async.js
var require_filter_parse_async = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var util$4 = __require("util");
	var ChunkStream = require_chunkstream();
	var Filter = require_filter_parse();
	var FilterAsync = module.exports = function(bitmapInfo) {
		ChunkStream.call(this);
		let buffers = [];
		let that = this;
		this._filter = new Filter(bitmapInfo, {
			read: this.read.bind(this),
			write: function(buffer) {
				buffers.push(buffer);
			},
			complete: function() {
				that.emit("complete", Buffer.concat(buffers));
			}
		});
		this._filter.start();
	};
	util$4.inherits(FilterAsync, ChunkStream);
}));
//#endregion
//#region node_modules/pngjs/lib/constants.js
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = {
		PNG_SIGNATURE: [
			137,
			80,
			78,
			71,
			13,
			10,
			26,
			10
		],
		TYPE_IHDR: 1229472850,
		TYPE_IEND: 1229278788,
		TYPE_IDAT: 1229209940,
		TYPE_PLTE: 1347179589,
		TYPE_tRNS: 1951551059,
		TYPE_gAMA: 1732332865,
		COLORTYPE_GRAYSCALE: 0,
		COLORTYPE_PALETTE: 1,
		COLORTYPE_COLOR: 2,
		COLORTYPE_ALPHA: 4,
		COLORTYPE_PALETTE_COLOR: 3,
		COLORTYPE_COLOR_ALPHA: 6,
		COLORTYPE_TO_BPP_MAP: {
			0: 1,
			2: 3,
			3: 1,
			4: 2,
			6: 4
		},
		GAMMA_DIVISION: 1e5
	};
}));
//#endregion
//#region node_modules/pngjs/lib/crc.js
var require_crc = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var crcTable = [];
	(function() {
		for (let i = 0; i < 256; i++) {
			let currentCrc = i;
			for (let j = 0; j < 8; j++) if (currentCrc & 1) currentCrc = 3988292384 ^ currentCrc >>> 1;
			else currentCrc = currentCrc >>> 1;
			crcTable[i] = currentCrc;
		}
	})();
	var CrcCalculator = module.exports = function() {
		this._crc = -1;
	};
	CrcCalculator.prototype.write = function(data) {
		for (let i = 0; i < data.length; i++) this._crc = crcTable[(this._crc ^ data[i]) & 255] ^ this._crc >>> 8;
		return true;
	};
	CrcCalculator.prototype.crc32 = function() {
		return this._crc ^ -1;
	};
	CrcCalculator.crc32 = function(buf) {
		let crc = -1;
		for (let i = 0; i < buf.length; i++) crc = crcTable[(crc ^ buf[i]) & 255] ^ crc >>> 8;
		return crc ^ -1;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/parser.js
var require_parser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var constants = require_constants();
	var CrcCalculator = require_crc();
	var Parser = module.exports = function(options, dependencies) {
		this._options = options;
		options.checkCRC = options.checkCRC !== false;
		this._hasIHDR = false;
		this._hasIEND = false;
		this._emittedHeadersFinished = false;
		this._palette = [];
		this._colorType = 0;
		this._chunks = {};
		this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this);
		this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this);
		this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this);
		this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this);
		this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this);
		this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this);
		this.read = dependencies.read;
		this.error = dependencies.error;
		this.metadata = dependencies.metadata;
		this.gamma = dependencies.gamma;
		this.transColor = dependencies.transColor;
		this.palette = dependencies.palette;
		this.parsed = dependencies.parsed;
		this.inflateData = dependencies.inflateData;
		this.finished = dependencies.finished;
		this.simpleTransparency = dependencies.simpleTransparency;
		this.headersFinished = dependencies.headersFinished || function() {};
	};
	Parser.prototype.start = function() {
		this.read(constants.PNG_SIGNATURE.length, this._parseSignature.bind(this));
	};
	Parser.prototype._parseSignature = function(data) {
		let signature = constants.PNG_SIGNATURE;
		for (let i = 0; i < signature.length; i++) if (data[i] !== signature[i]) {
			this.error(/* @__PURE__ */ new Error("Invalid file signature"));
			return;
		}
		this.read(8, this._parseChunkBegin.bind(this));
	};
	Parser.prototype._parseChunkBegin = function(data) {
		let length = data.readUInt32BE(0);
		let type = data.readUInt32BE(4);
		let name = "";
		for (let i = 4; i < 8; i++) name += String.fromCharCode(data[i]);
		let ancillary = Boolean(data[4] & 32);
		if (!this._hasIHDR && type !== constants.TYPE_IHDR) {
			this.error(/* @__PURE__ */ new Error("Expected IHDR on beggining"));
			return;
		}
		this._crc = new CrcCalculator();
		this._crc.write(Buffer.from(name));
		if (this._chunks[type]) return this._chunks[type](length);
		if (!ancillary) {
			this.error(/* @__PURE__ */ new Error("Unsupported critical chunk type " + name));
			return;
		}
		this.read(length + 4, this._skipChunk.bind(this));
	};
	Parser.prototype._skipChunk = function() {
		this.read(8, this._parseChunkBegin.bind(this));
	};
	Parser.prototype._handleChunkEnd = function() {
		this.read(4, this._parseChunkEnd.bind(this));
	};
	Parser.prototype._parseChunkEnd = function(data) {
		let fileCrc = data.readInt32BE(0);
		let calcCrc = this._crc.crc32();
		if (this._options.checkCRC && calcCrc !== fileCrc) {
			this.error(/* @__PURE__ */ new Error("Crc error - " + fileCrc + " - " + calcCrc));
			return;
		}
		if (!this._hasIEND) this.read(8, this._parseChunkBegin.bind(this));
	};
	Parser.prototype._handleIHDR = function(length) {
		this.read(length, this._parseIHDR.bind(this));
	};
	Parser.prototype._parseIHDR = function(data) {
		this._crc.write(data);
		let width = data.readUInt32BE(0);
		let height = data.readUInt32BE(4);
		let depth = data[8];
		let colorType = data[9];
		let compr = data[10];
		let filter = data[11];
		let interlace = data[12];
		if (depth !== 8 && depth !== 4 && depth !== 2 && depth !== 1 && depth !== 16) {
			this.error(/* @__PURE__ */ new Error("Unsupported bit depth " + depth));
			return;
		}
		if (!(colorType in constants.COLORTYPE_TO_BPP_MAP)) {
			this.error(/* @__PURE__ */ new Error("Unsupported color type"));
			return;
		}
		if (compr !== 0) {
			this.error(/* @__PURE__ */ new Error("Unsupported compression method"));
			return;
		}
		if (filter !== 0) {
			this.error(/* @__PURE__ */ new Error("Unsupported filter method"));
			return;
		}
		if (interlace !== 0 && interlace !== 1) {
			this.error(/* @__PURE__ */ new Error("Unsupported interlace method"));
			return;
		}
		this._colorType = colorType;
		let bpp = constants.COLORTYPE_TO_BPP_MAP[this._colorType];
		this._hasIHDR = true;
		this.metadata({
			width,
			height,
			depth,
			interlace: Boolean(interlace),
			palette: Boolean(colorType & constants.COLORTYPE_PALETTE),
			color: Boolean(colorType & constants.COLORTYPE_COLOR),
			alpha: Boolean(colorType & constants.COLORTYPE_ALPHA),
			bpp,
			colorType
		});
		this._handleChunkEnd();
	};
	Parser.prototype._handlePLTE = function(length) {
		this.read(length, this._parsePLTE.bind(this));
	};
	Parser.prototype._parsePLTE = function(data) {
		this._crc.write(data);
		let entries = Math.floor(data.length / 3);
		for (let i = 0; i < entries; i++) this._palette.push([
			data[i * 3],
			data[i * 3 + 1],
			data[i * 3 + 2],
			255
		]);
		this.palette(this._palette);
		this._handleChunkEnd();
	};
	Parser.prototype._handleTRNS = function(length) {
		this.simpleTransparency();
		this.read(length, this._parseTRNS.bind(this));
	};
	Parser.prototype._parseTRNS = function(data) {
		this._crc.write(data);
		if (this._colorType === constants.COLORTYPE_PALETTE_COLOR) {
			if (this._palette.length === 0) {
				this.error(/* @__PURE__ */ new Error("Transparency chunk must be after palette"));
				return;
			}
			if (data.length > this._palette.length) {
				this.error(/* @__PURE__ */ new Error("More transparent colors than palette size"));
				return;
			}
			for (let i = 0; i < data.length; i++) this._palette[i][3] = data[i];
			this.palette(this._palette);
		}
		if (this._colorType === constants.COLORTYPE_GRAYSCALE) this.transColor([data.readUInt16BE(0)]);
		if (this._colorType === constants.COLORTYPE_COLOR) this.transColor([
			data.readUInt16BE(0),
			data.readUInt16BE(2),
			data.readUInt16BE(4)
		]);
		this._handleChunkEnd();
	};
	Parser.prototype._handleGAMA = function(length) {
		this.read(length, this._parseGAMA.bind(this));
	};
	Parser.prototype._parseGAMA = function(data) {
		this._crc.write(data);
		this.gamma(data.readUInt32BE(0) / constants.GAMMA_DIVISION);
		this._handleChunkEnd();
	};
	Parser.prototype._handleIDAT = function(length) {
		if (!this._emittedHeadersFinished) {
			this._emittedHeadersFinished = true;
			this.headersFinished();
		}
		this.read(-length, this._parseIDAT.bind(this, length));
	};
	Parser.prototype._parseIDAT = function(length, data) {
		this._crc.write(data);
		if (this._colorType === constants.COLORTYPE_PALETTE_COLOR && this._palette.length === 0) throw new Error("Expected palette not found");
		this.inflateData(data);
		let leftOverLength = length - data.length;
		if (leftOverLength > 0) this._handleIDAT(leftOverLength);
		else this._handleChunkEnd();
	};
	Parser.prototype._handleIEND = function(length) {
		this.read(length, this._parseIEND.bind(this));
	};
	Parser.prototype._parseIEND = function(data) {
		this._crc.write(data);
		this._hasIEND = true;
		this._handleChunkEnd();
		if (this.finished) this.finished();
	};
}));
//#endregion
//#region node_modules/pngjs/lib/bitmapper.js
var require_bitmapper = /* @__PURE__ */ __commonJSMin(((exports) => {
	var interlaceUtils = require_interlace();
	var pixelBppMapper = [
		function() {},
		function(pxData, data, pxPos, rawPos) {
			if (rawPos === data.length) throw new Error("Ran out of data");
			let pixel = data[rawPos];
			pxData[pxPos] = pixel;
			pxData[pxPos + 1] = pixel;
			pxData[pxPos + 2] = pixel;
			pxData[pxPos + 3] = 255;
		},
		function(pxData, data, pxPos, rawPos) {
			if (rawPos + 1 >= data.length) throw new Error("Ran out of data");
			let pixel = data[rawPos];
			pxData[pxPos] = pixel;
			pxData[pxPos + 1] = pixel;
			pxData[pxPos + 2] = pixel;
			pxData[pxPos + 3] = data[rawPos + 1];
		},
		function(pxData, data, pxPos, rawPos) {
			if (rawPos + 2 >= data.length) throw new Error("Ran out of data");
			pxData[pxPos] = data[rawPos];
			pxData[pxPos + 1] = data[rawPos + 1];
			pxData[pxPos + 2] = data[rawPos + 2];
			pxData[pxPos + 3] = 255;
		},
		function(pxData, data, pxPos, rawPos) {
			if (rawPos + 3 >= data.length) throw new Error("Ran out of data");
			pxData[pxPos] = data[rawPos];
			pxData[pxPos + 1] = data[rawPos + 1];
			pxData[pxPos + 2] = data[rawPos + 2];
			pxData[pxPos + 3] = data[rawPos + 3];
		}
	];
	var pixelBppCustomMapper = [
		function() {},
		function(pxData, pixelData, pxPos, maxBit) {
			let pixel = pixelData[0];
			pxData[pxPos] = pixel;
			pxData[pxPos + 1] = pixel;
			pxData[pxPos + 2] = pixel;
			pxData[pxPos + 3] = maxBit;
		},
		function(pxData, pixelData, pxPos) {
			let pixel = pixelData[0];
			pxData[pxPos] = pixel;
			pxData[pxPos + 1] = pixel;
			pxData[pxPos + 2] = pixel;
			pxData[pxPos + 3] = pixelData[1];
		},
		function(pxData, pixelData, pxPos, maxBit) {
			pxData[pxPos] = pixelData[0];
			pxData[pxPos + 1] = pixelData[1];
			pxData[pxPos + 2] = pixelData[2];
			pxData[pxPos + 3] = maxBit;
		},
		function(pxData, pixelData, pxPos) {
			pxData[pxPos] = pixelData[0];
			pxData[pxPos + 1] = pixelData[1];
			pxData[pxPos + 2] = pixelData[2];
			pxData[pxPos + 3] = pixelData[3];
		}
	];
	function bitRetriever(data, depth) {
		let leftOver = [];
		let i = 0;
		function split() {
			if (i === data.length) throw new Error("Ran out of data");
			let byte = data[i];
			i++;
			let byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1;
			switch (depth) {
				default: throw new Error("unrecognised depth");
				case 16:
					byte2 = data[i];
					i++;
					leftOver.push((byte << 8) + byte2);
					break;
				case 4:
					byte2 = byte & 15;
					byte1 = byte >> 4;
					leftOver.push(byte1, byte2);
					break;
				case 2:
					byte4 = byte & 3;
					byte3 = byte >> 2 & 3;
					byte2 = byte >> 4 & 3;
					byte1 = byte >> 6 & 3;
					leftOver.push(byte1, byte2, byte3, byte4);
					break;
				case 1:
					byte8 = byte & 1;
					byte7 = byte >> 1 & 1;
					byte6 = byte >> 2 & 1;
					byte5 = byte >> 3 & 1;
					byte4 = byte >> 4 & 1;
					byte3 = byte >> 5 & 1;
					byte2 = byte >> 6 & 1;
					byte1 = byte >> 7 & 1;
					leftOver.push(byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8);
			}
		}
		return {
			get: function(count) {
				while (leftOver.length < count) split();
				let returner = leftOver.slice(0, count);
				leftOver = leftOver.slice(count);
				return returner;
			},
			resetAfterLine: function() {
				leftOver.length = 0;
			},
			end: function() {
				if (i !== data.length) throw new Error("extra data found");
			}
		};
	}
	function mapImage8Bit(image, pxData, getPxPos, bpp, data, rawPos) {
		let imageWidth = image.width;
		let imageHeight = image.height;
		let imagePass = image.index;
		for (let y = 0; y < imageHeight; y++) for (let x = 0; x < imageWidth; x++) {
			let pxPos = getPxPos(x, y, imagePass);
			pixelBppMapper[bpp](pxData, data, pxPos, rawPos);
			rawPos += bpp;
		}
		return rawPos;
	}
	function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) {
		let imageWidth = image.width;
		let imageHeight = image.height;
		let imagePass = image.index;
		for (let y = 0; y < imageHeight; y++) {
			for (let x = 0; x < imageWidth; x++) {
				let pixelData = bits.get(bpp);
				let pxPos = getPxPos(x, y, imagePass);
				pixelBppCustomMapper[bpp](pxData, pixelData, pxPos, maxBit);
			}
			bits.resetAfterLine();
		}
	}
	exports.dataToBitMap = function(data, bitmapInfo) {
		let width = bitmapInfo.width;
		let height = bitmapInfo.height;
		let depth = bitmapInfo.depth;
		let bpp = bitmapInfo.bpp;
		let interlace = bitmapInfo.interlace;
		let bits;
		if (depth !== 8) bits = bitRetriever(data, depth);
		let pxData;
		if (depth <= 8) pxData = Buffer.alloc(width * height * 4);
		else pxData = new Uint16Array(width * height * 4);
		let maxBit = Math.pow(2, depth) - 1;
		let rawPos = 0;
		let images;
		let getPxPos;
		if (interlace) {
			images = interlaceUtils.getImagePasses(width, height);
			getPxPos = interlaceUtils.getInterlaceIterator(width, height);
		} else {
			let nonInterlacedPxPos = 0;
			getPxPos = function() {
				let returner = nonInterlacedPxPos;
				nonInterlacedPxPos += 4;
				return returner;
			};
			images = [{
				width,
				height
			}];
		}
		for (let imageIndex = 0; imageIndex < images.length; imageIndex++) if (depth === 8) rawPos = mapImage8Bit(images[imageIndex], pxData, getPxPos, bpp, data, rawPos);
		else mapImageCustomBit(images[imageIndex], pxData, getPxPos, bpp, bits, maxBit);
		if (depth === 8) {
			if (rawPos !== data.length) throw new Error("extra data found");
		} else bits.end();
		return pxData;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/format-normaliser.js
var require_format_normaliser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	function dePalette(indata, outdata, width, height, palette) {
		let pxPos = 0;
		for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
			let color = palette[indata[pxPos]];
			if (!color) throw new Error("index " + indata[pxPos] + " not in palette");
			for (let i = 0; i < 4; i++) outdata[pxPos + i] = color[i];
			pxPos += 4;
		}
	}
	function replaceTransparentColor(indata, outdata, width, height, transColor) {
		let pxPos = 0;
		for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
			let makeTrans = false;
			if (transColor.length === 1) {
				if (transColor[0] === indata[pxPos]) makeTrans = true;
			} else if (transColor[0] === indata[pxPos] && transColor[1] === indata[pxPos + 1] && transColor[2] === indata[pxPos + 2]) makeTrans = true;
			if (makeTrans) for (let i = 0; i < 4; i++) outdata[pxPos + i] = 0;
			pxPos += 4;
		}
	}
	function scaleDepth(indata, outdata, width, height, depth) {
		let maxOutSample = 255;
		let maxInSample = Math.pow(2, depth) - 1;
		let pxPos = 0;
		for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
			for (let i = 0; i < 4; i++) outdata[pxPos + i] = Math.floor(indata[pxPos + i] * maxOutSample / maxInSample + .5);
			pxPos += 4;
		}
	}
	module.exports = function(indata, imageData) {
		let depth = imageData.depth;
		let width = imageData.width;
		let height = imageData.height;
		let colorType = imageData.colorType;
		let transColor = imageData.transColor;
		let palette = imageData.palette;
		let outdata = indata;
		if (colorType === 3) dePalette(indata, outdata, width, height, palette);
		else {
			if (transColor) replaceTransparentColor(indata, outdata, width, height, transColor);
			if (depth !== 8) {
				if (depth === 16) outdata = Buffer.alloc(width * height * 4);
				scaleDepth(indata, outdata, width, height, depth);
			}
		}
		return outdata;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/parser-async.js
var require_parser_async = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var util$3 = __require("util");
	var zlib$4 = __require("zlib");
	var ChunkStream = require_chunkstream();
	var FilterAsync = require_filter_parse_async();
	var Parser = require_parser();
	var bitmapper = require_bitmapper();
	var formatNormaliser = require_format_normaliser();
	var ParserAsync = module.exports = function(options) {
		ChunkStream.call(this);
		this._parser = new Parser(options, {
			read: this.read.bind(this),
			error: this._handleError.bind(this),
			metadata: this._handleMetaData.bind(this),
			gamma: this.emit.bind(this, "gamma"),
			palette: this._handlePalette.bind(this),
			transColor: this._handleTransColor.bind(this),
			finished: this._finished.bind(this),
			inflateData: this._inflateData.bind(this),
			simpleTransparency: this._simpleTransparency.bind(this),
			headersFinished: this._headersFinished.bind(this)
		});
		this._options = options;
		this.writable = true;
		this._parser.start();
	};
	util$3.inherits(ParserAsync, ChunkStream);
	ParserAsync.prototype._handleError = function(err) {
		this.emit("error", err);
		this.writable = false;
		this.destroy();
		if (this._inflate && this._inflate.destroy) this._inflate.destroy();
		if (this._filter) {
			this._filter.destroy();
			this._filter.on("error", function() {});
		}
		this.errord = true;
	};
	ParserAsync.prototype._inflateData = function(data) {
		if (!this._inflate) if (this._bitmapInfo.interlace) {
			this._inflate = zlib$4.createInflate();
			this._inflate.on("error", this.emit.bind(this, "error"));
			this._filter.on("complete", this._complete.bind(this));
			this._inflate.pipe(this._filter);
		} else {
			let imageSize = ((this._bitmapInfo.width * this._bitmapInfo.bpp * this._bitmapInfo.depth + 7 >> 3) + 1) * this._bitmapInfo.height;
			let chunkSize = Math.max(imageSize, zlib$4.Z_MIN_CHUNK);
			this._inflate = zlib$4.createInflate({ chunkSize });
			let leftToInflate = imageSize;
			let emitError = this.emit.bind(this, "error");
			this._inflate.on("error", function(err) {
				if (!leftToInflate) return;
				emitError(err);
			});
			this._filter.on("complete", this._complete.bind(this));
			let filterWrite = this._filter.write.bind(this._filter);
			this._inflate.on("data", function(chunk) {
				if (!leftToInflate) return;
				if (chunk.length > leftToInflate) chunk = chunk.slice(0, leftToInflate);
				leftToInflate -= chunk.length;
				filterWrite(chunk);
			});
			this._inflate.on("end", this._filter.end.bind(this._filter));
		}
		this._inflate.write(data);
	};
	ParserAsync.prototype._handleMetaData = function(metaData) {
		this._metaData = metaData;
		this._bitmapInfo = Object.create(metaData);
		this._filter = new FilterAsync(this._bitmapInfo);
	};
	ParserAsync.prototype._handleTransColor = function(transColor) {
		this._bitmapInfo.transColor = transColor;
	};
	ParserAsync.prototype._handlePalette = function(palette) {
		this._bitmapInfo.palette = palette;
	};
	ParserAsync.prototype._simpleTransparency = function() {
		this._metaData.alpha = true;
	};
	ParserAsync.prototype._headersFinished = function() {
		this.emit("metadata", this._metaData);
	};
	ParserAsync.prototype._finished = function() {
		if (this.errord) return;
		if (!this._inflate) this.emit("error", "No Inflate block");
		else this._inflate.end();
	};
	ParserAsync.prototype._complete = function(filteredData) {
		if (this.errord) return;
		let normalisedBitmapData;
		try {
			let bitmapData = bitmapper.dataToBitMap(filteredData, this._bitmapInfo);
			normalisedBitmapData = formatNormaliser(bitmapData, this._bitmapInfo);
			bitmapData = null;
		} catch (ex) {
			this._handleError(ex);
			return;
		}
		this.emit("parsed", normalisedBitmapData);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/bitpacker.js
var require_bitpacker = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var constants = require_constants();
	module.exports = function(dataIn, width, height, options) {
		let outHasAlpha = [constants.COLORTYPE_COLOR_ALPHA, constants.COLORTYPE_ALPHA].indexOf(options.colorType) !== -1;
		if (options.colorType === options.inputColorType) {
			let bigEndian = (function() {
				let buffer = /* @__PURE__ */ new ArrayBuffer(2);
				new DataView(buffer).setInt16(0, 256, true);
				return new Int16Array(buffer)[0] !== 256;
			})();
			if (options.bitDepth === 8 || options.bitDepth === 16 && bigEndian) return dataIn;
		}
		let data = options.bitDepth !== 16 ? dataIn : new Uint16Array(dataIn.buffer);
		let maxValue = 255;
		let inBpp = constants.COLORTYPE_TO_BPP_MAP[options.inputColorType];
		if (inBpp === 4 && !options.inputHasAlpha) inBpp = 3;
		let outBpp = constants.COLORTYPE_TO_BPP_MAP[options.colorType];
		if (options.bitDepth === 16) {
			maxValue = 65535;
			outBpp *= 2;
		}
		let outData = Buffer.alloc(width * height * outBpp);
		let inIndex = 0;
		let outIndex = 0;
		let bgColor = options.bgColor || {};
		if (bgColor.red === void 0) bgColor.red = maxValue;
		if (bgColor.green === void 0) bgColor.green = maxValue;
		if (bgColor.blue === void 0) bgColor.blue = maxValue;
		function getRGBA() {
			let red;
			let green;
			let blue;
			let alpha = maxValue;
			switch (options.inputColorType) {
				case constants.COLORTYPE_COLOR_ALPHA:
					alpha = data[inIndex + 3];
					red = data[inIndex];
					green = data[inIndex + 1];
					blue = data[inIndex + 2];
					break;
				case constants.COLORTYPE_COLOR:
					red = data[inIndex];
					green = data[inIndex + 1];
					blue = data[inIndex + 2];
					break;
				case constants.COLORTYPE_ALPHA:
					alpha = data[inIndex + 1];
					red = data[inIndex];
					green = red;
					blue = red;
					break;
				case constants.COLORTYPE_GRAYSCALE:
					red = data[inIndex];
					green = red;
					blue = red;
					break;
				default: throw new Error("input color type:" + options.inputColorType + " is not supported at present");
			}
			if (options.inputHasAlpha) {
				if (!outHasAlpha) {
					alpha /= maxValue;
					red = Math.min(Math.max(Math.round((1 - alpha) * bgColor.red + alpha * red), 0), maxValue);
					green = Math.min(Math.max(Math.round((1 - alpha) * bgColor.green + alpha * green), 0), maxValue);
					blue = Math.min(Math.max(Math.round((1 - alpha) * bgColor.blue + alpha * blue), 0), maxValue);
				}
			}
			return {
				red,
				green,
				blue,
				alpha
			};
		}
		for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
			let rgba = getRGBA(data, inIndex);
			switch (options.colorType) {
				case constants.COLORTYPE_COLOR_ALPHA:
				case constants.COLORTYPE_COLOR:
					if (options.bitDepth === 8) {
						outData[outIndex] = rgba.red;
						outData[outIndex + 1] = rgba.green;
						outData[outIndex + 2] = rgba.blue;
						if (outHasAlpha) outData[outIndex + 3] = rgba.alpha;
					} else {
						outData.writeUInt16BE(rgba.red, outIndex);
						outData.writeUInt16BE(rgba.green, outIndex + 2);
						outData.writeUInt16BE(rgba.blue, outIndex + 4);
						if (outHasAlpha) outData.writeUInt16BE(rgba.alpha, outIndex + 6);
					}
					break;
				case constants.COLORTYPE_ALPHA:
				case constants.COLORTYPE_GRAYSCALE: {
					let grayscale = (rgba.red + rgba.green + rgba.blue) / 3;
					if (options.bitDepth === 8) {
						outData[outIndex] = grayscale;
						if (outHasAlpha) outData[outIndex + 1] = rgba.alpha;
					} else {
						outData.writeUInt16BE(grayscale, outIndex);
						if (outHasAlpha) outData.writeUInt16BE(rgba.alpha, outIndex + 2);
					}
					break;
				}
				default: throw new Error("unrecognised color Type " + options.colorType);
			}
			inIndex += inBpp;
			outIndex += outBpp;
		}
		return outData;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/filter-pack.js
var require_filter_pack = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var paethPredictor = require_paeth_predictor();
	function filterNone(pxData, pxPos, byteWidth, rawData, rawPos) {
		for (let x = 0; x < byteWidth; x++) rawData[rawPos + x] = pxData[pxPos + x];
	}
	function filterSumNone(pxData, pxPos, byteWidth) {
		let sum = 0;
		let length = pxPos + byteWidth;
		for (let i = pxPos; i < length; i++) sum += Math.abs(pxData[i]);
		return sum;
	}
	function filterSub(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let val = pxData[pxPos + x] - left;
			rawData[rawPos + x] = val;
		}
	}
	function filterSumSub(pxData, pxPos, byteWidth, bpp) {
		let sum = 0;
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let val = pxData[pxPos + x] - left;
			sum += Math.abs(val);
		}
		return sum;
	}
	function filterUp(pxData, pxPos, byteWidth, rawData, rawPos) {
		for (let x = 0; x < byteWidth; x++) {
			let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
			let val = pxData[pxPos + x] - up;
			rawData[rawPos + x] = val;
		}
	}
	function filterSumUp(pxData, pxPos, byteWidth) {
		let sum = 0;
		let length = pxPos + byteWidth;
		for (let x = pxPos; x < length; x++) {
			let up = pxPos > 0 ? pxData[x - byteWidth] : 0;
			let val = pxData[x] - up;
			sum += Math.abs(val);
		}
		return sum;
	}
	function filterAvg(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
			let val = pxData[pxPos + x] - (left + up >> 1);
			rawData[rawPos + x] = val;
		}
	}
	function filterSumAvg(pxData, pxPos, byteWidth, bpp) {
		let sum = 0;
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
			let val = pxData[pxPos + x] - (left + up >> 1);
			sum += Math.abs(val);
		}
		return sum;
	}
	function filterPaeth(pxData, pxPos, byteWidth, rawData, rawPos, bpp) {
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
			let upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
			let val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
			rawData[rawPos + x] = val;
		}
	}
	function filterSumPaeth(pxData, pxPos, byteWidth, bpp) {
		let sum = 0;
		for (let x = 0; x < byteWidth; x++) {
			let left = x >= bpp ? pxData[pxPos + x - bpp] : 0;
			let up = pxPos > 0 ? pxData[pxPos + x - byteWidth] : 0;
			let upleft = pxPos > 0 && x >= bpp ? pxData[pxPos + x - (byteWidth + bpp)] : 0;
			let val = pxData[pxPos + x] - paethPredictor(left, up, upleft);
			sum += Math.abs(val);
		}
		return sum;
	}
	var filters = {
		0: filterNone,
		1: filterSub,
		2: filterUp,
		3: filterAvg,
		4: filterPaeth
	};
	var filterSums = {
		0: filterSumNone,
		1: filterSumSub,
		2: filterSumUp,
		3: filterSumAvg,
		4: filterSumPaeth
	};
	module.exports = function(pxData, width, height, options, bpp) {
		let filterTypes;
		if (!("filterType" in options) || options.filterType === -1) filterTypes = [
			0,
			1,
			2,
			3,
			4
		];
		else if (typeof options.filterType === "number") filterTypes = [options.filterType];
		else throw new Error("unrecognised filter types");
		if (options.bitDepth === 16) bpp *= 2;
		let byteWidth = width * bpp;
		let rawPos = 0;
		let pxPos = 0;
		let rawData = Buffer.alloc((byteWidth + 1) * height);
		let sel = filterTypes[0];
		for (let y = 0; y < height; y++) {
			if (filterTypes.length > 1) {
				let min = Infinity;
				for (let i = 0; i < filterTypes.length; i++) {
					let sum = filterSums[filterTypes[i]](pxData, pxPos, byteWidth, bpp);
					if (sum < min) {
						sel = filterTypes[i];
						min = sum;
					}
				}
			}
			rawData[rawPos] = sel;
			rawPos++;
			filters[sel](pxData, pxPos, byteWidth, rawData, rawPos, bpp);
			rawPos += byteWidth;
			pxPos += byteWidth;
		}
		return rawData;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/packer.js
var require_packer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var constants = require_constants();
	var CrcStream = require_crc();
	var bitPacker = require_bitpacker();
	var filter = require_filter_pack();
	var zlib$3 = __require("zlib");
	var Packer = module.exports = function(options) {
		this._options = options;
		options.deflateChunkSize = options.deflateChunkSize || 32768;
		options.deflateLevel = options.deflateLevel != null ? options.deflateLevel : 9;
		options.deflateStrategy = options.deflateStrategy != null ? options.deflateStrategy : 3;
		options.inputHasAlpha = options.inputHasAlpha != null ? options.inputHasAlpha : true;
		options.deflateFactory = options.deflateFactory || zlib$3.createDeflate;
		options.bitDepth = options.bitDepth || 8;
		options.colorType = typeof options.colorType === "number" ? options.colorType : constants.COLORTYPE_COLOR_ALPHA;
		options.inputColorType = typeof options.inputColorType === "number" ? options.inputColorType : constants.COLORTYPE_COLOR_ALPHA;
		if ([
			constants.COLORTYPE_GRAYSCALE,
			constants.COLORTYPE_COLOR,
			constants.COLORTYPE_COLOR_ALPHA,
			constants.COLORTYPE_ALPHA
		].indexOf(options.colorType) === -1) throw new Error("option color type:" + options.colorType + " is not supported at present");
		if ([
			constants.COLORTYPE_GRAYSCALE,
			constants.COLORTYPE_COLOR,
			constants.COLORTYPE_COLOR_ALPHA,
			constants.COLORTYPE_ALPHA
		].indexOf(options.inputColorType) === -1) throw new Error("option input color type:" + options.inputColorType + " is not supported at present");
		if (options.bitDepth !== 8 && options.bitDepth !== 16) throw new Error("option bit depth:" + options.bitDepth + " is not supported at present");
	};
	Packer.prototype.getDeflateOptions = function() {
		return {
			chunkSize: this._options.deflateChunkSize,
			level: this._options.deflateLevel,
			strategy: this._options.deflateStrategy
		};
	};
	Packer.prototype.createDeflate = function() {
		return this._options.deflateFactory(this.getDeflateOptions());
	};
	Packer.prototype.filterData = function(data, width, height) {
		let packedData = bitPacker(data, width, height, this._options);
		let bpp = constants.COLORTYPE_TO_BPP_MAP[this._options.colorType];
		return filter(packedData, width, height, this._options, bpp);
	};
	Packer.prototype._packChunk = function(type, data) {
		let len = data ? data.length : 0;
		let buf = Buffer.alloc(len + 12);
		buf.writeUInt32BE(len, 0);
		buf.writeUInt32BE(type, 4);
		if (data) data.copy(buf, 8);
		buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4);
		return buf;
	};
	Packer.prototype.packGAMA = function(gamma) {
		let buf = Buffer.alloc(4);
		buf.writeUInt32BE(Math.floor(gamma * constants.GAMMA_DIVISION), 0);
		return this._packChunk(constants.TYPE_gAMA, buf);
	};
	Packer.prototype.packIHDR = function(width, height) {
		let buf = Buffer.alloc(13);
		buf.writeUInt32BE(width, 0);
		buf.writeUInt32BE(height, 4);
		buf[8] = this._options.bitDepth;
		buf[9] = this._options.colorType;
		buf[10] = 0;
		buf[11] = 0;
		buf[12] = 0;
		return this._packChunk(constants.TYPE_IHDR, buf);
	};
	Packer.prototype.packIDAT = function(data) {
		return this._packChunk(constants.TYPE_IDAT, data);
	};
	Packer.prototype.packIEND = function() {
		return this._packChunk(constants.TYPE_IEND, null);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/packer-async.js
var require_packer_async = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var util$2 = __require("util");
	var Stream$1 = __require("stream");
	var constants = require_constants();
	var Packer = require_packer();
	var PackerAsync = module.exports = function(opt) {
		Stream$1.call(this);
		let options = opt || {};
		this._packer = new Packer(options);
		this._deflate = this._packer.createDeflate();
		this.readable = true;
	};
	util$2.inherits(PackerAsync, Stream$1);
	PackerAsync.prototype.pack = function(data, width, height, gamma) {
		this.emit("data", Buffer.from(constants.PNG_SIGNATURE));
		this.emit("data", this._packer.packIHDR(width, height));
		if (gamma) this.emit("data", this._packer.packGAMA(gamma));
		let filteredData = this._packer.filterData(data, width, height);
		this._deflate.on("error", this.emit.bind(this, "error"));
		this._deflate.on("data", function(compressedData) {
			this.emit("data", this._packer.packIDAT(compressedData));
		}.bind(this));
		this._deflate.on("end", function() {
			this.emit("data", this._packer.packIEND());
			this.emit("end");
		}.bind(this));
		this._deflate.end(filteredData);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/sync-inflate.js
var require_sync_inflate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var assert = __require("assert").ok;
	var zlib$2 = __require("zlib");
	var util$1 = __require("util");
	var kMaxLength = __require("buffer").kMaxLength;
	function Inflate(opts) {
		if (!(this instanceof Inflate)) return new Inflate(opts);
		if (opts && opts.chunkSize < zlib$2.Z_MIN_CHUNK) opts.chunkSize = zlib$2.Z_MIN_CHUNK;
		zlib$2.Inflate.call(this, opts);
		this._offset = this._offset === void 0 ? this._outOffset : this._offset;
		this._buffer = this._buffer || this._outBuffer;
		if (opts && opts.maxLength != null) this._maxLength = opts.maxLength;
	}
	function createInflate(opts) {
		return new Inflate(opts);
	}
	function _close(engine, callback) {
		if (callback) process.nextTick(callback);
		if (!engine._handle) return;
		engine._handle.close();
		engine._handle = null;
	}
	Inflate.prototype._processChunk = function(chunk, flushFlag, asyncCb) {
		if (typeof asyncCb === "function") return zlib$2.Inflate._processChunk.call(this, chunk, flushFlag, asyncCb);
		let self = this;
		let availInBefore = chunk && chunk.length;
		let availOutBefore = this._chunkSize - this._offset;
		let leftToInflate = this._maxLength;
		let inOff = 0;
		let buffers = [];
		let nread = 0;
		let error;
		this.on("error", function(err) {
			error = err;
		});
		function handleChunk(availInAfter, availOutAfter) {
			if (self._hadError) return;
			let have = availOutBefore - availOutAfter;
			assert(have >= 0, "have should not go down");
			if (have > 0) {
				let out = self._buffer.slice(self._offset, self._offset + have);
				self._offset += have;
				if (out.length > leftToInflate) out = out.slice(0, leftToInflate);
				buffers.push(out);
				nread += out.length;
				leftToInflate -= out.length;
				if (leftToInflate === 0) return false;
			}
			if (availOutAfter === 0 || self._offset >= self._chunkSize) {
				availOutBefore = self._chunkSize;
				self._offset = 0;
				self._buffer = Buffer.allocUnsafe(self._chunkSize);
			}
			if (availOutAfter === 0) {
				inOff += availInBefore - availInAfter;
				availInBefore = availInAfter;
				return true;
			}
			return false;
		}
		assert(this._handle, "zlib binding closed");
		let res;
		do {
			res = this._handle.writeSync(flushFlag, chunk, inOff, availInBefore, this._buffer, this._offset, availOutBefore);
			res = res || this._writeState;
		} while (!this._hadError && handleChunk(res[0], res[1]));
		if (this._hadError) throw error;
		if (nread >= kMaxLength) {
			_close(this);
			throw new RangeError("Cannot create final Buffer. It would be larger than 0x" + kMaxLength.toString(16) + " bytes");
		}
		let buf = Buffer.concat(buffers, nread);
		_close(this);
		return buf;
	};
	util$1.inherits(Inflate, zlib$2.Inflate);
	function zlibBufferSync(engine, buffer) {
		if (typeof buffer === "string") buffer = Buffer.from(buffer);
		if (!(buffer instanceof Buffer)) throw new TypeError("Not a string or buffer");
		let flushFlag = engine._finishFlushFlag;
		if (flushFlag == null) flushFlag = zlib$2.Z_FINISH;
		return engine._processChunk(buffer, flushFlag);
	}
	function inflateSync(buffer, opts) {
		return zlibBufferSync(new Inflate(opts), buffer);
	}
	module.exports = exports = inflateSync;
	exports.Inflate = Inflate;
	exports.createInflate = createInflate;
	exports.inflateSync = inflateSync;
}));
//#endregion
//#region node_modules/pngjs/lib/sync-reader.js
var require_sync_reader = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var SyncReader = module.exports = function(buffer) {
		this._buffer = buffer;
		this._reads = [];
	};
	SyncReader.prototype.read = function(length, callback) {
		this._reads.push({
			length: Math.abs(length),
			allowLess: length < 0,
			func: callback
		});
	};
	SyncReader.prototype.process = function() {
		while (this._reads.length > 0 && this._buffer.length) {
			let read = this._reads[0];
			if (this._buffer.length && (this._buffer.length >= read.length || read.allowLess)) {
				this._reads.shift();
				let buf = this._buffer;
				this._buffer = buf.slice(read.length);
				read.func.call(this, buf.slice(0, read.length));
			} else break;
		}
		if (this._reads.length > 0) return /* @__PURE__ */ new Error("There are some read requests waitng on finished stream");
		if (this._buffer.length > 0) return /* @__PURE__ */ new Error("unrecognised content at end of stream");
	};
}));
//#endregion
//#region node_modules/pngjs/lib/filter-parse-sync.js
var require_filter_parse_sync = /* @__PURE__ */ __commonJSMin(((exports) => {
	var SyncReader = require_sync_reader();
	var Filter = require_filter_parse();
	exports.process = function(inBuffer, bitmapInfo) {
		let outBuffers = [];
		let reader = new SyncReader(inBuffer);
		new Filter(bitmapInfo, {
			read: reader.read.bind(reader),
			write: function(bufferPart) {
				outBuffers.push(bufferPart);
			},
			complete: function() {}
		}).start();
		reader.process();
		return Buffer.concat(outBuffers);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/parser-sync.js
var require_parser_sync = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var hasSyncZlib = true;
	var zlib$1 = __require("zlib");
	var inflateSync = require_sync_inflate();
	if (!zlib$1.deflateSync) hasSyncZlib = false;
	var SyncReader = require_sync_reader();
	var FilterSync = require_filter_parse_sync();
	var Parser = require_parser();
	var bitmapper = require_bitmapper();
	var formatNormaliser = require_format_normaliser();
	module.exports = function(buffer, options) {
		if (!hasSyncZlib) throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");
		let err;
		function handleError(_err_) {
			err = _err_;
		}
		let metaData;
		function handleMetaData(_metaData_) {
			metaData = _metaData_;
		}
		function handleTransColor(transColor) {
			metaData.transColor = transColor;
		}
		function handlePalette(palette) {
			metaData.palette = palette;
		}
		function handleSimpleTransparency() {
			metaData.alpha = true;
		}
		let gamma;
		function handleGamma(_gamma_) {
			gamma = _gamma_;
		}
		let inflateDataList = [];
		function handleInflateData(inflatedData) {
			inflateDataList.push(inflatedData);
		}
		let reader = new SyncReader(buffer);
		new Parser(options, {
			read: reader.read.bind(reader),
			error: handleError,
			metadata: handleMetaData,
			gamma: handleGamma,
			palette: handlePalette,
			transColor: handleTransColor,
			inflateData: handleInflateData,
			simpleTransparency: handleSimpleTransparency
		}).start();
		reader.process();
		if (err) throw err;
		let inflateData = Buffer.concat(inflateDataList);
		inflateDataList.length = 0;
		let inflatedData;
		if (metaData.interlace) inflatedData = zlib$1.inflateSync(inflateData);
		else {
			let imageSize = ((metaData.width * metaData.bpp * metaData.depth + 7 >> 3) + 1) * metaData.height;
			inflatedData = inflateSync(inflateData, {
				chunkSize: imageSize,
				maxLength: imageSize
			});
		}
		inflateData = null;
		if (!inflatedData || !inflatedData.length) throw new Error("bad png - invalid inflate data response");
		let unfilteredData = FilterSync.process(inflatedData, metaData);
		inflateData = null;
		let bitmapData = bitmapper.dataToBitMap(unfilteredData, metaData);
		unfilteredData = null;
		let normalisedBitmapData = formatNormaliser(bitmapData, metaData);
		metaData.data = normalisedBitmapData;
		metaData.gamma = gamma || 0;
		return metaData;
	};
}));
//#endregion
//#region node_modules/pngjs/lib/packer-sync.js
var require_packer_sync = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	var hasSyncZlib = true;
	var zlib = __require("zlib");
	if (!zlib.deflateSync) hasSyncZlib = false;
	var constants = require_constants();
	var Packer = require_packer();
	module.exports = function(metaData, opt) {
		if (!hasSyncZlib) throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0");
		let packer = new Packer(opt || {});
		let chunks = [];
		chunks.push(Buffer.from(constants.PNG_SIGNATURE));
		chunks.push(packer.packIHDR(metaData.width, metaData.height));
		if (metaData.gamma) chunks.push(packer.packGAMA(metaData.gamma));
		let filteredData = packer.filterData(metaData.data, metaData.width, metaData.height);
		let compressedData = zlib.deflateSync(filteredData, packer.getDeflateOptions());
		filteredData = null;
		if (!compressedData || !compressedData.length) throw new Error("bad png - invalid compressed data response");
		chunks.push(packer.packIDAT(compressedData));
		chunks.push(packer.packIEND());
		return Buffer.concat(chunks);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/png-sync.js
var require_png_sync = /* @__PURE__ */ __commonJSMin(((exports) => {
	var parse = require_parser_sync();
	var pack = require_packer_sync();
	exports.read = function(buffer, options) {
		return parse(buffer, options || {});
	};
	exports.write = function(png, options) {
		return pack(png, options);
	};
}));
//#endregion
//#region node_modules/pngjs/lib/png.js
var require_png$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
	var util = __require("util");
	var Stream = __require("stream");
	var Parser = require_parser_async();
	var Packer = require_packer_async();
	var PNGSync = require_png_sync();
	var PNG = exports.PNG = function(options) {
		Stream.call(this);
		options = options || {};
		this.width = options.width | 0;
		this.height = options.height | 0;
		this.data = this.width > 0 && this.height > 0 ? Buffer.alloc(4 * this.width * this.height) : null;
		if (options.fill && this.data) this.data.fill(0);
		this.gamma = 0;
		this.readable = this.writable = true;
		this._parser = new Parser(options);
		this._parser.on("error", this.emit.bind(this, "error"));
		this._parser.on("close", this._handleClose.bind(this));
		this._parser.on("metadata", this._metadata.bind(this));
		this._parser.on("gamma", this._gamma.bind(this));
		this._parser.on("parsed", function(data) {
			this.data = data;
			this.emit("parsed", data);
		}.bind(this));
		this._packer = new Packer(options);
		this._packer.on("data", this.emit.bind(this, "data"));
		this._packer.on("end", this.emit.bind(this, "end"));
		this._parser.on("close", this._handleClose.bind(this));
		this._packer.on("error", this.emit.bind(this, "error"));
	};
	util.inherits(PNG, Stream);
	PNG.sync = PNGSync;
	PNG.prototype.pack = function() {
		if (!this.data || !this.data.length) {
			this.emit("error", "No data provided");
			return this;
		}
		process.nextTick(function() {
			this._packer.pack(this.data, this.width, this.height, this.gamma);
		}.bind(this));
		return this;
	};
	PNG.prototype.parse = function(data, callback) {
		if (callback) {
			let onParsed, onError;
			onParsed = function(parsedData) {
				this.removeListener("error", onError);
				this.data = parsedData;
				callback(null, this);
			}.bind(this);
			onError = function(err) {
				this.removeListener("parsed", onParsed);
				callback(err, null);
			}.bind(this);
			this.once("parsed", onParsed);
			this.once("error", onError);
		}
		this.end(data);
		return this;
	};
	PNG.prototype.write = function(data) {
		this._parser.write(data);
		return true;
	};
	PNG.prototype.end = function(data) {
		this._parser.end(data);
	};
	PNG.prototype._metadata = function(metadata) {
		this.width = metadata.width;
		this.height = metadata.height;
		this.emit("metadata", metadata);
	};
	PNG.prototype._gamma = function(gamma) {
		this.gamma = gamma;
	};
	PNG.prototype._handleClose = function() {
		if (!this._parser.writable && !this._packer.readable) this.emit("close");
	};
	PNG.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) {
		srcX |= 0;
		srcY |= 0;
		width |= 0;
		height |= 0;
		deltaX |= 0;
		deltaY |= 0;
		if (srcX > src.width || srcY > src.height || srcX + width > src.width || srcY + height > src.height) throw new Error("bitblt reading outside image");
		if (deltaX > dst.width || deltaY > dst.height || deltaX + width > dst.width || deltaY + height > dst.height) throw new Error("bitblt writing outside image");
		for (let y = 0; y < height; y++) src.data.copy(dst.data, (deltaY + y) * dst.width + deltaX << 2, (srcY + y) * src.width + srcX << 2, (srcY + y) * src.width + srcX + width << 2);
	};
	PNG.prototype.bitblt = function(dst, srcX, srcY, width, height, deltaX, deltaY) {
		PNG.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY);
		return this;
	};
	PNG.adjustGamma = function(src) {
		if (src.gamma) {
			for (let y = 0; y < src.height; y++) for (let x = 0; x < src.width; x++) {
				let idx = src.width * y + x << 2;
				for (let i = 0; i < 3; i++) {
					let sample = src.data[idx + i] / 255;
					sample = Math.pow(sample, 1 / 2.2 / src.gamma);
					src.data[idx + i] = Math.round(sample * 255);
				}
			}
			src.gamma = 0;
		}
	};
	PNG.prototype.adjustGamma = function() {
		PNG.adjustGamma(this);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/utils.js
var require_utils = /* @__PURE__ */ __commonJSMin(((exports) => {
	function hex2rgba(hex) {
		if (typeof hex === "number") hex = hex.toString();
		if (typeof hex !== "string") throw new Error("Color should be defined as hex string");
		let hexCode = hex.slice().replace("#", "").split("");
		if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8) throw new Error("Invalid hex color: " + hex);
		if (hexCode.length === 3 || hexCode.length === 4) hexCode = Array.prototype.concat.apply([], hexCode.map(function(c) {
			return [c, c];
		}));
		if (hexCode.length === 6) hexCode.push("F", "F");
		const hexValue = parseInt(hexCode.join(""), 16);
		return {
			r: hexValue >> 24 & 255,
			g: hexValue >> 16 & 255,
			b: hexValue >> 8 & 255,
			a: hexValue & 255,
			hex: "#" + hexCode.slice(0, 6).join("")
		};
	}
	exports.getOptions = function getOptions(options) {
		if (!options) options = {};
		if (!options.color) options.color = {};
		const margin = typeof options.margin === "undefined" || options.margin === null || options.margin < 0 ? 4 : options.margin;
		const width = options.width && options.width >= 21 ? options.width : void 0;
		const scale = options.scale || 4;
		return {
			width,
			scale: width ? 4 : scale,
			margin,
			color: {
				dark: hex2rgba(options.color.dark || "#000000ff"),
				light: hex2rgba(options.color.light || "#ffffffff")
			},
			type: options.type,
			rendererOpts: options.rendererOpts || {}
		};
	};
	exports.getScale = function getScale(qrSize, opts) {
		return opts.width && opts.width >= qrSize + opts.margin * 2 ? opts.width / (qrSize + opts.margin * 2) : opts.scale;
	};
	exports.getImageWidth = function getImageWidth(qrSize, opts) {
		const scale = exports.getScale(qrSize, opts);
		return Math.floor((qrSize + opts.margin * 2) * scale);
	};
	exports.qrToImageData = function qrToImageData(imgData, qr, opts) {
		const size = qr.modules.size;
		const data = qr.modules.data;
		const scale = exports.getScale(size, opts);
		const symbolSize = Math.floor((size + opts.margin * 2) * scale);
		const scaledMargin = opts.margin * scale;
		const palette = [opts.color.light, opts.color.dark];
		for (let i = 0; i < symbolSize; i++) for (let j = 0; j < symbolSize; j++) {
			let posDst = (i * symbolSize + j) * 4;
			let pxColor = opts.color.light;
			if (i >= scaledMargin && j >= scaledMargin && i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {
				const iSrc = Math.floor((i - scaledMargin) / scale);
				const jSrc = Math.floor((j - scaledMargin) / scale);
				pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0];
			}
			imgData[posDst++] = pxColor.r;
			imgData[posDst++] = pxColor.g;
			imgData[posDst++] = pxColor.b;
			imgData[posDst] = pxColor.a;
		}
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/png.js
var require_png = /* @__PURE__ */ __commonJSMin(((exports) => {
	var fs$2 = __require("fs");
	var PNG = require_png$1().PNG;
	var Utils = require_utils();
	exports.render = function render(qrData, options) {
		const opts = Utils.getOptions(options);
		const pngOpts = opts.rendererOpts;
		const size = Utils.getImageWidth(qrData.modules.size, opts);
		pngOpts.width = size;
		pngOpts.height = size;
		const pngImage = new PNG(pngOpts);
		Utils.qrToImageData(pngImage.data, qrData, opts);
		return pngImage;
	};
	exports.renderToDataURL = function renderToDataURL(qrData, options, cb) {
		if (typeof cb === "undefined") {
			cb = options;
			options = void 0;
		}
		exports.renderToBuffer(qrData, options, function(err, output) {
			if (err) cb(err);
			let url = "data:image/png;base64,";
			url += output.toString("base64");
			cb(null, url);
		});
	};
	exports.renderToBuffer = function renderToBuffer(qrData, options, cb) {
		if (typeof cb === "undefined") {
			cb = options;
			options = void 0;
		}
		const png = exports.render(qrData, options);
		const buffer = [];
		png.on("error", cb);
		png.on("data", function(data) {
			buffer.push(data);
		});
		png.on("end", function() {
			cb(null, Buffer.concat(buffer));
		});
		png.pack();
	};
	exports.renderToFile = function renderToFile(path, qrData, options, cb) {
		if (typeof cb === "undefined") {
			cb = options;
			options = void 0;
		}
		let called = false;
		const done = (...args) => {
			if (called) return;
			called = true;
			cb.apply(null, args);
		};
		const stream = fs$2.createWriteStream(path);
		stream.on("error", done);
		stream.on("close", done);
		exports.renderToFileStream(stream, qrData, options);
	};
	exports.renderToFileStream = function renderToFileStream(stream, qrData, options) {
		exports.render(qrData, options).pack().pipe(stream);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/utf8.js
var require_utf8 = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils();
	var BLOCK_CHAR = {
		WW: " ",
		WB: "▄",
		BB: "█",
		BW: "▀"
	};
	var INVERTED_BLOCK_CHAR = {
		BB: " ",
		BW: "▄",
		WW: "█",
		WB: "▀"
	};
	function getBlockChar(top, bottom, blocks) {
		if (top && bottom) return blocks.BB;
		if (top && !bottom) return blocks.BW;
		if (!top && bottom) return blocks.WB;
		return blocks.WW;
	}
	exports.render = function(qrData, options, cb) {
		const opts = Utils.getOptions(options);
		let blocks = BLOCK_CHAR;
		if (opts.color.dark.hex === "#ffffff" || opts.color.light.hex === "#000000") blocks = INVERTED_BLOCK_CHAR;
		const size = qrData.modules.size;
		const data = qrData.modules.data;
		let output = "";
		let hMargin = Array(size + opts.margin * 2 + 1).join(blocks.WW);
		hMargin = Array(opts.margin / 2 + 1).join(hMargin + "\n");
		const vMargin = Array(opts.margin + 1).join(blocks.WW);
		output += hMargin;
		for (let i = 0; i < size; i += 2) {
			output += vMargin;
			for (let j = 0; j < size; j++) {
				const topModule = data[i * size + j];
				const bottomModule = data[(i + 1) * size + j];
				output += getBlockChar(topModule, bottomModule, blocks);
			}
			output += vMargin + "\n";
		}
		output += hMargin.slice(0, -1);
		if (typeof cb === "function") cb(null, output);
		return output;
	};
	exports.renderToFile = function renderToFile(path, qrData, options, cb) {
		if (typeof cb === "undefined") {
			cb = options;
			options = void 0;
		}
		const fs = __require("fs");
		const utf8 = exports.render(qrData, options);
		fs.writeFile(path, utf8, cb);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/terminal/terminal.js
var require_terminal$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
	exports.render = function(qrData, options, cb) {
		const size = qrData.modules.size;
		const data = qrData.modules.data;
		const black = "\x1B[40m  \x1B[0m";
		const white = "\x1B[47m  \x1B[0m";
		let output = "";
		const hMargin = Array(size + 3).join(white);
		const vMargin = Array(2).join(white);
		output += hMargin + "\n";
		for (let i = 0; i < size; ++i) {
			output += white;
			for (let j = 0; j < size; j++) output += data[i * size + j] ? black : white;
			output += vMargin + "\n";
		}
		output += hMargin + "\n";
		if (typeof cb === "function") cb(null, output);
		return output;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/terminal/terminal-small.js
var require_terminal_small = /* @__PURE__ */ __commonJSMin(((exports) => {
	var foregroundWhite = "\x1B[37m";
	var foregroundBlack = "\x1B[30m";
	var reset = "\x1B[0m";
	var lineSetupNormal = "\x1B[47m\x1B[30m";
	var lineSetupInverse = "\x1B[40m\x1B[37m";
	var createPalette = function(lineSetup, foregroundWhite, foregroundBlack) {
		return {
			"00": "\x1B[0m " + lineSetup,
			"01": reset + foregroundWhite + "▄" + lineSetup,
			"02": reset + foregroundBlack + "▄" + lineSetup,
			10: reset + foregroundWhite + "▀" + lineSetup,
			11: " ",
			12: "▄",
			20: reset + foregroundBlack + "▀" + lineSetup,
			21: "▀",
			22: "█"
		};
	};
	/**
	* Returns code for QR pixel
	* @param {boolean[][]} modules
	* @param {number} size
	* @param {number} x
	* @param {number} y
	* @return {'0' | '1' | '2'}
	*/
	var mkCodePixel = function(modules, size, x, y) {
		const sizePlus = size + 1;
		if (x >= sizePlus || y >= sizePlus || y < -1 || x < -1) return "0";
		if (x >= size || y >= size || y < 0 || x < 0) return "1";
		return modules[y * size + x] ? "2" : "1";
	};
	/**
	* Returns code for four QR pixels. Suitable as key in palette.
	* @param {boolean[][]} modules
	* @param {number} size
	* @param {number} x
	* @param {number} y
	* @return {keyof palette}
	*/
	var mkCode = function(modules, size, x, y) {
		return mkCodePixel(modules, size, x, y) + mkCodePixel(modules, size, x, y + 1);
	};
	exports.render = function(qrData, options, cb) {
		const size = qrData.modules.size;
		const data = qrData.modules.data;
		const inverse = !!(options && options.inverse);
		const lineSetup = options && options.inverse ? lineSetupInverse : lineSetupNormal;
		const palette = createPalette(lineSetup, inverse ? foregroundBlack : foregroundWhite, inverse ? foregroundWhite : foregroundBlack);
		const newLine = "\x1B[0m\n" + lineSetup;
		let output = lineSetup;
		for (let y = -1; y < size + 1; y += 2) {
			for (let x = -1; x < size; x++) output += palette[mkCode(data, size, x, y)];
			output += palette[mkCode(data, size, size, y)] + newLine;
		}
		output += reset;
		if (typeof cb === "function") cb(null, output);
		return output;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/terminal.js
var require_terminal = /* @__PURE__ */ __commonJSMin(((exports) => {
	var big = require_terminal$1();
	var small = require_terminal_small();
	exports.render = function(qrData, options, cb) {
		if (options && options.small) return small.render(qrData, options, cb);
		return big.render(qrData, options, cb);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/svg-tag.js
var require_svg_tag = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils();
	function getColorAttrib(color, attrib) {
		const alpha = color.a / 255;
		const str = attrib + "=\"" + color.hex + "\"";
		return alpha < 1 ? str + " " + attrib + "-opacity=\"" + alpha.toFixed(2).slice(1) + "\"" : str;
	}
	function svgCmd(cmd, x, y) {
		let str = cmd + x;
		if (typeof y !== "undefined") str += " " + y;
		return str;
	}
	function qrToPath(data, size, margin) {
		let path = "";
		let moveBy = 0;
		let newRow = false;
		let lineLength = 0;
		for (let i = 0; i < data.length; i++) {
			const col = Math.floor(i % size);
			const row = Math.floor(i / size);
			if (!col && !newRow) newRow = true;
			if (data[i]) {
				lineLength++;
				if (!(i > 0 && col > 0 && data[i - 1])) {
					path += newRow ? svgCmd("M", col + margin, .5 + row + margin) : svgCmd("m", moveBy, 0);
					moveBy = 0;
					newRow = false;
				}
				if (!(col + 1 < size && data[i + 1])) {
					path += svgCmd("h", lineLength);
					lineLength = 0;
				}
			} else moveBy++;
		}
		return path;
	}
	exports.render = function render(qrData, options, cb) {
		const opts = Utils.getOptions(options);
		const size = qrData.modules.size;
		const data = qrData.modules.data;
		const qrcodesize = size + opts.margin * 2;
		const bg = !opts.color.light.a ? "" : "<path " + getColorAttrib(opts.color.light, "fill") + " d=\"M0 0h" + qrcodesize + "v" + qrcodesize + "H0z\"/>";
		const path = "<path " + getColorAttrib(opts.color.dark, "stroke") + " d=\"" + qrToPath(data, size, opts.margin) + "\"/>";
		const viewBox = "viewBox=\"0 0 " + qrcodesize + " " + qrcodesize + "\"";
		const svgTag = "<svg xmlns=\"http://www.w3.org/2000/svg\" " + (!opts.width ? "" : "width=\"" + opts.width + "\" height=\"" + opts.width + "\" ") + viewBox + " shape-rendering=\"crispEdges\">" + bg + path + "</svg>\n";
		if (typeof cb === "function") cb(null, svgTag);
		return svgTag;
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/svg.js
var require_svg = /* @__PURE__ */ __commonJSMin(((exports) => {
	exports.render = require_svg_tag().render;
	exports.renderToFile = function renderToFile(path, qrData, options, cb) {
		if (typeof cb === "undefined") {
			cb = options;
			options = void 0;
		}
		const fs = __require("fs");
		const xmlStr = "<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" + exports.render(qrData, options);
		fs.writeFile(path, xmlStr, cb);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/renderer/canvas.js
var require_canvas = /* @__PURE__ */ __commonJSMin(((exports) => {
	var Utils = require_utils();
	function clearCanvas(ctx, canvas, size) {
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		if (!canvas.style) canvas.style = {};
		canvas.height = size;
		canvas.width = size;
		canvas.style.height = size + "px";
		canvas.style.width = size + "px";
	}
	function getCanvasElement() {
		try {
			return document.createElement("canvas");
		} catch (e) {
			throw new Error("You need to specify a canvas element");
		}
	}
	exports.render = function render(qrData, canvas, options) {
		let opts = options;
		let canvasEl = canvas;
		if (typeof opts === "undefined" && (!canvas || !canvas.getContext)) {
			opts = canvas;
			canvas = void 0;
		}
		if (!canvas) canvasEl = getCanvasElement();
		opts = Utils.getOptions(opts);
		const size = Utils.getImageWidth(qrData.modules.size, opts);
		const ctx = canvasEl.getContext("2d");
		const image = ctx.createImageData(size, size);
		Utils.qrToImageData(image.data, qrData, opts);
		clearCanvas(ctx, canvasEl, size);
		ctx.putImageData(image, 0, 0);
		return canvasEl;
	};
	exports.renderToDataURL = function renderToDataURL(qrData, canvas, options) {
		let opts = options;
		if (typeof opts === "undefined" && (!canvas || !canvas.getContext)) {
			opts = canvas;
			canvas = void 0;
		}
		if (!opts) opts = {};
		const canvasEl = exports.render(qrData, canvas, opts);
		const type = opts.type || "image/png";
		const rendererOpts = opts.rendererOpts || {};
		return canvasEl.toDataURL(type, rendererOpts.quality);
	};
}));
//#endregion
//#region node_modules/qrcode/lib/browser.js
var require_browser = /* @__PURE__ */ __commonJSMin(((exports) => {
	var canPromise = require_can_promise();
	var QRCode = require_qrcode();
	var CanvasRenderer = require_canvas();
	var SvgRenderer = require_svg_tag();
	function renderCanvas(renderFunc, canvas, text, opts, cb) {
		const args = [].slice.call(arguments, 1);
		const argsNum = args.length;
		const isLastArgCb = typeof args[argsNum - 1] === "function";
		if (!isLastArgCb && !canPromise()) throw new Error("Callback required as last argument");
		if (isLastArgCb) {
			if (argsNum < 2) throw new Error("Too few arguments provided");
			if (argsNum === 2) {
				cb = text;
				text = canvas;
				canvas = opts = void 0;
			} else if (argsNum === 3) if (canvas.getContext && typeof cb === "undefined") {
				cb = opts;
				opts = void 0;
			} else {
				cb = opts;
				opts = text;
				text = canvas;
				canvas = void 0;
			}
		} else {
			if (argsNum < 1) throw new Error("Too few arguments provided");
			if (argsNum === 1) {
				text = canvas;
				canvas = opts = void 0;
			} else if (argsNum === 2 && !canvas.getContext) {
				opts = text;
				text = canvas;
				canvas = void 0;
			}
			return new Promise(function(resolve, reject) {
				try {
					resolve(renderFunc(QRCode.create(text, opts), canvas, opts));
				} catch (e) {
					reject(e);
				}
			});
		}
		try {
			const data = QRCode.create(text, opts);
			cb(null, renderFunc(data, canvas, opts));
		} catch (e) {
			cb(e);
		}
	}
	exports.create = QRCode.create;
	exports.toCanvas = renderCanvas.bind(null, CanvasRenderer.render);
	exports.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL);
	exports.toString = renderCanvas.bind(null, function(data, _, opts) {
		return SvgRenderer.render(data, opts);
	});
}));
//#endregion
//#region src/main/llbot-ipc.ts
var import_server = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports) => {
	var canPromise = require_can_promise();
	var QRCode = require_qrcode();
	require_png();
	var Utf8Renderer = require_utf8();
	var TerminalRenderer = require_terminal();
	var SvgRenderer = require_svg();
	function checkParams(text, opts, cb) {
		if (typeof text === "undefined") throw new Error("String required as first argument");
		if (typeof cb === "undefined") {
			cb = opts;
			opts = {};
		}
		if (typeof cb !== "function") if (!canPromise()) throw new Error("Callback required as last argument");
		else {
			opts = cb || {};
			cb = null;
		}
		return {
			opts,
			cb
		};
	}
	function getStringRendererFromType(type) {
		switch (type) {
			case "svg": return SvgRenderer;
			case "terminal": return TerminalRenderer;
			default: return Utf8Renderer;
		}
	}
	function render(renderFunc, text, params) {
		if (!params.cb) return new Promise(function(resolve, reject) {
			try {
				return renderFunc(QRCode.create(text, params.opts), params.opts, function(err, data) {
					return err ? reject(err) : resolve(data);
				});
			} catch (e) {
				reject(e);
			}
		});
		try {
			return renderFunc(QRCode.create(text, params.opts), params.opts, params.cb);
		} catch (e) {
			params.cb(e);
		}
	}
	exports.create = QRCode.create;
	exports.toCanvas = require_browser().toCanvas;
	exports.toString = function toString(text, opts, cb) {
		const params = checkParams(text, opts, cb);
		return render(getStringRendererFromType(params.opts ? params.opts.type : void 0).render, text, params);
	};
})))(), 1);
var logger = getLogger("llbot-ipc");
var loginState = { state: "initializing" };
var server = null;
function setLoginState(patch) {
	loginState = {
		...loginState,
		...patch
	};
}
function startIpcServer() {
	const pipeName = process.env.LL_IPC_PIPE;
	if (!pipeName) return;
	if (server) return;
	server = net.createServer((socket) => {
		socket.setEncoding("utf8");
		let buffer = "";
		socket.on("data", (chunk) => {
			buffer += chunk;
			let idx;
			while ((idx = buffer.indexOf("\n")) >= 0) {
				const line = buffer.slice(0, idx);
				buffer = buffer.slice(idx + 1);
				if (line.trim()) handleLine(socket, line);
			}
		});
		socket.on("error", () => {});
	});
	let listenPath;
	if (process.platform === "win32") listenPath = `\\\\.\\pipe\\${pipeName}`;
	else {
		listenPath = pipeName;
		try {
			fs.unlinkSync(listenPath);
		} catch {}
	}
	server.listen(listenPath, () => {
		logger.info(`[LL_IPC] listening on ${listenPath}`);
	});
	server.on("error", (e) => {
		logger.warn(`[LL_IPC] server error: ${e.message}`);
	});
	if (process.platform !== "win32") {
		const cleanup = () => {
			try {
				fs.unlinkSync(listenPath);
			} catch {}
		};
		process.once("exit", cleanup);
		process.once("SIGINT", () => {
			cleanup();
			process.exit(0);
		});
		process.once("SIGTERM", () => {
			cleanup();
			process.exit(0);
		});
	}
}
function handleLine(socket, line) {
	let msg;
	try {
		msg = JSON.parse(line);
	} catch {
		return;
	}
	if (msg.type !== "request" || !msg.id || !msg.method) return;
	let response;
	if (msg.method === "get_login_state") response = {
		type: "response",
		id: msg.id,
		data: loginState
	};
	else response = {
		type: "response",
		id: msg.id,
		error: `unknown method: ${msg.method}`
	};
	if (!socket.destroyed) socket.write(JSON.stringify(response) + "\n");
}
//#endregion
//#region src/main/qqProtocol/base.ts
/**
* QQProtocolBase: PMHQ / Direct 两模式共享的抽象层.
* - sendPB/get_is_connected/start/getLoginQrCode 是 abstract, 由子类按各自传输实现.
* - sendOidb / onDisconnect / maybeEmitOnline 是通用工具, 在这里定型.
* - 具体实现: PmhqQQProtocol (WS+HTTP) / DirectQQProtocol (native sign + TCP).
*/
var QQProtocolBase = class extends Service {
	ctx;
	static inject = ["config"];
	disconnectCallbacks = /* @__PURE__ */ new Map();
	lastConnectedTime = Date.now();
	disconnectCheckTimer;
	logger;
	onlineEmitted = false;
	qrResult = null;
	qrFetchedAt = 0;
	lastPrintedQrSig = "";
	qrLoopRunning = false;
	constructor(ctx) {
		super(ctx, "qqProtocol");
		this.ctx = ctx;
		this.logger = ctx.logger("qq-protocol");
	}
	/**
	* 列出本地可快速登录的账号. **仅 Direct 模式实现** -- 直连持有 data/qq-session-*.json 是唯一可靠来源.
	* PMHQ 模式下 QQ NT 已登过, WebUI 不复用它的快速登录列表(那是 Desktop 的路径), 走 base 默认返空,
	* FE 拿到空列表会自动切扫码模式. 别在 PMHQ 里补真正的实现.
	*/
	listQuickLoginAccounts() {
		return [];
	}
	/**
	* 以指定 uin 快速登录. **仅 Direct 模式实现** -- 依赖 qq-session-<uin>.json 的加密凭证.
	* PMHQ 走 base 默认直接抛; 上层路由收到 500 后 FE 会 fallback 到扫码.
	*/
	async quickLogin(_uin) {
		throw new Error("quickLogin not supported in this mode");
	}
	/** 退出当前 QQ 登录, 回未登录态. 仅 Direct 模式实现; PMHQ 走 base 默认 no-op. */
	async logout() {}
	async [Service.init]() {
		await this.start();
		this.startDisconnectMonitoring();
	}
	async sendOidb(command, subCommand, body, cmdSuffix) {
		const reqBytes = Oidb.Base.encode({
			command,
			subCommand,
			body
		});
		const cmd = cmdSuffix ?? `OidbSvcTrpcTcp.0x${command.toString(16)}_${subCommand}`;
		const resp = await this.sendPB(cmd, reqBytes);
		const decoded = Oidb.Base.decode(Buffer.from(resp.pb, "hex"));
		return {
			errorCode: decoded.errorCode,
			errorMsg: decoded.errorMsg
		};
	}
	maybeEmitOnline() {
		if (this.onlineEmitted) return;
		if (!selfInfo.online) return;
		if (!selfInfo.uid && !selfInfo.uin) return;
		this.onlineEmitted = true;
		authTokenStatus.loginError = "";
		this.ctx.parallel("qq/online");
	}
	/**
	* emit qq/online 之后 ntUserApi 才会随插件加载. 用 ctx.inject 等它 ready 再拉一次 nick;
	* 拿到就写 selfInfo.nick, 失败就 warn 一下留空。子类在登录成功后调用。
	* guardToken/guardCheck 用于避免拿到 nick 时会话已换代(重复登录/换号)后错误写回。
	*/
	scheduleFetchSelfNick(guardCheck) {
		this.ctx.inject(["ntUserApi"], async (ctx) => {
			if (guardCheck && !guardCheck()) return;
			try {
				const nick = await ctx.ntUserApi.getSelfNick(false);
				this.logger.info(`getSelfNick -> ${JSON.stringify(nick)}`);
				if (guardCheck && !guardCheck()) return;
				if (nick) {
					selfInfo.nick = nick;
					ctx.parallel("llbot/self-nick-changed", { nick });
				}
			} catch (e) {
				this.logger.warn(`getSelfNick threw: ${e.message}`);
			}
		});
	}
	/**
	* WebUI / 外部拉登录二维码 -- 只返回后端当前缓存的那张 (过期才拉新).
	* 保证终端 QR / WebUI QR / Desktop QR 同源. expireTime 是剩余有效秒数,
	* FE 拿它 setTimeout 到期显示"点击刷新".
	*/
	async getLoginQrCode() {
		await this.refreshQrCodeIfStale();
		const qr = this.qrResult;
		if (!qr) throw new Error("QR code unavailable");
		const remainingMs = Math.max(0, qr.expireTimeSec * 1e3 - (Date.now() - this.qrFetchedAt));
		return {
			qrcodeUrl: qr.qrcodeUrl,
			pngBase64QrcodeData: qr.pngBase64,
			expireTime: Math.max(1, Math.floor(remainingMs / 1e3)),
			pollTimeInterval: 3
		};
	}
	/** 缓存无 / 到期 (按该码自己的 expireTimeSec) 才拉新码; 否则复用. */
	async refreshQrCodeIfStale() {
		if (this.qrResult && Date.now() - this.qrFetchedAt < this.qrResult.expireTimeSec * 1e3) return;
		const qr = await this.fetchFreshQrCode();
		if (!qr) return;
		this.qrResult = qr;
		this.qrFetchedAt = Date.now();
		this.onQrRefreshed();
	}
	/** 让缓存立即过期, 下次 refreshQrCodeIfStale 就会拉新码. */
	invalidateQrCache() {
		this.qrResult = null;
		this.qrFetchedAt = 0;
	}
	/** 完整复位 QR 展示状态 (缓存 + 打印去重 sig). 子类断线/重连/换账号时调, 保证重连后重新拉码打印. */
	resetQrState() {
		this.qrResult = null;
		this.qrFetchedAt = 0;
		this.lastPrintedQrSig = "";
	}
	/**
	* 拉码钩子: refreshQrCodeIfStale 拉到新码后调. 默认空.
	* Direct override 里启动 native 扫码 poll; PMHQ 无需 (靠 /health 探测 online).
	*/
	onQrRefreshed() {}
	/**
	* 拉二维码 -> 终端 ASCII 打印 + 落盘 png + 推 Desktop IPC + web url.
	* 按 sig 去重: 同一张码只打印一次, 换新码才再输出.
	*/
	async printQrToTerminal() {
		try {
			const data = await this.getLoginQrCode();
			const sig = this.qrResult?.sig || "";
			if (!sig || sig === this.lastPrintedQrSig) return;
			this.lastPrintedQrSig = sig;
			setLoginState({
				state: "need_qrcode",
				qrcode_png_base64: data.pngBase64QrcodeData
			});
			const qrText = await import_server.toString(data.qrcodeUrl, {
				type: "terminal",
				small: true
			});
			console.log("\n========== 请使用手机QQ扫描二维码登录 ==========");
			console.log(qrText);
			console.log("================================================\n");
			if (data.pngBase64QrcodeData) {
				const base64Data = data.pngBase64QrcodeData.replace(/^data:image\/png;base64,/, "");
				const qrFilePath = path.join(TEMP_DIR, "login-qrcode.png");
				if (!existsSync(TEMP_DIR)) mkdirSync(TEMP_DIR, { recursive: true });
				await writeFile(qrFilePath, Buffer.from(base64Data, "base64"));
				this.logger.info(`二维码文件已保存: ${qrFilePath}`);
			}
			const qrWebUrl = `https://api.2dcode.biz/v1/create-qr-code?data=${encodeURIComponent(data.qrcodeUrl)}`;
			this.logger.info(`或浏览器打开二维码网址: ${qrWebUrl}`);
		} catch (e) {
			const reason = e instanceof Error ? e.message : String(e);
			this.logger.warn(`获取登录二维码失败: ${reason}`);
		}
	}
	/** 幂等启动终端扫码 tick loop: 已在跑则不再起新链. 子类未登录时调. */
	ensureQrLoop() {
		if (this.qrLoopRunning) return;
		this.qrLoop();
	}
	/**
	* loop 是否暂停打印新码 (但不停 loop). 默认 false.
	* Direct override: 登录中 (isLoggedIn 但 online 未置) 返回 true -- 别拉新码, 但保持 loop
	* 以防 register 失败清 session 后无码可出.
	*/
	shouldSkipQrPrint() {
		return false;
	}
	/**
	* 终端扫码 loop: online 则停; 未登录每秒 tick 一次 printQrToTerminal.
	* 真正拉新码的节流由 refreshQrCodeIfStale 的 TTL 说了算, 每秒 tick 只在换码时打印.
	*/
	qrLoop = async () => {
		if (selfInfo.online) {
			this.qrLoopRunning = false;
			return;
		}
		this.qrLoopRunning = true;
		if (!this.shouldSkipQrPrint()) await this.printQrToTerminal();
		if (selfInfo.online) {
			this.qrLoopRunning = false;
			return;
		}
		setTimeout(this.qrLoop, 1e3);
	};
	onDisconnect(timeout, callback) {
		const id = randomUUID();
		this.disconnectCallbacks.set(id, {
			timeout,
			callback,
			triggered: false
		});
		return id;
	}
	offDisconnect(id) {
		this.disconnectCallbacks.delete(id);
	}
	/** 由子类在 start() 完成后调用 (基类 Service.init 里已代为调用一次). 幂等. */
	startDisconnectMonitoring() {
		if (this.disconnectCheckTimer) return;
		this.disconnectCheckTimer = setInterval(() => {
			if (this.get_is_connected()) {
				this.lastConnectedTime = Date.now();
				for (const info of this.disconnectCallbacks.values()) info.triggered = false;
			} else {
				const disconnectedDuration = Date.now() - this.lastConnectedTime;
				for (const info of this.disconnectCallbacks.values()) if (!info.triggered && disconnectedDuration >= info.timeout) {
					info.triggered = true;
					this.logger.warn(`[Protocol] Triggering disconnect callback, duration: ${disconnectedDuration}ms, timeout: ${info.timeout}ms`);
					try {
						info.callback(disconnectedDuration);
					} catch (e) {
						this.logger.error("disconnect callback error", e);
					}
				}
			}
		}, 5e3);
	}
};
//#endregion
//#region src/main/qqProtocol/pmhq.ts
/**
* PMHQ 模式实现: WS(优先) + HTTP 回退 与 PMHQ dll 通信.
* QQ NT 早已登录, LLBot 寄生其上; 靠 /health 轮询拿 uin/uid.
*/
var PmhqQQProtocol = class extends QQProtocolBase {
	reconnectTimer;
	httpUrl;
	wsUrl;
	ws;
	resListeners = /* @__PURE__ */ new Map();
	hasConnectedOnce = false;
	hasLoggedConnectionError = false;
	pmhqProbeToken = 0;
	constructor(ctx) {
		super(ctx);
		const { pmhqHost, pmhqPort } = this.getPMHQHostPort();
		this.httpUrl = `http://${pmhqHost}:${pmhqPort}/`;
		this.wsUrl = `ws://${pmhqHost}:${pmhqPort}/ws`;
	}
	async start() {
		this.addResListener((data) => {
			if (data?.type === "recv" && data.data?.cmd && data.data?.pb) {
				const payload = Buffer.from(data.data.pb, "hex");
				this.ctx.parallel("qq/raw", {
					cmd: data.data.cmd,
					payload
				});
			}
		});
		await this.connectWebSocket();
	}
	get_is_connected() {
		return !!this.ws && this.ws.readyState === WebSocket.OPEN;
	}
	async sendPB(cmd, pb, timeout = 15e3) {
		const hex = Buffer.isBuffer(pb) ? pb.toString("hex") : pb;
		if (this.ws?.readyState === WebSocket.OPEN) return this.unwrapPmhqRes(await this.wsSend({
			type: "send",
			data: {
				cmd,
				pb: hex
			}
		}, timeout), cmd);
		return this.unwrapPmhqRes(await this.httpSend({
			type: "send",
			data: {
				cmd,
				pb: hex
			}
		}), cmd);
	}
	/**
	* base 拉码钩子: 拉一张新登录二维码 (QQ 未登录时 PMHQ 注入的 JS 会主动拉码写临时文件, 这里读接口).
	* expireTimeSec 用接口返回的真实 expireTime -- base 据此做 TTL, 没过期不重拉 (修终端狂刷 bug).
	* code:1 (已登录) / 其它 (未就绪) 返回 null, base loop 静默重试.
	*/
	async fetchFreshQrCode() {
		const res = await this.fetchPmhqQrcode();
		if (res.code === 0 && res.data) return {
			qrcodeUrl: res.data.qrcodeUrl,
			pngBase64: res.data.pngBase64QrcodeData,
			expireTimeSec: res.data.expireTime,
			sig: res.data.qrcodeUrl
		};
		return null;
	}
	/**
	* PMHQ 模式下 LLBot 是寄生在 QQ NT 上的, QQ NT 早就登录过了, 开机时的 InfoSyncPush 也早处理完.
	* LLBot 想要群最新 seq (拉历史用) 就得自己主动触发一次: 发 SsoInfoSync, server 看到注册请求就回一发 InfoSyncPush.
	* isFirstRegisterProxyOnline=0 + 派生 guid (基于 uid, 每个号固定) 尽量避免和 QQ NT 的注册项冲突.
	*/
	async triggerInfoSyncPush() {
		const seed = selfInfo.uid || selfInfo.uin || "llbot";
		const payload = buildSsoInfoSync(createHash("md5").update(`llbot-${seed}`).digest().subarray(0, 16), false);
		await this.sendPB("trpc.msg.register_proxy.RegisterProxy.SsoInfoSync", payload, 5e3);
		this.logger.debug("已主动触发 RegisterProxy.SsoInfoSync（PMHQ）");
	}
	resetPmhqState() {
		const wasOnline = this.onlineEmitted;
		selfInfo.online = false;
		selfInfo.uid = "";
		selfInfo.uin = "";
		selfInfo.nick = "";
		this.pmhqProbeToken++;
		this.onlineEmitted = false;
		this.resetQrState();
		if (wasOnline) this.ctx.parallel("protocol/disconnect");
	}
	/**
	* PMHQ 模式: 轮询 /health 拿 self uin/uid (DLL 从 QQ 内存直接读 uin,
	* injector 侧扫 recv pb 抠 uid, 都写到 /health). 拿到 uin+uid 立即 emit online,
	* nick 通过 scheduleFetchSelfNick 异步等 ntUserApi 服务 ready 后再拉.
	* 重连后会被 onopen 再次调用, 所以必须先 reset 旧状态再启动新一轮.
	*/
	startPmhqLoginProbe() {
		this.resetPmhqState();
		const myToken = ++this.pmhqProbeToken;
		let warnedNotLoggedIn = false;
		const probe = async () => {
			if (this.pmhqProbeToken !== myToken) return;
			try {
				const resp = await fetch(`${this.httpUrl}health`);
				if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
				const health = await resp.json();
				if (this.pmhqProbeToken !== myToken) return;
				if (health.uin && health.uid) {
					selfInfo.uid = health.uid;
					selfInfo.uin = String(health.uin);
					this.ctx.logger.info(`Self info ${selfInfo.nick || "<pending>"}(${selfInfo.uin}) uid=${selfInfo.uid}`);
					if (!selfInfo.online) this.logger.info("QQ 登录成功");
					selfInfo.online = true;
					this.maybeEmitOnline();
					this.scheduleFetchSelfNick(() => this.pmhqProbeToken === myToken);
				} else {
					this.ensureQrLoop();
					if (!warnedNotLoggedIn) {
						this.logger.info("QQ 未登录，等待登录中...");
						warnedNotLoggedIn = true;
					}
				}
			} catch (e) {
				if (this.pmhqProbeToken !== myToken) return;
				if (!warnedNotLoggedIn) {
					this.logger.info("PMHQ /health probe failed (QQ 未启动?), 继续等待: %s", e.message);
					warnedNotLoggedIn = true;
				}
			}
			if (this.pmhqProbeToken !== myToken) return;
			if (selfInfo.online) return;
			setTimeout(probe, 600);
		};
		probe();
	}
	/**
	* 打一次 PMHQ /get_login_qrcode. 响应约定 (见 pmhq_get_login_qrcode 文档):
	* code:0 拿到码; code:1 已登录; code:-1 未就绪/已过期 (稍后重试会返回新码)。
	*/
	async fetchPmhqQrcode() {
		const resp = await fetch(`${this.httpUrl}get_login_qrcode`);
		if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
		return await resp.json();
	}
	getPMHQHostPort() {
		let pmhqPort = "13000";
		let pmhqHost = "127.0.0.1";
		for (const pArg of process.argv) if (pArg.startsWith("--pmhq-port=")) pmhqPort = pArg.replace("--pmhq-port=", "");
		else if (pArg.startsWith("--pmhq-host=")) pmhqHost = pArg.replace("--pmhq-host=", "");
		return {
			pmhqPort,
			pmhqHost
		};
	}
	addResListener(listener) {
		const listenerId = randomUUID();
		this.resListeners.set(listenerId, listener);
		return listenerId;
	}
	removeResListener(listenerId) {
		this.resListeners.delete(listenerId);
	}
	async connectWebSocket() {
		const reconnect = () => {
			this.ws = void 0;
			if (this.reconnectTimer) {
				clearTimeout(this.reconnectTimer);
				this.reconnectTimer = void 0;
			}
			this.reconnectTimer = setTimeout(() => {
				this.connectWebSocket();
			}, 1e3);
		};
		try {
			this.ws = new WebSocket(this.wsUrl);
		} catch (e) {
			return reconnect();
		}
		this.ws.onmessage = async (event) => {
			let data;
			try {
				data = JSON.parse(event.data.toString());
			} catch (e) {
				this.logger.error("解析 PMHQ 消息失败", event.data, e);
				return;
			}
			data = deepConvertMap(data);
			for (const func of this.resListeners.values()) setImmediate(() => {
				try {
					func(data);
				} catch (e) {
					this.logger.error("PMHQ res listener error", e);
				}
			});
		};
		this.ws.onerror = () => {
			selfInfo.online = false;
			this.resetPmhqState();
			if (!this.hasLoggedConnectionError) {
				this.logger.error("PMHQ WebSocket 连接错误，可能 QQ 未启动，正在等待 QQ 启动进行重连...");
				this.hasLoggedConnectionError = true;
			}
			reconnect();
		};
		this.ws.onclose = () => {
			selfInfo.online = false;
			this.resetPmhqState();
			if (!this.hasLoggedConnectionError) {
				this.logger.info("PMHQ WebSocket 连接关闭，准备重连...");
				this.hasLoggedConnectionError = true;
			}
			reconnect();
		};
		this.ws.onopen = () => {
			this.logger.info("PMHQ WebSocket 连接成功");
			this.hasLoggedConnectionError = false;
			if (!this.hasConnectedOnce) {
				this.hasConnectedOnce = true;
				this.lastConnectedTime = Date.now();
			}
			this.startPmhqLoginProbe();
		};
	}
	async waitConnected() {
		return new Promise((resolve) => {
			const check = () => {
				if (this.ws && this.ws.readyState === WebSocket.OPEN) resolve(true);
				else setTimeout(check, 1e3);
			};
			check();
		});
	}
	async wsSend(data, timeout = 15e3) {
		await this.waitConnected();
		let echo = data.data?.echo;
		if (!data.data?.echo) {
			echo = randomUUID();
			data.data.echo = echo;
		}
		const payload = JSON.stringify(deepStringifyMap(data));
		const p = new Promise((resolve, reject) => {
			const timeoutId = setTimeout(() => {
				reject(/* @__PURE__ */ new Error("pmhq ws send: wait result timeout"));
				this.removeResListener(listenerId);
			}, timeout);
			const listenerId = this.addResListener((res) => {
				if (!res.data) this.logger.error(`PMHQ WS send error: payload ${JSON.stringify(data)}, response ${JSON.stringify(res)}`);
				if (res.data?.echo == echo) {
					resolve(res);
					clearTimeout(timeoutId);
					this.removeResListener(listenerId);
				}
			});
		});
		this.ws.send(payload);
		return p;
	}
	async httpSend(data) {
		const payload = JSON.stringify(deepStringifyMap(data));
		const response = await fetch(this.httpUrl, {
			method: "POST",
			headers: { "Content-Type": "application/json" },
			body: payload
		});
		if (!response.ok) {
			const errorBody = await response.text();
			throw new Error(`PMHQ请求失败，请检查发包器PMHQ设置 ${response.status} - ${errorBody}`);
		}
		let result = await response.json();
		result = deepConvertMap(result);
		return result;
	}
	/**
	* 解包 PMHQ active-send 响应. echo 只用于关联请求, 不能"echo 匹配就算成功":
	* PMHQ 即使发包失败 / QQ 未登录, 也会回一条 echo 匹配但 code 非 0 的响应.
	* 成败一律看 code: 0 = QQ 真回包 (已登录); 非 0 (-100 未登录/KernelMsgService 缺失/管道未连,
	* 或 QQ app error) 一律抛错, 不让上层拿空 pb 去 decode.
	*/
	unwrapPmhqRes(res, cmd) {
		if (res.code != null && res.code !== 0) {
			const pb = res.data?.pb ?? "";
			const detail = pb ? ` pb=${pb.slice(0, 160)}` : " pb=<empty>";
			throw new Error(`PMHQ send failed: cmd=${cmd} code=${res.code} ${res.message ?? ""}${detail}`.trim());
		}
		return res.data;
	}
};
//#endregion
//#region src/main/qqProtocol/direct.ts
/**
* Direct 模式实现: 走 native sign + TCP 直连. QQ 未登录 -> WebUI 扫码.
* 内部持有一个低层 native `DirectProtocolClient` (direct-lib/client.ts, 不要跟本类混淆).
*/
var DirectQQProtocol = class DirectQQProtocol extends QQProtocolBase {
	directClient = null;
	directInitInFlight = false;
	directPendingToken = "";
	directQrResult = null;
	directPollResult = null;
	directStopHeartbeat = null;
	reconnectTimer = null;
	manualLogout = false;
	qrPollToken = 0;
	static QR_TTL_MS = 18e4;
	static RECONNECT_MS = 5e3;
	runtimeUinOverride = null;
	constructor(ctx) {
		super(ctx);
	}
	async start() {
		this.ctx.on("nt/kicked-offline", () => {
			if (this.directStopHeartbeat) {
				this.directStopHeartbeat();
				this.directStopHeartbeat = null;
			}
			const kickedUin = selfInfo.uin || this.runtimeUinOverride || getSpecifiedUin() || "";
			if (kickedUin) deleteSession(kickedUin);
			deleteMachineGuid();
			this.directClient?.setGuid(loadMachineGuidSync());
			this.runtimeUinOverride = null;
			this.directClient?.clearSession();
			this.directClient?.disconnect();
		});
		startAuthTokenWatcher(this.onAuthTokenValid.bind(this), this.logger);
	}
	get_is_connected() {
		return !!this.directClient?.isLoggedIn;
	}
	async sendPB(cmd, pb, timeout = 15e3) {
		if (!this.directClient?.isLoggedIn) throw new Error("Direct client not logged in");
		const buf = Buffer.isBuffer(pb) ? pb : Buffer.from(pb, "hex");
		return {
			cmd,
			pb: (await this.directClient.sendCommand(cmd, buf, void 0, timeout)).payload.toString("hex")
		};
	}
	/**
	* 列出本地可快速登录的账号 (对应 data/qq-session-<uin>.json). 用于 WebUI 快速登录列表.
	* 直连模式无 QQ NT 进程可问, 只能从本地 session 文件推断; 换机场景对应 session 已解不开,
	* 但此处只列明文元数据, 换机时 quickLogin 阶段 registerOnline 会失败并 fallback 扫码.
	*/
	listQuickLoginAccounts() {
		return listAvailableSessions();
	}
	/**
	* WebUI 请求以某个已保存 session 快速登录. 设置 runtime override 后重新 initDirectClient,
	* 走 loadSession(uin) 恢复通道 (等价于用户带 -q <uin> 启动).
	* 已在线时 no-op. session 解不开 (换机) 会抛错让 FE 弹提示, 用户可切扫码登录.
	*/
	async quickLogin(uin) {
		if (selfInfo.online) return;
		if (!/^\d+$/.test(uin)) throw new Error("invalid uin");
		if (!loadSession(uin)) throw new Error("session 已失效(可能换了机器或加密 key 变了), 请扫码重新登录");
		this.runtimeUinOverride = uin;
		await this.initDirectClient();
		this.ensureQrLoop();
	}
	async logout() {
		this.manualLogout = true;
		if (this.reconnectTimer) {
			clearTimeout(this.reconnectTimer);
			this.reconnectTimer = null;
		}
		this.directClient?.clearSession();
		this.directClient?.disconnect();
		selfInfo.online = false;
		selfInfo.uin = "";
		selfInfo.uid = "";
		selfInfo.nick = "";
		this.onlineEmitted = false;
		this.runtimeUinOverride = null;
		this.resetQrState();
		setLoginState({ state: "need_qrcode" });
		this.ensureQrLoop();
	}
	/**
	* base 拉码钩子: 向 QQ 服务器拉一张新二维码 (native wtlogin.trans_emp).
	* 存 native 凭证到 directQrResult (poll/登录要用 sig/tgtgtKey), 返回展示信息给 base 缓存.
	* client 未就绪时返回 null, base loop 静默重试.
	*/
	async fetchFreshQrCode() {
		if (!this.directClient) return null;
		if (!this.directClient.isConnected) await this.directClient.connect();
		const qr = await fetchQrCode(this.directClient);
		this.directQrResult = qr;
		return {
			qrcodeUrl: qr.url,
			pngBase64: qr.image.length > 0 ? "data:image/png;base64," + qr.image.toString("base64") : "",
			expireTimeSec: DirectQQProtocol.QR_TTL_MS / 1e3,
			sig: qr.sig.toString("hex")
		};
	}
	/** base 拉到新码后: 启动 native 扫码 poll (等手机扫码 -> Confirmed -> completeDirectLogin). */
	onQrRefreshed() {
		this.startDirectQrPolling();
	}
	/**
	* authTokenWatcher 校验通过 token 后回调本方法. 登录/sign 阶段的错误写回
	* authTokenStatus.loginError 供 WebUI 展示; init 抛错的话交给 watcher 定时重试自愈.
	*/
	async onAuthTokenValid(token) {
		if (selfInfo.online) return;
		try {
			await this.initDirectClient(token);
			this.ensureQrLoop();
		} catch (e) {
			authTokenStatus.loginError = e?.message || String(e);
			this.logger.error("[Sign] auth_token 校验通过但登录初始化失败:", e);
			throw e;
		}
	}
	/**
	* 登录中 (isLoggedIn 但 online 未置) 暂停打印新码, 但 base 的 qrLoop 继续 tick --
	* 以防 register 失败清 session 后无码可出. 真在线由 qrLoop 顶部 guard 停.
	*/
	shouldSkipQrPrint() {
		return !!this.directClient?.isLoggedIn;
	}
	scheduleReconnect() {
		if (this.reconnectTimer || selfInfo.online) return;
		if (!(authTokenUtil.reload() || process.env.AUTH_TOKEN || "").trim()) return;
		this.reconnectTimer = setTimeout(async () => {
			this.reconnectTimer = null;
			if (selfInfo.online) return;
			try {
				await this.initDirectClient();
				this.ensureQrLoop();
			} catch (e) {
				this.logger.warn("[Direct] 重连失败, 稍后重试", e);
			}
			this.scheduleReconnect();
		}, DirectQQProtocol.RECONNECT_MS);
	}
	/**
	* Initialize direct protocol client and attempt session restore.
	*
	* auth_token 未配置时不再 throw: 直接 return, 让进程/WebUI 正常起来. token 校验通过后
	* 由 authTokenWatcher 调 onAuthTokenValid -> 本方法(带已校验的 token)开始登录.
	* token 有效性校验在 watcher 里 (validateAuthToken), 这里不再做 preflight.
	* 可重入: 二次调用先拆掉上一个 client, 并把最新 token 热切换进 native sign。
	*/
	async initDirectClient(tokenArg) {
		let authToken = (tokenArg || authTokenUtil.reload() || process.env.AUTH_TOKEN || "").trim();
		if (!authToken) {
			const tokenPath = authTokenUtil.getPath();
			this.logger.warn(`[Sign] auth_token 未配置 (${tokenPath} 为空 / 不存在). 请在 WebUI 中录入, 或到 https://auth.luckylillia.com 获取后填入; 录入验证通过后会自动开始登录.`);
			return;
		}
		if (this.directInitInFlight) {
			this.directPendingToken = authToken;
			return;
		}
		this.directInitInFlight = true;
		let lastErr = null;
		try {
			do {
				this.directPendingToken = "";
				try {
					lastErr = null;
					await this.doInitDirectClient(authToken);
				} catch (e) {
					lastErr = e;
				}
				authToken = this.directPendingToken;
			} while (authToken);
		} finally {
			this.directInitInFlight = false;
			this.directPendingToken = "";
		}
		if (lastErr) throw lastErr;
	}
	async doInitDirectClient(authToken) {
		this.manualLogout = false;
		this.qrPollToken++;
		this.resetQrState();
		this.directQrResult = null;
		await updateAuthToken(authToken).catch((e) => this.logger.warn("[Sign] updateAuthToken failed:", e.message));
		const specifiedUin = this.runtimeUinOverride || getSpecifiedUin();
		if (specifiedUin) this.logger.info("Specified login uin: %s, will try qq-session-%s.json", specifiedUin, specifiedUin);
		else this.logger.info("No uin specified, will perform fresh QR login (session will be saved as qq-session-<uin>.json)");
		const persisted = loadSession(this.runtimeUinOverride ?? void 0);
		if (persisted) overwriteMachineGuid(Buffer.from(persisted.guid, "hex"));
		const uinCandidate = persisted?.uin || specifiedUin || "";
		const uinForInit = uinCandidate ? Number(uinCandidate) : void 0;
		const uinArg = Number.isFinite(uinForInit) && uinForInit > 0 ? uinForInit : void 0;
		if (!this.directClient) {
			this.directClient = new DirectProtocolClient({
				authToken,
				botVersion: `LLBot_${version$3}`,
				uin: uinArg
			});
			this.bindDirectClientEvents(this.directClient);
		} else {
			this.directClient.setAuthToken(authToken);
			this.directClient.setUin(uinArg);
			this.directClient.clearSession();
			if (persisted) {
				const g = Buffer.from(persisted.guid, "hex");
				if (!g.equals(this.directClient.getGuid())) this.directClient.setGuid(g);
			}
		}
		if (persisted) {
			this.logger.info("Found saved session for UIN %s (file: %s), attempting restore...", persisted.uin, getSessionFilePathForUin(persisted.uin));
			if (!this.directClient.isConnected) await this.directClient.connect();
			const session = persistedToSessionInfo(persisted);
			this.directClient.setSession(session);
			try {
				await registerOnline(this.directClient);
				this.logger.info("[QQ Server] Online registered!");
				selfInfo.uin = persisted.uin;
				selfInfo.uid = persisted.uid;
				if (persisted.nick) selfInfo.nick = persisted.nick;
				selfInfo.online = true;
				this.runtimeUinOverride = persisted.uin;
				this.directStopHeartbeat = startHeartbeat(this.directClient);
				this.maybeEmitOnline();
				if (!selfInfo.nick) this.scheduleFetchSelfNick();
				return;
			} catch (e) {
				this.logger.info("Saved session expired, will need QR login: %s", e.message);
				this.directClient.clearSession();
			}
		}
		if (!this.directClient.isConnected) await this.directClient.connect();
	}
	/** 给 client 挂事件 (error/connected/close/push). 只在首次建立 client 时调一次 -- 复用 client 不重挂. */
	bindDirectClientEvents(client) {
		client.on("error", (err) => {
			this.logger.warn("Direct client error:", err.message);
		});
		client.on("connected", () => {
			this.lastConnectedTime = Date.now();
		});
		client.on("close", () => {
			const wasOnline = this.onlineEmitted;
			selfInfo.online = false;
			if (this.directStopHeartbeat) {
				this.directStopHeartbeat();
				this.directStopHeartbeat = null;
			}
			this.onlineEmitted = false;
			if (wasOnline) {
				this.ctx.parallel("protocol/disconnect");
				if (!this.manualLogout) this.scheduleReconnect();
			}
		});
		client.on("push", (packet) => {
			this.lastConnectedTime = Date.now();
			this.ctx.parallel("qq/raw", {
				cmd: packet.cmd,
				payload: packet.payload
			});
		});
	}
	startDirectQrPolling() {
		if (!this.directClient || !this.directQrResult) return;
		const myToken = ++this.qrPollToken;
		const poll = async () => {
			if (this.qrPollToken !== myToken) return;
			if (!this.directClient || !this.directQrResult) return;
			if (this.directClient.isLoggedIn) return;
			try {
				const result = await pollQrCode(this.directClient, this.directQrResult.sig);
				if (this.qrPollToken !== myToken) return;
				this.directPollResult = result;
				if (result.state === QrCodeState.Confirmed) {
					await this.completeDirectLogin();
					return;
				}
				if (result.state === QrCodeState.WaitingForConfirm) setLoginState({ state: "waiting_confirm" });
				if (result.state === QrCodeState.Expired || result.state === QrCodeState.Cancelled) {
					setLoginState({ state: result.state === QrCodeState.Expired ? "expired" : "cancelled" });
					this.invalidateQrCache();
					return;
				}
			} catch (e) {
				this.logger.warn("QR poll error:", e.message);
			}
			if (this.qrPollToken !== myToken) return;
			setTimeout(poll, 2e3);
		};
		setTimeout(poll, 2e3);
	}
	async completeDirectLogin() {
		if (!this.directClient || !this.directPollResult || !this.directQrResult) return;
		this.manualLogout = false;
		const qrSig = new URL(this.directQrResult.url).searchParams.get("k") || "";
		const uin = await getCorrectUin(AppInfo.appId, qrSig);
		this.directPollResult.uin = String(uin);
		const loginResult = await loginWithQrResult(this.directClient, this.directPollResult);
		if (!loginResult.success) {
			this.logger.error(`Login failed: state=${loginResult.state} ${loginResult.tag} ${loginResult.message}`);
			authTokenStatus.loginError = `登录失败: ${[loginResult.tag, loginResult.message].filter(Boolean).join(" ")}`.trim();
			return;
		}
		this.logger.info(`Login successful! UID: ${loginResult.uid}, nick: "${loginResult.nick}"`);
		saveSession(this.directClient.getSession(), this.directPollResult.tgtgtKey, this.directClient.getGuid(), loginResult.tempPassword, loginResult.nick);
		try {
			await registerOnline(this.directClient);
		} catch (e) {
			const msg = e.message;
			this.logger.error("Register online failed:", msg);
			authTokenStatus.loginError = `上线注册失败: ${msg}`;
			this.directClient.clearSession();
			return;
		}
		this.directStopHeartbeat = startHeartbeat(this.directClient);
		selfInfo.uin = String(uin);
		selfInfo.uid = loginResult.uid;
		selfInfo.nick = loginResult.nick;
		selfInfo.online = true;
		this.runtimeUinOverride = String(uin);
		this.maybeEmitOnline();
		if (!selfInfo.nick) this.scheduleFetchSelfNick();
	}
};
//#endregion
//#region src/main/qqProtocol/mixins/friend.ts
function FriendMixin(Base) {
	class Mixed extends Base {
		async sendFriendPoke(friendUin, toUin) {
			const body = Oidb.SendPokeReq.encode({
				toUin,
				friendUin
			});
			return await this.sendOidb(3795, 1, body);
		}
		/**
		* 取私聊文件下载 url。field 10 是 query 发起者自己的 uid（PMHQ 抓包验过）。
		*/
		async getPrivateFileUrl(fileUuid) {
			const body = Oidb.GetPrivateFileReq.encode({
				subCommand: 1200,
				field2: 1,
				body: {
					receiverUid: selfInfo.uid,
					fileUuid,
					type: 2,
					fileHash: "",
					t2: 0
				},
				field101: 3,
				field102: 1,
				field200: 1,
				field99999: Buffer.from([
					192,
					133,
					44,
					1
				])
			});
			const data = Oidb.Base.encode({
				command: 3639,
				subCommand: 1200,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xe37_1200", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetPrivateFileResp.decode(oidbRespBody);
		}
		async setFriendRequest(targetUid, accept) {
			const body = Oidb.SetFriendRequestReq.encode({
				targetUid,
				accept
			});
			return await this.sendOidb(2909, 44, body);
		}
		async setFilteredFriendRequestReq(selfUid, requestUid) {
			const body = Oidb.SetFilteredFriendRequestReq.encode({
				selfUid,
				requestUid
			});
			return await this.sendOidb(3442, 0, body);
		}
		async fetchFriends(cookie) {
			const body = Oidb.IncPullReq.encode({
				reqCount: 500,
				cookie,
				flag: 1,
				requestBiz: [{
					bizType: 1,
					bizData: { extBusi: [
						102,
						103,
						20002,
						20009,
						20031,
						20037,
						27394
					] }
				}]
			});
			const data = Oidb.Base.encode({
				command: 4052,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xfd4_1", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.IncPullResp.decode(oidbRespBody);
		}
		async getFriendRecommendContactArk(uin) {
			const body = Oidb.GetFriendRecommendContactArkReq.encode({
				uin,
				phoneNumber: "-",
				jumpUrl: `mqqapi://card/show_pslcard?src_type=internal&source=sharecard&version=1&uin=${uin}`
			});
			const data = Oidb.Base.encode({
				command: 4790,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x12b6_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetFriendRecommendContactArkResp.decode(oidbRespBody);
		}
		async setFriendRemark(uid, remark) {
			const body = Oidb.SetFriendRemarkReq.encode({
				uid,
				remark
			});
			return await this.sendOidb(4300, 1, body);
		}
		async deleteFriend(targetUid, block, bothDelete) {
			const body = Oidb.DeleteFriendReq.encode({ field1: {
				targetUid,
				field2: {
					field1: 130,
					field2: 109,
					field3: {
						field1: 8,
						field2: 8,
						field3: 50
					}
				},
				block,
				bothDelete
			} });
			return await this.sendOidb(4715, 0, body);
		}
		async setFriendCategory(uid, categoryId) {
			const body = Oidb.SetFriendCategoryReq.encode({
				uid,
				categoryId
			});
			return await this.sendOidb(4331, 1, body);
		}
		async fetchFriendRequests(selfUid, reqNum) {
			const body = Oidb.FetchFriendRequestsReq.encode({
				version: 1,
				type: 6,
				selfUid,
				startIndex: 0,
				reqNum,
				getFlag: 2,
				startTime: 0,
				needCommFriend: 1,
				field22: 1
			});
			const data = Oidb.Base.encode({
				command: 1487,
				subCommand: 11,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x5cf_11", data);
			const oidbResp = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchFriendRequestsResp.decode(oidbResp.body);
		}
		async fetchFilteredFriendRequests(count) {
			const body = Oidb.FetchFilteredFriendRequestsReq.encode({
				field1: 1,
				field2: { count }
			});
			const data = Oidb.Base.encode({
				command: 3433,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xd69_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchFilteredFriendRequestsResp.decode(oidbRespBody);
		}
		async setFriendPin(friendUid, isPinned) {
			let timestamp;
			if (isPinned) {
				timestamp = Buffer.alloc(4);
				timestamp.writeInt32BE(Math.floor(Date.now() / 1e3), 0);
			} else timestamp = Buffer.alloc(0);
			const body = Oidb.SetFriendPinReq.encode({
				field1: 0,
				field3: 1,
				info: {
					friendUid,
					field400: {
						field1: 13578,
						timestamp
					}
				}
			});
			return await this.sendOidb(1494, 18, body);
		}
		/**
		* 拉取与某个**好友**之间的最新 c2cMsgSeq。
		*
		* server cmd: trpc.msg.msg_svc.MsgService.SsoGetPeerSeq
		* 入参：只接受 user uid（u_xxx 格式），不能传群 code（server 内部要把 peerUid 转 uin，
		*       群 code 转换失败会返回 "rsp uid convert to uin all fail"，全 0）。
		* 返回 (实测)：
		*   seq1, seq2 = 双端一致的 c2cMsgSeq；多数情况下相等，偶尔差 1（可能分别是发/收方向的最后一条）。
		*   latestMsgTime = 跟该 peer 最后一条消息的时间戳。
		*
		* 群聊场景请改用 fetchGroupExtra → info.results.latestMessageSeq（OidbSvcTrpcTcp.0x88d_0）。
		*/
		async getFriendLatestSequence(peerUid) {
			const data = Action.SsoGetPeerSeqReq.encode({ peerUid });
			const res = await this.sendPB("trpc.msg.msg_svc.MsgService.SsoGetPeerSeq", data);
			return Action.SsoGetPeerSeqResp.decode(Buffer.from(res.pb, "hex"));
		}
		async getFriendsStatus(selfUid) {
			const body = Oidb.GetFriendsStatusReq.encode({
				selfUid,
				field5: 1,
				field7: 0,
				field100: 0,
				field101: 400
			});
			const data = Oidb.Base.encode({
				command: 4461,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x116d_1", data);
			const oidbResp = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GetFriendsStatusResp.decode(oidbResp.body);
		}
	}
	return Mixed;
}
//#endregion
//#region src/main/qqProtocol/mixins/group.ts
function GroupMixin(Base) {
	class Mixed extends Base {
		async sendGroupPoke(groupCode, memberUin) {
			const body = Oidb.SendPokeReq.encode({
				toUin: memberUin,
				groupCode
			});
			return await this.sendOidb(3795, 1, body);
		}
		async setSpecialTitle(groupCode, memberUid, title) {
			const body = Oidb.SetSpecialTitleReq.encode({
				groupCode,
				body: {
					targetUid: memberUid,
					uidName: title,
					specialTitle: title,
					expireTime: -1
				}
			});
			return await this.sendOidb(2300, 2, body);
		}
		async groupClockIn(groupCode) {
			const body = Oidb.GroupClockInReq.encode({ body: {
				uin: selfInfo.uin,
				groupCode
			} });
			return await this.sendOidb(3767, 1, body);
		}
		async getGroupFileUrl(groupCode, fileId) {
			const body = Oidb.GetGroupFileReq.encode({ download: {
				groupCode,
				appId: 7,
				busId: 102,
				fileId
			} });
			const data = Oidb.Base.encode({
				command: 1750,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d6_2", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetGroupFileResp.decode(oidbRespBody);
		}
		async fetchGroups() {
			const body = Oidb.FetchGroupsReq.encode({ config: {
				config1: {
					groupOwner: true,
					createdTime: true,
					memberMax: true,
					memberCount: true,
					groupName: true,
					topTime: true,
					groupShutupExpireTime: true,
					description: true,
					question: true,
					richDescription: true,
					announcement: true
				},
				config2: {
					memberRole: true,
					remark: true,
					personShutupExpireTime: true,
					msgMask: true
				}
			} });
			const data = Oidb.Base.encode({
				command: 4069,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xfe5_2", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupsResp.decode(oidbRespBody);
		}
		async getGroupFileList(groupCode, targetDirectory, startIndex, fileCount) {
			const body = Oidb.GetGroupFileListReq.encode({ listReq: {
				groupCode,
				appId: 7,
				targetDirectory,
				fileCount,
				sortBy: 1,
				startIndex,
				field17: 2,
				field18: 0
			} });
			const data = Oidb.Base.encode({
				command: 1752,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d8_1", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetGroupFileListResp.decode(oidbRespBody);
		}
		/** 群文件总数（OidbSvcTrpcTcp.0x6d8_2） */
		async getGroupFileCount(groupCode, busId = 6) {
			const body = Oidb.GetGroupFileCountReq.encode({ countReq: {
				groupCode,
				appId: 7,
				busId
			} });
			const data = Oidb.Base.encode({
				command: 1752,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d8_2", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetGroupFileCountResp.decode(oidbRespBody);
		}
		/** 群文件总空间 / 已用空间（OidbSvcTrpcTcp.0x6d8_3） */
		async getGroupFileSpace(groupCode) {
			const body = Oidb.GetGroupFileSpaceReq.encode({ spaceReq: {
				groupCode,
				appId: 7
			} });
			const data = Oidb.Base.encode({
				command: 1752,
				subCommand: 3,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d8_3", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetGroupFileSpaceResp.decode(oidbRespBody);
		}
		/** 群文件 feed（0x6d9_4）—— upload 完成后调用，server 才会把文件作为聊天消息发到群里 */
		async feedGroupFile(groupCode, fileId, msgRandom, busId) {
			const body = Oidb.GroupFileFeedReq.encode({ feedsInfoReq: {
				groupCode,
				appId: 2,
				feedsInfoList: [{
					busId,
					fileId,
					msgRandom,
					feedFlag: 1
				}]
			} });
			const data = Oidb.Base.encode({
				command: 1753,
				subCommand: 4,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d9_4", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFileFeedResp.decode(decoded.body);
		}
		/** 删除群文件，busId 一般为 102（v1 默认），fileId 是 list 接口返回的 fileId */
		async deleteGroupFile(groupCode, fileId, busId = 102) {
			const body = Oidb.GroupFileDeleteReq.encode({ delete: {
				groupCode,
				busId,
				fileId
			} });
			const data = Oidb.Base.encode({
				command: 1750,
				subCommand: 3,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d6_3", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFileDeleteResp.decode(decoded.body);
		}
		/** 移动群文件到另一目录 */
		async moveGroupFile(groupCode, fileId, parentDirectory, targetDirectory) {
			const body = Oidb.GroupFileMoveReq.encode({ move: {
				groupCode,
				appId: 7,
				busId: 102,
				fileId,
				parentDirectory,
				targetDirectory
			} });
			const data = Oidb.Base.encode({
				command: 1750,
				subCommand: 5,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d6_5", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFileMoveResp.decode(decoded.body);
		}
		/** 设置本地群备注（只自己看见，对群成员不可见） */
		async setGroupRemark(groupCode, remark) {
			const body = Oidb.GroupRemarkReq.encode({ body: {
				groupCode,
				targetRemark: remark
			} });
			return await this.sendOidb(3862, 1, body);
		}
		/** 创建群文件夹，rootDirectory 为父目录 id（根目录用 "/"） */
		async createGroupFolder(groupCode, folderName, rootDirectory = "/") {
			const body = Oidb.GroupFolderCreateReq.encode({ create: {
				groupCode,
				rootDirectory,
				folderName
			} });
			const data = Oidb.Base.encode({
				command: 1751,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d7_0", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFolderCreateResp.decode(decoded.body);
		}
		/** 删除群文件夹（一定要空文件夹否则 server 拒绝） */
		async deleteGroupFolder(groupCode, folderId) {
			const body = Oidb.GroupFolderDeleteReq.encode({ delete: {
				groupCode,
				folderId
			} });
			const data = Oidb.Base.encode({
				command: 1751,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d7_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFolderDeleteResp.decode(decoded.body);
		}
		/** 重命名群文件夹 */
		async renameGroupFolder(groupCode, folderId, newFolderName) {
			const body = Oidb.GroupFolderRenameReq.encode({ rename: {
				groupCode,
				folderId,
				newFolderName
			} });
			const data = Oidb.Base.encode({
				command: 1751,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d7_2", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.GroupFolderRenameResp.decode(decoded.body);
		}
		async setGroupPin(groupCode, isPinned) {
			let timestamp;
			if (isPinned) {
				timestamp = Buffer.alloc(4);
				timestamp.writeInt32BE(Math.floor(Date.now() / 1e3), 0);
			} else timestamp = Buffer.alloc(0);
			const body = Oidb.SetGroupPinReq.encode({
				field1: 0,
				field3: 11,
				info: {
					groupCode,
					field400: {
						field1: 13569,
						timestamp
					}
				}
			});
			return await this.sendOidb(1494, 1, body);
		}
		async fetchGroup(groupCode) {
			const body = Oidb.FetchGroupReq.encode({
				random: randomInt(0, 2147483647),
				config: {
					groupCode,
					flags: {
						ownerUid: true,
						groupCreateTime: true,
						maxMemberNum: true,
						memberNum: true,
						groupName: "",
						question: "",
						description: "",
						shutUpMeTimestamp: true,
						richGroupName: ""
					}
				}
			});
			const data = Oidb.Base.encode({
				command: 2189,
				subCommand: 14,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x88d_14", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupResp.decode(oidbRespBody);
		}
		async fetchGroupMembers(groupCode, cookie) {
			const body = Oidb.FetchGroupMembersReq.encode({
				groupCode,
				field2: 5,
				field3: 2,
				body: {
					memberName: true,
					memberCard: true,
					level: true,
					specialTitle: true,
					joinTimestamp: true,
					lastMsgTimestamp: true,
					shutUpTimestamp: true,
					permission: true
				},
				cookie
			});
			const data = Oidb.Base.encode({
				command: 4071,
				subCommand: 3,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xfe7_3", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupMembersResp.decode(oidbRespBody);
		}
		async kickGroupMember(groupCode, kickUids, rejectSubsequentRequests, reason) {
			const body = Oidb.KickMemberReq.encode({
				groupCode,
				kickUids,
				rejectSubsequentRequests,
				reason
			});
			return await this.sendOidb(2208, 1, body);
		}
		async muteGroupMember(groupCode, memList) {
			const body = Oidb.MuteMemberReq.encode({
				groupCode,
				memCount: memList.length,
				memList
			});
			return await this.sendOidb(4691, 1, body);
		}
		async muteAllGroupMembers(groupCode, isMute) {
			const body = Oidb.MuteAllMembersReq.encode({
				groupCode,
				body: { duration: isMute ? 4294967295 : 0 }
			});
			return await this.sendOidb(2202, 0, body);
		}
		async setGroupName(groupCode, name) {
			const body = Oidb.SetGroupNameReq.encode({
				groupCode,
				body: { name }
			});
			return await this.sendOidb(2202, 15, body);
		}
		async setGroupMemberCard(groupCode, memberUid, card) {
			const body = Oidb.SetMemberCardReq.encode({
				groupCode,
				body: [{
					targetUid: memberUid,
					card
				}]
			});
			return await this.sendOidb(2300, 3, body);
		}
		async setGroupMemberAdmin(groupCode, memberUid, isSet) {
			const body = Oidb.SetMemberAdminReq.encode({
				groupCode,
				memberUid,
				isSet
			});
			return await this.sendOidb(4246, 1, body);
		}
		async leaveGroup(groupCode) {
			const body = Oidb.LeaveGroupReq.encode({ groupCode });
			return await this.sendOidb(4247, 1, body);
		}
		/** operation: 1=accept, 2=reject, 3=ignore */
		async handleGroupRequest(sequence, eventType, groupCode, operation, message = "", filtered = false) {
			const body = Oidb.HandleGroupRequestReq.encode({
				operation,
				body: {
					sequence,
					eventType,
					groupCode,
					message
				}
			});
			const subCommand = filtered ? 2 : 1;
			return await this.sendOidb(4296, subCommand, body);
		}
		/** isAdd: true=设精华, false=取消精华 */
		async setGroupEssence(groupCode, msgSequence, msgRandom, isAdd) {
			const body = Oidb.GroupEssenceReq.encode({
				groupCode,
				msgSequence,
				msgRandom
			});
			const subCommand = isAdd ? 1 : 2;
			const data = Oidb.Base.encode({
				command: 3756,
				subCommand,
				body
			});
			const res = await this.sendPB(`OidbSvcTrpcTcp.0xeac_${subCommand}`, data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GroupEssenceResp.decode(oidbRespBody);
		}
		/** type: 1=face(QQ表情)，2=emoji(unicode)。默认按 code 长度推断（≤3 当 face，否则 emoji） */
		async setGroupReaction(groupCode, sequence, code, isAdd, type) {
			const finalType = type ?? (code.length <= 3 ? 1 : 2);
			const body = Oidb.GroupReactionReq.encode({
				groupCode,
				sequence,
				code,
				type: finalType
			});
			const subCommand = isAdd ? 1 : 2;
			return await this.sendOidb(36994, subCommand, body);
		}
		/** filtered: true=拉过滤掉的通知（来自陌生人的入群申请等） */
		async fetchGroupNotifies(count, filtered, startSequence) {
			const body = Oidb.FetchGroupNotifiesReq.encode({
				count,
				startSequence
			});
			const subCommand = filtered ? 2 : 1;
			const data = Oidb.Base.encode({
				command: 4288,
				subCommand,
				body
			});
			const res = await this.sendPB(`OidbSvcTrpcTcp.0x10c0_${subCommand}`, data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupNotifiesResp.decode(oidbRespBody);
		}
		async getGroupRecommendContactArk(groupCode) {
			const body = Oidb.GetGroupRecommendContactArkReq.encode({
				field1: 1,
				groupCode,
				field5: 1
			});
			const data = Oidb.Base.encode({
				command: 2231,
				subCommand: 5,
				body
			});
			const res = await this.sendPB(`OidbSvcTrpcTcp.0x8b7_5`, data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.GetGroupRecommendContactArkResp.decode(oidbRespBody);
		}
		async setGroupMsgMask(groupCode, selfUid, msgMask) {
			const body = Oidb.SetGroupMsgMaskReq.encode({ body: {
				groupCode,
				setting: {
					selfUid,
					msgMask
				},
				field3: 1,
				field4: 2
			} });
			const data = Oidb.Base.encode({
				command: 2688,
				subCommand: 1,
				body
			});
			const res = await this.sendPB(`OidbSvcTrpcTcp.0xa80_1`, data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.SetGroupMsgMaskResp.decode(oidbRespBody);
		}
		async transGroupFile(groupCode, fileId) {
			const body = Oidb.TransGroupFileReq.encode({ body: {
				groupCode,
				busId: 102,
				fileId
			} });
			const data = Oidb.Base.encode({
				command: 1753,
				subCommand: 0,
				body
			});
			const res = await this.sendPB(`OidbSvcTrpcTcp.0x6d9_0`, data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.TransGroupFileResp.decode(oidbRespBody);
		}
		/** 拉群相册列表 (QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.GetAlbumList) */
		async fetchGroupAlbumList(groupCode) {
			const ts = /* @__PURE__ */ new Date();
			const pad = (n, w = 2) => n.toString().padStart(w, "0");
			const sessionId = `_${pad(ts.getMonth() + 1)}${pad(ts.getDate())}${pad(ts.getHours())}${pad(ts.getMinutes())}${pad(ts.getSeconds())}${pad(ts.getMilliseconds(), 3)}_${randomInt(1e4, 99999)}`;
			const reqBytes = Action.GetAlbumListReq.encode({
				field1: 0,
				field2: Buffer.alloc(0),
				field3: Buffer.alloc(0),
				body: {
					groupCode: String(groupCode),
					albumId: Buffer.alloc(0)
				},
				sessionId,
				headers: [{
					name: "fc-appid",
					value: "100"
				}]
			});
			const res = await this.sendPB("QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.GetAlbumList", reqBytes);
			return Action.GetAlbumListResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 重命名群文件 (OidbSvcTrpcTcp.0x6d6_4) */
		async renameGroupFile(groupCode, fileId, parentDirectory, newFileName, busId = 102) {
			const body = Oidb.RenameGroupFileReq.encode({ rename: {
				groupCode,
				busId,
				fileId,
				parentDirectory,
				newFileName
			} });
			const data = Oidb.Base.encode({
				command: 1750,
				subCommand: 4,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d6_4", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.RenameGroupFileResp.decode(decoded.body);
		}
		genQunAlbumSession() {
			const ts = /* @__PURE__ */ new Date();
			const pad = (n, w = 2) => n.toString().padStart(w, "0");
			return `_${pad(ts.getMonth() + 1)}${pad(ts.getDate())}${pad(ts.getHours())}${pad(ts.getMinutes())}${pad(ts.getSeconds())}${pad(ts.getMilliseconds(), 3)}_${randomInt(1e4, 99999)}`;
		}
		/** 创建群相册 (QunAlbum.AddAlbum) */
		async createGroupAlbum(groupCode, name, desc) {
			const reqBytes = Action.AddAlbumReq.encode({
				requestId: randomInt(1, 2147483647),
				field2: Buffer.alloc(0),
				field3: Buffer.alloc(0),
				body: { info: {
					groupCode: String(groupCode),
					name,
					desc,
					field5: 0
				} },
				sessionId: this.genQunAlbumSession(),
				headers: [{
					name: "fc-appid",
					value: "100"
				}]
			});
			const res = await this.sendPB("QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.AddAlbum", reqBytes);
			return Action.AddAlbumResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 删群相册 (QunAlbum.DeleteAlbum) */
		async deleteGroupAlbum(groupCode, albumId) {
			const reqBytes = Action.DeleteAlbumReq.encode({
				requestId: randomInt(1, 2147483647),
				field2: Buffer.alloc(0),
				field3: Buffer.alloc(0),
				body: {
					groupCode: String(groupCode),
					albumId
				},
				sessionId: this.genQunAlbumSession(),
				headers: [{
					name: "fc-appid",
					value: "100"
				}]
			});
			const res = await this.sendPB("QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.DeleteAlbum", reqBytes);
			return Action.DeleteAlbumResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 拉群相册媒体列表 (QunAlbum.GetMediaList) */
		async fetchGroupAlbumMediaList(groupCode, albumId, attachInfo) {
			const reqBytes = Action.GetMediaListReq.encode({
				field1: 0,
				field2: Buffer.alloc(0),
				field3: Buffer.alloc(0),
				body: {
					groupCode: String(groupCode),
					albumId,
					field3: 0,
					field4: Buffer.alloc(0),
					attachInfo
				},
				sessionId: this.genQunAlbumSession(),
				headers: [{
					name: "fc-appid",
					value: "100"
				}]
			});
			const res = await this.sendPB("QunAlbum.trpc.qzone.webapp_qun_media.QunMedia.GetMediaList", reqBytes);
			return Action.GetMediaListResp.decode(Buffer.from(res.pb, "hex"));
		}
		async fetchGroupAtAllRemain(uin, groupCode) {
			const body = Oidb.FetchGroupAtAllRemainReq.encode({
				subCmd: 1,
				limitIntervalTypeForUin: 2,
				limitIntervalTypeForGroup: 1,
				uin,
				groupCode
			});
			const data = Oidb.Base.encode({
				command: 2215,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x8a7_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupAtAllRemainResp.decode(oidbRespBody);
		}
		async fetchGroupExtra(groupCode) {
			const body = Oidb.FetchGroupExtraReq.encode({
				random: randomInt(0, 2147483647),
				config: {
					groupCode,
					flags: { latestMessageSeq: true }
				}
			});
			const data = Oidb.Base.encode({
				command: 2189,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x88d_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchGroupExtraResp.decode(oidbRespBody);
		}
		async forwardGroupFile(groupCode, dstUin, fileId, busId, toFriend) {
			const body = Oidb.ForwardGroupFileReq.encode({ copyToReq: {
				groupCode,
				appId: 1,
				srcBusId: busId,
				srcFileId: fileId,
				dstBusId: toFriend ? 3 : 102,
				dstUin
			} });
			const data = Oidb.Base.encode({
				command: 1753,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d9_2", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.ForwardGroupFileResp.decode(decoded.body);
		}
	}
	return Mixed;
}
//#endregion
//#region src/ntqqapi/helper/ntv2RichMedia.ts
var NTV2RichMedia;
(function(_NTV2RichMedia) {
	async function buildUploadReq(peer, entity, ext, subFileInfos = []) {
		let requestType, businessType;
		if (entity.type === "video") {
			requestType = 2;
			businessType = 2;
		} else if (entity.type === "image") {
			requestType = 2;
			businessType = 1;
		} else if (entity.type === "voice") {
			requestType = 2;
			businessType = 3;
		}
		const isGroup = peer.chatType === ChatType.Group;
		return Media.NTV2RichMediaReq.encode({
			reqHead: {
				common: {
					requestId: 1,
					command: 100
				},
				scene: {
					requestType,
					businessType,
					sceneType: isGroup ? 2 : 1,
					c2c: !isGroup ? {
						accountType: 2,
						targetUid: peer.peerUid,
						tmpInfo: peer.chatType === ChatType.TempC2CFromGroup ? { body: { targetUid: peer.peerUid } } : void 0
					} : void 0,
					group: isGroup ? { groupId: +peer.peerUid } : void 0
				},
				client: { agentType: 2 }
			},
			upload: {
				uploadInfo: [{
					fileInfo: await buildFileInfo(entity),
					subFileType: 0
				}, ...await Promise.all(subFileInfos.map(async ([subFileType, subEntity]) => ({
					fileInfo: await buildFileInfo(subEntity),
					subFileType
				})))],
				tryFastUploadCompleted: true,
				srvSendMsg: false,
				clientRandomId: randomInt(0, 2147483647),
				compatQMsgSceneType: isGroup ? 2 : 1,
				clientSeq: 10,
				extBizInfo: ext,
				noNeedCompatMsg: false
			}
		});
	}
	_NTV2RichMedia.buildUploadReq = buildUploadReq;
	async function buildFileInfo(entity) {
		const md5HexStr = await getMd5HexFromFile(entity.filePath);
		const sha1HexStr = await getSha1HexFromFile(entity.filePath);
		const { size: fileSize } = await stat$1(entity.filePath);
		let fileName, fileType, width, height, time, original;
		if (entity.type === "video") {
			fileName = `${md5HexStr}.mp4`;
			fileType = { type: 2 };
			time = entity.duration ?? 0;
			width = entity.width ?? 0;
			height = entity.height ?? 0;
		} else if (entity.type === "image") {
			const { ext } = await getFileType(entity.filePath);
			fileName = `${md5HexStr}.${ext}`;
			fileType = {
				type: 1,
				picFormat: ext === "gif" ? 2e3 : 1e3
			};
			width = entity.width ?? 0;
			height = entity.height ?? 0;
			original = 1;
		} else if (entity.type === "voice") {
			fileName = `${md5HexStr}.amr`;
			fileType = {
				type: 3,
				pttFormat: 1
			};
			time = entity.duration ?? 1;
			original = 1;
		}
		return {
			fileSize,
			md5HexStr,
			sha1HexStr,
			fileName,
			fileType,
			width,
			height,
			time,
			original
		};
	}
	function generateExt(upload, subFileInfo) {
		const blockSize = 1048576;
		const msgInfoStruct = Media.MsgInfo.decode(upload.msgInfo);
		const head = msgInfoStruct.msgInfoBody[0];
		if (!head?.index) throw new Error(`NTV2 generateExt: server response 缺少 msgInfoBody[0].index，无法生成 highway ext (uKey=${upload.uKey ?? "?"}, msgInfoBody.length=${msgInfoStruct.msgInfoBody?.length ?? 0})`);
		const index = head.index;
		const initialSha1 = index.info?.sha1HexStr ? [Buffer.from(index.info.sha1HexStr, "hex")] : [Buffer.alloc(0)];
		if (subFileInfo) {
			const subIndex = msgInfoStruct.msgInfoBody[1]?.index;
			const subInitialSha1 = subIndex?.info?.sha1HexStr ? [Buffer.from(subIndex.info.sha1HexStr, "hex")] : initialSha1;
			return {
				fileUuid: index.fileUuid,
				uKey: subFileInfo.uKey,
				network: convertIPv4(subFileInfo.ipv4s),
				msgInfoBody: msgInfoStruct.msgInfoBody,
				blockSize,
				hash: { fileSha1: subInitialSha1 }
			};
		} else return {
			fileUuid: index.fileUuid,
			uKey: upload.uKey,
			network: convertIPv4(upload.ipv4s),
			msgInfoBody: msgInfoStruct.msgInfoBody,
			blockSize,
			hash: { fileSha1: initialSha1 }
		};
	}
	_NTV2RichMedia.generateExt = generateExt;
	function convertIPv4(ipv4s) {
		return { ipv4s: ipv4s.map((ipv4) => ({
			domain: {
				isEnable: true,
				ip: uint32ToIPV4Addr(ipv4.outIP)
			},
			port: ipv4.outPort
		})) };
	}
})(NTV2RichMedia || (NTV2RichMedia = {}));
//#endregion
//#region src/main/qqProtocol/mixins/media.ts
function MediaMixin(Base) {
	class Mixed extends Base {
		async getRKey() {
			const data = Buffer.from("08e7a00210ca01221c0a130a05080110ca011206a80602b006011a02080122050a030a1400", "hex");
			const resp = await this.sendPB("OidbSvcTrpcTcp.0x9067_202", data);
			const rkeyBody = Oidb.Base.decode(Buffer.from(resp.pb, "hex")).body;
			return Oidb.GetRKeyResp.decode(rkeyBody);
		}
		async getPrivatePttUrl(fileUuid) {
			const body = Media.NTV2RichMediaReq.encode({
				reqHead: {
					common: {
						requestId: 1,
						command: 200
					},
					scene: {
						requestType: 1,
						businessType: 3,
						field103: 0,
						sceneType: 1,
						c2c: {
							accountType: 2,
							targetUid: selfInfo.uid
						}
					},
					client: { agentType: 2 }
				},
				download: { node: {
					fileUuid,
					storeID: 1,
					uploadTime: 0,
					expire: 0,
					type: 0
				} }
			});
			const data = Oidb.Base.encode({
				command: 4717,
				subCommand: 200,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x126d_200", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Media.NTV2RichMediaResp.decode(oidbRespBody);
		}
		async getGroupPttUrl(fileUuid) {
			const body = Media.NTV2RichMediaReq.encode({
				reqHead: {
					common: {
						requestId: 1,
						command: 200
					},
					scene: {
						requestType: 1,
						businessType: 3,
						field103: 0,
						sceneType: 2,
						group: { groupId: 0 }
					},
					client: { agentType: 2 }
				},
				download: { node: {
					fileUuid,
					storeID: 1,
					uploadTime: 0,
					expire: 0,
					type: 0
				} }
			});
			const data = Oidb.Base.encode({
				command: 4718,
				subCommand: 200,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x126e_200", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Media.NTV2RichMediaResp.decode(oidbRespBody);
		}
		async getGroupVideoUrl(fileUuid) {
			const body = Media.NTV2RichMediaReq.encode({
				reqHead: {
					common: {
						requestId: 1,
						command: 200
					},
					scene: {
						requestType: 2,
						businessType: 2,
						field103: 0,
						sceneType: 2,
						group: { groupId: 0 }
					},
					client: { agentType: 2 }
				},
				download: { node: {
					fileUuid,
					storeID: 1,
					uploadTime: 0,
					expire: 0,
					type: 0
				} }
			});
			const data = Oidb.Base.encode({
				command: 4586,
				subCommand: 200,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11ea_200", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Media.NTV2RichMediaResp.decode(oidbRespBody);
		}
		async getPrivateVideoUrl(fileUuid) {
			const body = Media.NTV2RichMediaReq.encode({
				reqHead: {
					common: {
						requestId: 1,
						command: 200
					},
					scene: {
						requestType: 2,
						businessType: 2,
						field103: 0,
						sceneType: 1,
						c2c: {
							accountType: 2,
							targetUid: selfInfo.uid
						}
					},
					client: { agentType: 2 }
				},
				download: { node: {
					fileUuid,
					storeID: 1,
					uploadTime: 0,
					expire: 0,
					type: 0
				} }
			});
			const data = Oidb.Base.encode({
				command: 4585,
				subCommand: 200,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11e9_200", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Media.NTV2RichMediaResp.decode(oidbRespBody);
		}
		async getHighwaySession() {
			const data = Media.HighwaySessionReq.encode({ reqBody: {
				uin: 0,
				idcId: 0,
				appid: 16,
				loginSigType: 1,
				requestFlag: 3,
				serviceTypes: [
					1,
					5,
					10,
					21
				],
				field9: 2,
				field10: 9,
				field11: 8,
				version: "1.0.1"
			} });
			const res = await this.sendPB("HttpConn.0x6ff_501", data);
			const { rspBody } = Media.HighwaySessionResp.decode(Buffer.from(res.pb, "hex"));
			const highwayHostAndPorts = {};
			for (const srvAddr of rspBody.addrs) {
				const addresses = [];
				for (const addr of srvAddr.addrs) {
					const ip = uint32ToIPV4Addr(addr.ip);
					const port = addr.port;
					addresses.push(`${ip}:${port}`);
				}
				highwayHostAndPorts[srvAddr.serviceType] = addresses;
			}
			return {
				highwayHostAndPorts,
				sigSession: rspBody.sigSession
			};
		}
		async notifyGroupVideoUploadCompleted(groupCode, msgInfoBytes, clientRandomId) {
			const body = Media.NTV2RichMediaReq.encode({
				reqHead: {
					common: {
						requestId: 1,
						command: 100
					},
					scene: {
						requestType: 2,
						businessType: 2,
						sceneType: 2,
						group: { groupId: +groupCode }
					},
					client: { agentType: 2 }
				},
				uploadCompleted: {
					srvSendMsg: false,
					clientRandomId: BigInt(clientRandomId),
					msgInfo: msgInfoBytes,
					clientSeq: 0
				}
			});
			const data = Oidb.Base.encode({
				command: 4586,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11ea_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Media.NTV2RichMediaResp.decode(oidbRespBody);
		}
		async getGroupVideoUploadInfo(groupCode, filePath, thumbFilePath, duration, width, height) {
			const peer = {
				chatType: ChatType.Group,
				peerUid: groupCode,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "video",
				filePath,
				duration,
				width,
				height
			}, { video: { pbReserve: Buffer.from([
				128,
				1,
				0
			]) } }, [[100, {
				type: "image",
				filePath: thumbFilePath,
				width,
				height
			}]]);
			const data = Oidb.Base.encode({
				command: 4586,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11ea_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload),
				subExt: NTV2RichMedia.generateExt(upload, upload.subFileInfos[0])
			};
		}
		async getC2CVideoUploadInfo(chatType, peerUid, filePath, thumbFilePath, duration, width, height) {
			const peer = {
				chatType,
				peerUid,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "video",
				filePath,
				duration,
				width,
				height
			}, { video: { pbReserve: Buffer.from([
				128,
				1,
				0
			]) } }, [[100, {
				type: "image",
				filePath: thumbFilePath,
				width,
				height
			}]]);
			const data = Oidb.Base.encode({
				command: 4585,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11e9_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload),
				subExt: NTV2RichMedia.generateExt(upload, upload.subFileInfos[0])
			};
		}
		async getGroupFileUploadInfo(groupCode, filePath, fileName, parentFolderId, busId) {
			const fileSize = (await stat$2(filePath)).size;
			const md5 = await getMd5BufferFromFile(filePath);
			const body = Oidb.GroupFileReq.encode({ uploadFileReq: {
				groupCode,
				appId: 7,
				busId,
				entrance: 6,
				parentFolderId,
				fileName,
				localPath: `/${fileName}`,
				fileSize,
				sha: await getSha1BufferFromFile(filePath),
				md5
			} });
			const data = Oidb.Base.encode({
				command: 1750,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x6d6_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { uploadFileRsp } = Oidb.GroupFileResp.decode(oidbRespBody);
			return {
				...uploadFileRsp,
				fileSize,
				md5
			};
		}
		async getC2CFileUploadInfo(chatType, peerUid, filePath, fileName) {
			const fileSize = (await stat$2(filePath)).size;
			const md510MCheckSum = await readAndHash10M(filePath);
			const sha1CheckSum = await getSha1BufferFromFile(filePath);
			const md5CheckSum = await getMd5BufferFromFile(filePath);
			const sha3CheckSum = await calculateTriSha1(filePath, fileSize);
			const body = Oidb.OfflineFileUploadReq.encode({
				command: 1700,
				seq: 0,
				upload: {
					senderUid: selfInfo.uid,
					receiverUid: peerUid,
					fileSize,
					fileName,
					md510MCheckSum,
					sha1CheckSum,
					localPath: "/",
					md5CheckSum,
					sha3CheckSum
				},
				businessId: 3,
				clientType: 1,
				flagSupportMediaPlatform: 1
			});
			const data = Oidb.Base.encode({
				command: 3639,
				subCommand: 1700,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xe37_1700", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Oidb.OfflineFileUploadResp.decode(oidbRespBody);
			return {
				isExist: upload.fileExist,
				fileId: upload.uuid,
				uploadKey: upload.mediaPlatformUploadKey,
				rtpMediaPlatformUploadAddress: upload.rtpMediaPlatformUploadAddress.map((addr) => [uint32ToIPV4Addr(addr.innerIp), addr.innerPort]),
				crcMedia: upload.fileIdCrc,
				fileSize,
				md510MCheckSum,
				sha1CheckSum,
				md5CheckSum,
				sha3CheckSum
			};
		}
		async getGroupImageUploadInfo(groupCode, filePath, width, height, summary, bizType) {
			const peer = {
				chatType: ChatType.Group,
				peerUid: groupCode,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "image",
				filePath,
				width,
				height
			}, { pic: {
				bizType,
				summary
			} });
			const data = Oidb.Base.encode({
				command: 4548,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11c4_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload)
			};
		}
		async getC2CImageUploadInfo(chatType, peerUid, filePath, width, height, summary, bizType) {
			const peer = {
				chatType,
				peerUid,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "image",
				filePath,
				width,
				height
			}, { pic: {
				bizType,
				summary
			} });
			const data = Oidb.Base.encode({
				command: 4549,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x11c5_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload)
			};
		}
		async getGroupPttUploadInfo(groupCode, filePath, duration) {
			const peer = {
				chatType: ChatType.Group,
				peerUid: groupCode,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "voice",
				filePath,
				duration
			}, { ptt: {
				bytesPbReserve: Buffer.from([
					8,
					0,
					56,
					0
				]),
				bytesGeneralFlags: Buffer.from([
					154,
					1,
					7,
					170,
					3,
					4,
					8,
					8,
					18,
					0
				])
			} });
			const data = Oidb.Base.encode({
				command: 4718,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x126e_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload)
			};
		}
		async getC2CPttUploadInfo(chatType, peerUid, filePath, duration) {
			const peer = {
				chatType,
				peerUid,
				guildId: ""
			};
			const body = await NTV2RichMedia.buildUploadReq(peer, {
				type: "voice",
				filePath,
				duration
			}, { ptt: {
				bytesPbReserve: Buffer.from([
					8,
					0,
					56,
					0
				]),
				bytesGeneralFlags: Buffer.from([
					154,
					1,
					7,
					170,
					3,
					4,
					8,
					8,
					18,
					0
				])
			} });
			const data = Oidb.Base.encode({
				command: 4717,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x126d_100", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			const { upload } = Media.NTV2RichMediaResp.decode(oidbRespBody);
			return {
				info: upload.msgInfo,
				compat: upload.compatQMsg,
				ext: NTV2RichMedia.generateExt(upload)
			};
		}
		async imageOcr(imageUrl) {
			const body = Oidb.ImageOcrReq.encode({
				version: 1,
				client: 0,
				entrance: 1,
				ocrReqBody: {
					imageUrl,
					originMd5: "",
					afterCompressMd5: "",
					afterCompressFileSize: "",
					afterCompressWeight: "",
					afterCompressHeight: "",
					isCut: false
				}
			});
			const data = Oidb.Base.encode({
				command: 3591,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xe07_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.ImageOcrResp.decode(oidbRespBody);
		}
		/** 闪传：通过 share code 解析 fileSetId (OidbSvcTrpcTcp.0x93eb_1) */
		async getFlashFileSetIdByCode(code) {
			const body = Oidb.FlashFileSetIdByCodeReq.encode({ code });
			const data = Oidb.Base.encode({
				command: 37867,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93eb_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`getFlashFileSetIdByCode failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return Oidb.FlashFileSetIdByCodeResp.decode(Buffer.from(decoded.body)).fileSetId ?? "";
		}
		/** 闪传：取 fileSet 基本信息 (OidbSvcTrpcTcp.0x93d3_1)。
		* field2 = 7 对应 Windows QQ 重新分享时的 send (1 是早期值，对自己 fileset 拿的字段更少)。 */
		async getFlashFileInfo(fileSetId) {
			const body = Oidb.FlashFileInfoReq.encode({
				fileSetId,
				field2: 7
			});
			const data = Oidb.Base.encode({
				command: 37843,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93d3_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`getFlashFileInfo failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return Oidb.FlashFileInfoResp.decode(Buffer.from(decoded.body)).info;
		}
		/** 闪传：取 fileSet 中文件列表 (OidbSvcTrpcTcp.0x93d4_1) */
		async getFlashFileList(fileSetId) {
			const body = Oidb.FlashFileListReq.encode({
				fileSetId,
				paging: {
					cookie: Buffer.alloc(0),
					field2: 1,
					count: 18,
					field4: Buffer.alloc(0),
					flags1: { field1: 0 },
					flags2: {
						field1: 0,
						field2: 0
					}
				},
				field3: 2,
				field4: 1
			});
			const data = Oidb.Base.encode({
				command: 37844,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93d4_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`getFlashFileList failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return Oidb.FlashFileListResp.decode(Buffer.from(decoded.body)).result?.files ?? [];
		}
		/** 闪传：取单个老文件的完整元数据 (OidbSvcTrpcTcp.0x93e5_4)。
		* 跟 list (0x93d4_1) 不同——对 bot 自己 own 的 fileSet 也能拿到 sha1/md5/historyToken，
		* 没有 list 的 ownership 限制。是 Windows QQ "重新分享" 按钮的第一步。 */
		async getFlashFileEntryFull(fileSetId, fileUuid) {
			const body = Oidb.FlashFileGetFileInfoReq.encode({
				fileUuid,
				fileSetId,
				field3: 1
			});
			const data = Oidb.Base.encode({
				command: 37861,
				subCommand: 4,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93e5_4", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`getFlashFileEntryFull failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return Oidb.FlashFileGetFileInfoResp.decode(Buffer.from(decoded.body)).wrap?.file;
		}
		/** 闪传：finalize fileSet 状态 (OidbSvcTrpcTcp.0x93d1_1)。
		* 名字看起来像 download，但抓包看 Windows QQ 是 commit 后用它 finalize fileset。
		* sceneType=6 是 finalize；上传完成必调，跟齐 Windows QQ 客户端流程。 */
		async downloadFlashFile(fileSetId, sceneType = 6) {
			const body = Oidb.FlashFileDownloadReq.encode({
				fileSetId,
				sceneType
			});
			const data = Oidb.Base.encode({
				command: 37841,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93d1_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`downloadFlashFile failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return { result: 0 };
		}
		/** 闪传：创建 fileSet 并拿到 shareLink (OidbSvcTrpcTcp.0x93cf_1)。
		* 这只是 uploadFlashFile 多步流程的第一步——还需 0x93d0_1 注册文件 + 0x93db_1 prep
		* + 0x12a9_100/103 highway 上传 + 0x93d1_1 finalize 才能把实际文件放进 fileSet。
		*
		* field3 = 20 (普通上传)，21 (Windows QQ 重新分享场景；实测对 server 行为无区别)。
		* 用 1 server 直接拒 errorCode=100000 "加载失败，请稍后重试"。 */
		async createFlashFileSet(opts) {
			const body = Oidb.CreateFlashFileSetReq.encode({
				totalFileCount: opts.totalFileCount,
				meta: {
					title: opts.title,
					subtitle: opts.subtitle ?? opts.title,
					field4: 1,
					totalFileSize: opts.totalFileSize,
					uploader: {
						uin: opts.uploaderUin,
						nickname: opts.uploaderNick,
						uid: opts.uploaderUid,
						field4: Buffer.alloc(0)
					},
					field16: 1,
					field20: 0,
					field21: 0,
					field23: 0,
					field24: {
						field2: 0,
						field3: Buffer.alloc(0)
					}
				},
				field3: opts.scene ?? 20
			});
			const data = Oidb.Base.encode({
				command: 37839,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93cf_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`createFlashFileSet failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return Oidb.CreateFlashFileSetResp.decode(Buffer.from(decoded.body));
		}
		/** 闪传：登记单个文件元数据 (OidbSvcTrpcTcp.0x93d0_1) */
		async registerFlashFile(fileSetId, file) {
			const body = Oidb.RegisterFlashFileReq.encode({
				field1: 1,
				fileSetId,
				fileSetIdEcho: fileSetId,
				file: {
					fileSetId,
					fileUuid: file.fileUuid,
					field3: 0,
					field4: Buffer.alloc(0),
					field5: 1,
					field6: 1,
					field7: 11,
					name: file.name,
					name2: file.name,
					field10: 0,
					fileSize: file.fileSize,
					field12: 0,
					sha1Hex: file.sha1Hex,
					field24: Buffer.alloc(0),
					md5Hex: file.md5Hex
				},
				field5: 1,
				field6: 1
			});
			const data = Oidb.Base.encode({
				command: 37840,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93d0_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`registerFlashFile failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return { result: 0 };
		}
		/** 闪传：fileSet upload prep (OidbSvcTrpcTcp.0x93db_1) */
		async prepFlashFileSet(fileSetId) {
			const body = Oidb.PrepFlashFileSetReq.encode({
				fileSetId,
				field2: Buffer.alloc(0)
			});
			const data = Oidb.Base.encode({
				command: 37851,
				subCommand: 1,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x93db_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`prepFlashFileSet failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return { result: 0 };
		}
		/** 闪传：upload preflight (OidbSvcTrpcTcp.0x12a9_100)。
		* 若 server 已有同 sha1 的文件则返回成功（秒传），否则返回 highway uKey+IPs。
		* 当前实现只支持秒传命中场景；返回 highway 信息时 caller 需要调用 highway 上传。
		* field103: LLBot 实际会做两遍 preflight+commit，第一遍 24（图像类），第二遍 22（通用）。 */
		async flashFileUploadPreflight(opts) {
			const body = Oidb.FlashFileUploadPreReq.encode({
				head: {
					common: {
						requestId: opts.requestId,
						command: 100
					},
					scene: {
						requestType: 2,
						businessType: 4,
						field103: opts.field103 ?? 22,
						sceneType: 5
					},
					client: { agentType: 1 }
				},
				upload: {
					uploadInfo: {
						fileInfo: {
							fileSize: opts.fileSize,
							md5: Buffer.alloc(0),
							sha1: opts.sha1Hex,
							name: opts.name,
							fileType: {
								field1: 0,
								field2: 0,
								field3: 0,
								field4: 0
							},
							width: 0,
							height: 0,
							field8: 0,
							field9: 1
						},
						subFileType: 0
					},
					tryFastUploadCompleted: true,
					srvSendMsg: false,
					clientRandomId: 0,
					compatQMsgSceneType: 0,
					extBizInfo: { field1: {
						field1: 0,
						field2: Buffer.alloc(0)
					} }
				}
			});
			const data = Oidb.Base.encode({
				command: 4777,
				subCommand: 100,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x12a9_100", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`flashFileUploadPreflight failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			const resp = Oidb.FlashFileUploadResp.decode(Buffer.from(decoded.body));
			const summary = resp.body?.fastUploadInfo?.summary?.fileSummary;
			return {
				retCode: resp.head?.retCode ?? "",
				uKey: resp.body?.uKey ?? "",
				token: summary?.token ?? "",
				time: summary?.time ?? 0,
				ttl: summary?.ttl ?? 0
			};
		}
		/** 闪传：upload commit (OidbSvcTrpcTcp.0x12a9_103) — 在 preflight 秒传命中后立即调用。
		* fileSetId + fileUuid 必传——这是告诉 server 这次 commit 属于哪个 fileset 的哪个文件。
		* 漏了这俩 server 表面返 success 但实际不把文件挂到 fileset 上，fileset 卡在"待上传"。 */
		async flashFileUploadCommit(opts) {
			const body = Oidb.FlashFileUploadCommitReq.encode({
				head: {
					common: {
						requestId: opts.requestId,
						command: 103
					},
					scene: {
						requestType: 2,
						businessType: 4,
						field103: opts.field103 ?? 22,
						sceneType: 5
					},
					client: { agentType: 1 }
				},
				commit: {
					fileSummary: {
						fileInfo: {
							fileSize: opts.fileSize,
							md5: Buffer.alloc(0),
							sha1: opts.sha1Hex,
							name: opts.name,
							fileType: {
								field1: 0,
								field2: 0,
								field3: 0,
								field4: 0
							},
							width: 0,
							height: 0,
							field8: 0,
							field9: 1
						},
						token: opts.token,
						field3: 1,
						time: opts.time,
						ttl: opts.ttl,
						field6: 0
					},
					field2: { field1: 2 },
					field3: {
						field1: 0,
						field2: 0
					},
					target: {
						fileSetId: opts.fileSetId,
						fileSetId2: opts.fileSetId,
						fileUuid: opts.fileUuid,
						field4: 1,
						field5: 0,
						field6: 0,
						fileTypeFlag: opts.fileTypeFlag ?? 11,
						field8: Buffer.alloc(0),
						field9: 0,
						field10: 0,
						field11: 0,
						field12: 0,
						field13: 0,
						field14: 0
					}
				}
			});
			const data = Oidb.Base.encode({
				command: 4777,
				subCommand: 103,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x12a9_103", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`flashFileUploadCommit failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			return { result: 0 };
		}
		/** 闪传：拿单个文件的下载 URL (OidbSvcTrpcTcp.0x12a9_200)。
		* 流程：fileSetId → getFlashFileList 拿到 file 的 fileUuid/sha1/name → 这里换 HTTPS URL。
		* server 用 (fileSetId, fileUuid) 真正定位文件（download.info.fileId 是历史 token，不传也行）。
		* 上层用 `https://${host}${path}${rkey}` 直接下载（rkey 已经带 & 前缀）。 */
		async flashFileDownloadUrl(opts) {
			const body = Oidb.FlashFileDownloadPreReq.encode({
				head: {
					common: {
						requestId: opts.requestId,
						command: 200
					},
					scene: {
						requestType: 2,
						businessType: 4,
						field103: 22,
						sceneType: 5
					},
					client: { agentType: 1 }
				},
				download: {
					info: {
						fileInfo: {
							fileSize: opts.fileSize ?? 0,
							md5: opts.fileMd5 ?? Buffer.alloc(0),
							sha1: opts.fileSha1 ?? Buffer.alloc(0),
							name: opts.fileName,
							fileType: {
								field1: 0,
								field2: 0,
								field3: 0,
								field4: 0
							},
							width: 0,
							height: 0,
							field8: 0,
							field9: 0
						},
						fileId: opts.fileId ?? "",
						field3: 0,
						field4: 0,
						field5: 0,
						field6: 0
					},
					clientCaps: {
						capsBody: {
							field1: 4294967294,
							field3: 4294967295,
							field5: 111,
							field6: {
								field1: 3409274228,
								field2: Buffer.alloc(0),
								field3: Buffer.alloc(0),
								field4: 0
							}
						},
						smallFlag: { field1: 0 },
						target: {
							fileSetId: opts.fileSetId,
							fileUuid: opts.fileUuid,
							field3: opts.fileTypeFlag ?? 11,
							fileUuid2: opts.fileUuid
						}
					},
					field3: 0
				}
			});
			const data = Oidb.Base.encode({
				command: 4777,
				subCommand: 200,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x12a9_200", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			if (decoded.errorCode !== 0) throw new Error(`flashFileDownloadUrl failed: errorCode=${decoded.errorCode}, errorMsg="${decoded.errorMsg}"`);
			const resp = Oidb.FlashFileDownloadPreResp.decode(Buffer.from(decoded.body));
			const u = resp.body?.url;
			if (!u || !u.host) throw new Error("flashFileDownloadUrl: server did not return URL");
			const fullUrl = `https://${u.host}${u.path}${resp.body.rkey ?? ""}`;
			return {
				host: u.host,
				path: u.path,
				port: u.port,
				rkey: resp.body.rkey ?? "",
				ttl: resp.body.ttl ?? 0,
				fullUrl
			};
		}
	}
	return Mixed;
}
//#endregion
//#region src/main/qqProtocol/mixins/message.ts
function MessageMixin(Base) {
	class Mixed extends Base {
		async uploadForward(peerUid, isGroup, items) {
			const transmit = Msg.PbMultiMsgTransmit.encode({ pbItemList: items });
			const data = Action.SendLongMsgReq.encode({
				info: {
					type: isGroup ? 3 : 1,
					peer: { uid: isGroup ? peerUid : selfInfo.uid },
					groupCode: isGroup ? +peerUid : 0,
					payload: gzipSync(transmit)
				},
				settings: {
					field1: 4,
					field2: 1,
					field3: 7,
					field4: 0
				}
			});
			const res = await this.sendPB("trpc.group.long_msg_interface.MsgService.SsoSendLongMsg", data);
			return Action.SendLongMsgResp.decode(Buffer.from(res.pb, "hex"));
		}
		async getMultiMsg(resId) {
			const data = Action.RecvLongMsgReq.encode({
				info: {
					peer: { uid: selfInfo.uid },
					resId,
					acquire: true
				},
				settings: {
					field1: 2,
					field2: 0,
					field3: 0,
					field4: 0
				}
			});
			const res = await this.sendPB("trpc.group.long_msg_interface.MsgService.SsoRecvLongMsg", data);
			const payload = Action.RecvLongMsgResp.decode(Buffer.from(res.pb, "hex")).result.payload;
			const inflate = gunzipSync(payload);
			return Msg.PbMultiMsgTransmit.decode(inflate);
		}
		async pullPics(word) {
			const data = Action.PullPicsReq.encode({
				uin: +selfInfo.uin,
				field3: 1,
				word,
				word2: word,
				field8: 0,
				field9: 0,
				field14: 1
			});
			const res = await this.sendPB("PicSearchSvr.PullPics", data);
			return Action.PullPicsResp.decode(Buffer.from(res.pb, "hex"));
		}
		async fetchAiCharacterList(groupId, chatType) {
			const body = Oidb.FetchAiCharacterListReq.encode({
				groupId,
				chatType
			});
			const data = Oidb.Base.encode({
				command: 37533,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x929d_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchAiCharacterListResp.decode(oidbRespBody);
		}
		async getGroupGenerateAiRecord(groupId, character, text, chatType) {
			const msgRandom = randomBytes(4).readUInt32BE(0);
			const body = Oidb.GetGroupGenerateAiRecordReq.encode({
				groupId,
				voiceId: character,
				text,
				chatType,
				clientMsgInfo: { msgRandom }
			});
			const data = Oidb.Base.encode({
				command: 37531,
				subCommand: 0,
				body
			});
			await this.sendPB("OidbSvcTrpcTcp.0x929b_0", data);
			return { msgRandom };
		}
		/** 拉群历史消息（按 seq 范围）。返回 Msg.Message 解码后的对象列表（routingHead/contentHead/body） */
		async getGroupMessages(groupCode, startSequence, endSequence) {
			const data = Action.SsoGetGroupMsgReq.encode({
				groupInfo: {
					groupCode,
					startSequence,
					endSequence
				},
				filter: 1
			});
			const res = await this.sendPB("trpc.msg.register_proxy.RegisterProxy.SsoGetGroupMsg", data);
			return Action.SsoGetGroupMsgResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 拉私聊历史消息（按 seq 范围） */
		async getC2CMessages(peerUid, startSequence, endSequence) {
			const data = Action.SsoGetC2CMsgReq.encode({
				peerUid,
				startSequence,
				endSequence
			});
			const res = await this.sendPB("trpc.msg.register_proxy.RegisterProxy.SsoGetC2cMsg", data);
			return Action.SsoGetC2CMsgResp.decode(Buffer.from(res.pb, "hex"));
		}
		/**
		* 拉私聊漫游消息（按时间）。SsoGetC2CMsg 必须传 seq，不知道 seq 时走这个：
		*   time=now、direction=1（"向上滚 = 看更早的"）即可拿到"最新 N 条"。
		* count 上限 30。
		* 拿"绝对最新 N 条"建议传 time=0xFFFFFFFA（远未来）避开本地时钟漂移与 TOCTOU。
		*/
		async getC2CRoamMessages(peerUid, time, count, direction = 1) {
			const data = Action.SsoGetRoamMsgReq.encode({
				peerUid,
				time,
				random: 0,
				count: Math.min(count, 30),
				direction
			});
			const res = await this.sendPB("trpc.msg.register_proxy.RegisterProxy.SsoGetRoamMsg", data);
			return Action.SsoGetRoamMsgResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 撤回群消息 */
		async recallGroupMessage(groupCode, sequence) {
			const data = Action.SsoGroupRecallMsgReq.encode({
				type: 1,
				groupCode,
				info: { sequence }
			});
			await this.sendPB("trpc.msg.msg_svc.MsgService.SsoGroupRecallMsg", data);
		}
		/**
		* 群语音转文字（提交请求）。服务端立即返回 ack；转写文字通过 MsgPush msgType=528 subType=61 异步推回。
		* 调用方负责监听 `nt/ptt-trans-result` 事件，按 msgUid 匹配。
		*/
		async pttTransGroupReq(opts) {
			const data = Msg.PttTransGroupReq.encode({
				field1: 1,
				body: {
					msgUid: opts.msgUid,
					senderUin: opts.senderUin,
					groupUin: opts.groupUin,
					field4: 0,
					voiceMd5Hex: opts.voiceMd5Hex,
					field6: 3,
					field7: 5142,
					field8: 1,
					voiceFileId: opts.voiceFileId,
					field10: 0
				},
				field5: 1,
				field6: 1,
				field10: 0
			});
			await this.sendPB("pttTrans.TransGroupPttReq", data);
		}
		/** 私聊语音转文字。结果同样走 MsgPush msgType=528 subType=61。 */
		async pttTransC2CReq(opts) {
			const data = Msg.PttTransC2CReq.encode({
				field1: 2,
				body: {
					msgUid: opts.msgUid,
					senderUin: opts.senderUin,
					receiverUin: opts.receiverUin,
					voiceFileId: opts.voiceFileId,
					field5: 7,
					field6: 14144,
					field7: 1,
					field8: 0,
					voiceMd5Hex: opts.voiceMd5Hex
				},
				field5: 1,
				field6: 1,
				field10: 0
			});
			await this.sendPB("pttTrans.TransC2CPttReq", data);
		}
		/** 收藏表情列表（Faceroam.OpReq subCmd=1）。返回每个表情的 emoji_id（含 md5）+ bid + 配额。 */
		async listFavEmojis() {
			const data = Msg.FaceroamOpReq.encode({
				comm: {
					imPlat: 1,
					osVersion: DeviceInfo.osVer,
					qVersion: AppInfo.currentVersion
				},
				selfUin: BigInt(selfInfo.uin),
				subCmd: 1,
				field6: 1
			});
			const res = await this.sendPB("Faceroam.OpReq", data);
			return Msg.FaceroamListResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 删除收藏表情（Faceroam.OpReq subCmd=2）。emojiIds 形如 `{uin}_0_0_0_{MD5_HEX_UPPER}_0_0`。 */
		async deleteFavEmojis(emojiIds) {
			const data = Msg.FaceroamOpReq.encode({
				comm: {
					imPlat: 1,
					osVersion: DeviceInfo.osVer
				},
				selfUin: BigInt(selfInfo.uin),
				subCmd: 2,
				deleteList: emojiIds.map((id) => ({ emojiId: id }))
			});
			const res = await this.sendPB("Faceroam.OpReq", data);
			return Msg.FaceroamDeleteResp.decode(Buffer.from(res.pb, "hex"));
		}
		/**
		* 申请上传收藏表情。返回 uKey + 上传服务器 IP/端口 + 最终 emoji_id。
		* 拿到后用 HighwayHttpSession（cmd=9, ticket=uKey）上传图片字节流。
		* 服务端收到完整文件后会自动加进用户收藏列表。
		*/
		async addFavEmojiPrep(opts) {
			const data = Msg.BDHExpressionRoamReq.encode({
				field1: 3,
				field2: 1,
				body: {
					field1: 0,
					uin: BigInt(selfInfo.uin),
					field3: 0,
					md5: opts.md5,
					fileSize: opts.fileSize,
					field7: 2,
					field8: 8,
					field9: 1,
					version: "1.0.0",
					field16: 1
				},
				commandId: 9,
				extension: Buffer.from("0a07080010001a01301001", "hex")
			});
			const res = await this.sendPB("ImgStore.BDHExpressionRoam", data);
			return Msg.BDHExpressionRoamResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 撤回私聊消息 */
		async recallC2CMessage(targetUid, clientSequence, random, timestamp, c2cMsgSeq) {
			const data = Action.SsoC2CRecallMsgReq.encode({
				type: 1,
				targetUid,
				info: {
					clientSequence,
					random,
					messageUid: BigInt(16777216) << 32n | BigInt(random),
					timestamp,
					field5: 0,
					c2cMsgSeq
				},
				field5: {
					field1: 0,
					field2: 0
				},
				field6: 0
			});
			await this.sendPB("trpc.msg.msg_svc.MsgService.SsoC2CRecallMsg", data);
		}
		/** 发消息（仅文本/At/表情/回复，不含媒体） */
		async sendMessage(opts) {
			const random = opts.random ?? randomBytes(4).readUInt32BE(0);
			const clientSequence = 1e4 + Math.floor(Math.random() * 9e4);
			const data = Msg.PbSendMsg.encode({
				routingHead: opts.content ? { trans0X211: {
					toUin: opts.toUin,
					ccCmd: 4,
					uid: opts.toUid
				} } : {
					1: { c2c: {
						toUin: opts.toUin,
						toUid: opts.toUid
					} },
					2: { group: { groupCode: opts.groupCode } },
					100: { groupTemp: {
						groupCode: opts.groupCode,
						toUid: opts.toUid
					} }
				}[opts.chatType],
				contentHead: {
					pkgNum: 1,
					pkgIndex: 0,
					divSeq: 0,
					autoReply: 0
				},
				body: {
					richText: { elems: opts.elems },
					msgContent: opts.content
				},
				clientSequence,
				random
			});
			const res = await this.sendPB("MessageSvc.PbSendMsg", data);
			const resp = Msg.PbSendMsgResp.decode(Buffer.from(res.pb, "hex"));
			const seq = resp.groupMsgSeq || resp.c2cMsgSeq;
			return {
				resultCode: resp.resultCode,
				errMsg: resp.errMsg ?? "",
				sequence: seq,
				timestamp: resp.sendTime,
				random,
				clientSequence
			};
		}
		/** 发送 C2C 离线文件消息（trans 0x211 + FileExtra）。upload + feed by send-msg。 */
		async sendC2CFileMessage(opts) {
			const random = randomBytes(4).readUInt32BE(0);
			const clientSequence = 1e4 + Math.floor(Math.random() * 9e4);
			const expireTime = Math.floor(Date.now() / 1e3) + 604800;
			const msgContent = Msg.FileExtra.encode({ file: {
				fileType: 0,
				fileUuid: opts.fileUuid,
				fileMd5: opts.file10MMd5,
				fileName: opts.fileName,
				fileSize: opts.fileSize,
				subCmd: 1,
				dangerLevel: 0,
				expireTime,
				fileIdCrcMedia: opts.crcMedia
			} });
			const data = Msg.PbSendMsg.encode({
				routingHead: { trans0X211: {
					toUin: opts.toUin,
					ccCmd: 4,
					uid: opts.toUid
				} },
				contentHead: {
					pkgNum: 1,
					pkgIndex: 0,
					divSeq: 0,
					autoReply: 0
				},
				body: { msgContent },
				clientSequence,
				random
			});
			const res = await this.sendPB("MessageSvc.PbSendMsg", data);
			const resp = Msg.PbSendMsgResp.decode(Buffer.from(res.pb, "hex"));
			return {
				resultCode: resp.resultCode,
				errMsg: resp.errMsg,
				sequence: resp.c2cMsgSeq,
				timestamp: resp.sendTime,
				random
			};
		}
		/** 拉取消息表情回应用户列表 (OidbSvcTrpcTcp.0x9083_1) */
		async fetchMsgEmojiLikes(groupCode, msgSeq, emojiCode, count, cookie) {
			const body = Oidb.FetchEmojiLikesReq.encode({
				groupCode,
				msgSeq,
				chatType: 1,
				emojiCode,
				cookie,
				field7: 0,
				count
			});
			const data = Oidb.Base.encode({
				command: 36995,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x9083_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchEmojiLikesResp.decode(decoded.body);
		}
		async reportMessageRead(chatType, peerUid, startSequence) {
			const isGroup = chatType === 2;
			const data = Action.SsoReadedReportReq.encode({
				group: isGroup ? {
					groupCode: +peerUid,
					startSequence
				} : void 0,
				c2c: !isGroup ? {
					targetUid: peerUid,
					startSequence
				} : void 0
			});
			const res = await this.sendPB("trpc.msg.msg_svc.MsgService.SsoReadedReport", data);
			return Action.SsoReadedReportResp.decode(Buffer.from(res.pb, "hex"));
		}
		async setInputStatus(toUid, eventType) {
			const body = Oidb.SetInputStatusReq.encode({ body: {
				toUid,
				field2: 0,
				eventType
			} });
			const data = Oidb.Base.encode({
				command: 3284,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xcd4_1", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.SetInputStatusResp.decode(oidbRespBody);
		}
	}
	return Mixed;
}
//#endregion
//#region src/main/qqProtocol/mixins/user.ts
function UserMixin(Base) {
	class Mixed extends Base {
		async fetchUserInfoByUin(uin) {
			const body = Oidb.FetchUserInfoByUinReq.encode({
				uin,
				keys: [
					{ key: 102 },
					{ key: 103 },
					{ key: 104 },
					{ key: 105 },
					{ key: 107 },
					{ key: 20002 },
					{ key: 20003 },
					{ key: 20009 },
					{ key: 20020 },
					{ key: 20021 },
					{ key: 20026 },
					{ key: 20031 },
					{ key: 20037 },
					{ key: 27394 }
				]
			});
			const data = Oidb.Base.encode({
				command: 4065,
				subCommand: 2,
				body,
				isReserved: 1
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xfe1_2", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchUserInfoResp.decode(decoded.body);
		}
		async fetchUserInfoByUid(uid) {
			const body = Oidb.FetchUserInfoByUidReq.encode({
				uid,
				keys: [
					{ key: 102 },
					{ key: 103 },
					{ key: 104 },
					{ key: 105 },
					{ key: 107 },
					{ key: 20002 },
					{ key: 20003 },
					{ key: 20009 },
					{ key: 20020 },
					{ key: 20021 },
					{ key: 20026 },
					{ key: 20031 },
					{ key: 20037 },
					{ key: 27394 }
				]
			});
			const data = Oidb.Base.encode({
				command: 4065,
				subCommand: 2,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0xfe1_2", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchUserInfoResp.decode(decoded.body);
		}
		async fetchUserLoginDays(uin) {
			const body = Action.FetchUserLoginDaysReq.encode({
				field2: 0,
				json: JSON.stringify({
					msg_req_basic_info: { uint64_request_uin: [uin] },
					uint32_req_login_info: 1
				})
			});
			const res = await this.sendPB("MQUpdateSvc_com_qq_ti.web.OidbSvc.0xdef_1", body);
			const { json } = Action.FetchUserLoginDaysResp.decode(Buffer.from(res.pb, "hex"));
			return JSON.parse(json).msg_rsp_basic_info?.rpt_msg_basic_info.find((e) => e.uint64_uin === uin)?.uint32_login_days ?? 0;
		}
		/** 给好友点赞，count 1~20 表示一次点赞次数（QQ 协议限制每天 20 个） */
		async sendFriendLike(targetUid, count = 1) {
			const body = Oidb.FriendLikeReq.encode({
				targetUid,
				field2: 71,
				count
			});
			return await this.sendOidb(2021, 104, body);
		}
		/** 设置在线状态。status: 在线状态码（10=在线, 30=离开, 40=隐身, 50=忙碌, 60=Q我, 70=请勿打扰）；extStatus 通常 0 */
		async setOnlineStatus(status, extStatus, batteryStatus, customFaceId, customText) {
			const body = Action.SetStatusReq.encode({
				status,
				extStatus,
				batteryStatus,
				customExt: customFaceId ? {
					faceId: customFaceId,
					text: customText ?? "",
					field3: 1
				} : void 0
			});
			const res = await this.sendPB("trpc.qq_new_tech.status_svc.StatusService.SetStatus", body);
			return Action.SetStatusResp.decode(Buffer.from(res.pb, "hex"));
		}
		/** 拉 clientKey（用于换 web cookies）。OidbSvcTrpcTcp.0x102a_1 */
		async fetchClientKey() {
			const body = Oidb.FetchCookiesReq.encode({});
			const data = Oidb.Base.encode({
				command: 4138,
				subCommand: 1,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x102a_1", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchCookiesResp.decode(decoded.body);
		}
		/** 拉指定 domain 的 PSkey 字典。OidbSvcTrpcTcp.0x102a_0 */
		async fetchPSkey(domains) {
			const body = Oidb.FetchCookiesReq.encode({ domain: domains });
			const data = Oidb.Base.encode({
				command: 4138,
				subCommand: 0,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x102a_0", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchCookiesResp.decode(decoded.body);
		}
		/** 获取赞过我或我赞过的列表。direction: 0=我赞过的, 1=赞过我的。OidbSvcTrpcTcp.0x7ed_13 */
		async fetchProfileLikes(selfUid, direction, start, count) {
			const body = Oidb.FetchProfileLikeReq.encode({
				selfUid,
				field2: 1,
				field3: direction,
				field4: direction === 0 ? 1 : 0,
				field101: 1,
				start,
				count
			});
			const data = Oidb.Base.encode({
				command: 2029,
				subCommand: 13,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x7ed_13", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchProfileLikeResp.decode(decoded.body);
		}
		async fetchProfileLikeCount(uid) {
			const body = Oidb.FetchProfileLikeCountReq.encode({ uid });
			const data = Oidb.Base.encode({
				command: 2029,
				subCommand: 12,
				body
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x7ed_12", data);
			const decoded = Oidb.Base.decode(Buffer.from(res.pb, "hex"));
			return Oidb.FetchProfileLikeCountResp.decode(decoded.body);
		}
		/** 修改自己的资料 (OidbSvcTrpcTcp.0x112a_2) */
		async modifySelfProfile(profile) {
			const bytesProperties = [];
			const numberProperties = [];
			if (isNonNullable(profile.longNick)) bytesProperties.push({
				key: 102,
				value: Buffer.from(profile.longNick, "utf-8")
			});
			if (isNonNullable(profile.nick)) bytesProperties.push({
				key: 20002,
				value: Buffer.from(profile.nick, "utf-8")
			});
			bytesProperties.push({
				key: 20032,
				value: Buffer.alloc(12)
			});
			if (isNonNullable(profile.sex)) numberProperties.push({
				key: 20009,
				value: profile.sex
			});
			if (isNonNullable(profile.birthdayYear)) {
				const packed = (profile.birthdayYear & 65535) << 16 | ((profile.birthdayMonth ?? 0) & 255) << 8 | (profile.birthdayDay ?? 0) & 255;
				numberProperties.push({
					key: 20031,
					value: packed
				});
			}
			const body = Oidb.ModifySelfProfileReq.encode({
				selfUin: +selfInfo.uin,
				bytesProperties,
				numberProperties
			});
			return await this.sendOidb(4394, 2, body);
		}
	}
	return Mixed;
}
//#endregion
//#region src/main/qqProtocol/mixins/system.ts
function SystemMixin(Base) {
	class Mixed extends Base {
		async fetchPins() {
			const data = Oidb.Base.encode({
				command: 4787,
				subCommand: 0,
				body: Buffer.alloc(0)
			});
			const res = await this.sendPB("OidbSvcTrpcTcp.0x12b3_0", data);
			const oidbRespBody = Oidb.Base.decode(Buffer.from(res.pb, "hex")).body;
			return Oidb.FetchPinsResp.decode(oidbRespBody);
		}
	}
	return Mixed;
}
//#endregion
//#region src/main/qqProtocol/index.ts
function applyMixins(Base, mixins) {
	return mixins.reduce((acc, mixin) => mixin(acc), Base);
}
var mixins = [
	GroupMixin,
	FriendMixin,
	MediaMixin,
	MessageMixin,
	UserMixin,
	SystemMixin
];
/**
* 两个模式的 Service 类分别 apply 所有 OIDB mixins.
* main.ts 根据 isPmhqMode() 二选一 ctx.plugin(...) 一次.
*/
var DirectQQProtocolClient = applyMixins(DirectQQProtocol, mixins);
var PmhqQQProtocolClient = applyMixins(PmhqQQProtocol, mixins);
//#endregion
//#region node_modules/@cordisjs/plugin-logger-console/lib/browser.js
var ConsoleExporter = class {
	constructor(ctx, config = {}) {
		this.ctx = ctx;
		Object.assign(this, this.getDefaults(), config);
		this.timestamp = Date.now();
		ctx.logger.exporter(this);
	}
	static name = "logger-console";
	static Config = lib_default$1.object({
		colors: lib_default$1.union([lib_default$1.const(false), lib_default$1.number()]),
		maxLength: lib_default$1.number(),
		levels: lib_default$1.dict(lib_default$1.number()),
		showDiff: lib_default$1.boolean().default(false),
		showTime: lib_default$1.string().default("yyyy-MM-dd hh:mm:ss "),
		label: lib_default$1.object({
			width: lib_default$1.number(),
			margin: lib_default$1.number(),
			align: lib_default$1.union(["left", "right"])
		})
	});
	colors;
	maxLength;
	levels;
	showDiff;
	showTime;
	label;
	timestamp;
	formatters = {};
	getDefaults() {
		return {
			colors: false,
			showTime: "yyyy-MM-dd hh:mm:ss ",
			showDiff: false
		};
	}
	export(message) {
		console.log(this.render(message));
	}
	render(message) {
		const prefix = `[${message.type[0].toUpperCase()}]`;
		const space = " ".repeat(this.label?.margin ?? 1);
		let indent = 3 + space.length, output = "";
		if (this.showTime) {
			indent += this.showTime.length;
			output += Logger.color(this, 8, Time.template(this.showTime));
		}
		const code = Logger.code(message.name, this.colors);
		const label = Logger.color(this, code, message.name, ";1");
		const padLength = (this.label?.width ?? 0) + label.length - message.name.length;
		if (this.label?.align === "right") {
			output += label.padStart(padLength) + space + prefix + space;
			indent += (this.label.width ?? 0) + space.length;
		} else output += prefix + space + label.padEnd(padLength) + space;
		output += Logger.format(this, message).replace(/\n/g, "\n" + " ".repeat(indent));
		if (this.showDiff && this.timestamp) {
			const diff = message.ts - this.timestamp;
			output += Logger.color(this, code, " +" + Time.format(diff));
		}
		this.timestamp = message.ts;
		return output;
	}
};
var ConsoleExporter2 = class extends ConsoleExporter {
	static name = "logger-console";
	export(message) {
		const prefix = `[${message.type[0].toUpperCase()}] ${message.name}`;
		const method = message.type === "error" ? "error" : message.type === "warn" ? "warn" : "log";
		console[method](prefix, ...message.args);
	}
};
var browser_default = ConsoleExporter2;
//#endregion
//#region node_modules/@cordisjs/plugin-timer/lib/index.js
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", {
	value,
	configurable: true
});
var TimerService = class extends Service {
	static {
		__name(this, "TimerService");
	}
	constructor(ctx) {
		super(ctx, "timer");
		ctx.mixin("timer", [
			"timeout",
			"interval",
			"throttle",
			"debounce",
			"setTimeout",
			"setInterval"
		]);
	}
	/** @deprecated use `ctx.timeout()` instead */
	setTimeout(callback, delay) {
		return this.timeout(callback, delay);
	}
	/** @deprecated use `ctx.interval()` instead */
	setInterval(callback, delay) {
		return this.interval(callback, delay);
	}
	timeout(...args) {
		const callback = typeof args[0] === "function" ? args.shift() : void 0;
		const delay = args[0];
		if (callback) {
			const dispose = this.ctx.effect(() => {
				const timer = setTimeout(() => {
					dispose();
					callback();
				}, delay);
				return () => clearTimeout(timer);
			}, "ctx.timeout()");
			return dispose;
		} else {
			const { promise, resolve, reject } = Promise.withResolvers();
			const dispose = this.ctx.effect(() => {
				const timer = setTimeout(resolve, delay);
				return () => {
					clearTimeout(timer);
					reject(/* @__PURE__ */ new Error("Context has been disposed"));
				};
			}, "ctx.timeout()");
			return promise.finally(dispose);
		}
	}
	interval(...args) {
		const callback = typeof args[0] === "function" ? args.shift() : void 0;
		const delay = args[0];
		if (callback) return this.ctx.effect(() => {
			const timer = setInterval(callback, delay);
			return () => clearInterval(timer);
		}, "ctx.interval()");
		else {
			let done;
			let nextTask;
			const dispose = this.ctx.effect(() => {
				const timer = setInterval(() => {
					nextTask?.resolve({
						done: false,
						value: void 0
					});
				}, delay);
				return () => {
					clearInterval(timer);
					if (done) return;
					done = {
						kind: "throw",
						reason: /* @__PURE__ */ new Error("Context has been disposed")
					};
					nextTask?.reject(done.reason);
				};
			}, "ctx.interval()");
			return {
				next: /* @__PURE__ */ __name(() => {
					if (!done) return (nextTask = Promise.withResolvers()).promise;
					if (done.kind === "return") return Promise.resolve({
						done: true,
						value: done.value
					});
					return Promise.reject(done.reason);
				}, "next"),
				return: /* @__PURE__ */ __name((value) => {
					if (!done) done = {
						kind: "return",
						value
					};
					nextTask?.resolve({
						done: true,
						value
					});
					dispose();
					return Promise.resolve({
						done: true,
						value
					});
				}, "return"),
				throw: /* @__PURE__ */ __name((reason) => {
					if (!done) done = {
						kind: "throw",
						reason
					};
					nextTask?.reject(reason);
					dispose();
					return Promise.resolve({
						done: true,
						value: void 0
					});
				}, "throw"),
				[Symbol.asyncIterator]() {
					return this;
				}
			};
		}
	}
	_schedule(label, trigger, isDisposed = false) {
		let timer;
		const dispose = this.ctx.effect(() => () => {
			isDisposed = true;
			clearTimeout(timer);
		}, label);
		const wrapper = /* @__PURE__ */ __name((...args) => {
			clearTimeout(timer);
			timer = trigger(args, isDisposed);
		}, "wrapper");
		wrapper.dispose = dispose;
		return wrapper;
	}
	throttle(callback, delay, noTrailing) {
		let lastCall = -Infinity;
		const execute = /* @__PURE__ */ __name((...args) => {
			lastCall = Date.now();
			callback(...args);
		}, "execute");
		return this._schedule("ctx.throttle()", (args, isDisposed) => {
			const remaining = delay - Date.now() + lastCall;
			if (remaining <= 0) execute(...args);
			else if (!isDisposed) return setTimeout(execute, remaining, ...args);
		}, noTrailing);
	}
	debounce(callback, delay) {
		return this._schedule("ctx.debounce()", (args, isDisposed) => {
			if (isDisposed) return;
			return setTimeout(callback, delay, ...args);
		});
	}
};
var index_default = TimerService;
//#endregion
//#region src/main/main.ts
globalThis.__dirname = import.meta.dirname;
function applyDebugLevel(ctx) {
	const level = isDebugEnabled() ? 3 : 2;
	ctx.logger.exporters?.forEach((exp) => {
		exp.levels = {
			...exp.levels ?? {},
			default: level
		};
	});
}
async function onLoad() {
	if (!existsSync(LOG_DIR)) mkdirSync(LOG_DIR);
	if (!existsSync(TEMP_DIR)) mkdirSync(TEMP_DIR);
	const ctx = new Context$1();
	ctx.plugin(Log);
	ctx.plugin(browser_default, { levels: { default: isDebugEnabled() ? 3 : 2 } });
	bindLoggerFactory((name) => ctx.logger(name));
	ctx.plugin(index_default);
	ctx.plugin(Config);
	ctx.plugin(isPmhqMode() ? PmhqQQProtocolClient : DirectQQProtocolClient);
	ctx.plugin(NTFileApi);
	ctx.plugin(NTFriendApi);
	ctx.plugin(NTGroupApi);
	ctx.plugin(NTLoginApi);
	ctx.plugin(NTMsgApi);
	ctx.plugin(NTUserApi);
	ctx.plugin(NTWebApi);
	ctx.plugin(NTSystemApi);
	let config;
	let sessionLoaded = false;
	const loadPluginAfterLogin = () => {
		if (sessionLoaded) return;
		sessionLoaded = true;
		ctx.plugin(index_default$2);
		ctx.plugin(index_default$1, { path: pathToFileURL(path.join(dbDir, `${selfInfo.uin}.v3.db`)).href });
		ctx.plugin(Core, config);
		ctx.plugin(Onebot11Adapter, {
			...config.ob11,
			musicSignUrl: config.musicSignUrl,
			enableLocalFile2Url: config.enableLocalFile2Url,
			ffmpeg: config.ffmpeg
		});
		ctx.plugin(SatoriAdapter, {
			...config.satori,
			ffmpeg: config.ffmpeg
		});
		ctx.plugin(MilkyAdapter, config.milky);
		ctx.plugin(Store, { msgCacheExpire: config.msgCacheExpire });
		ctx.plugin(EmailNotificationService);
	};
	ctx.inject(["qqProtocol", "config"], (ctx) => {
		ctx.logger.info(`LLBot ${version$3}`);
		ctx.logger.info(process.argv);
		config = ctx.config.get();
		setConfigLogLevel(config.logLevel);
		applyDebugLevel(ctx);
		ctx.on("llob/config-updated", (c) => {
			setConfigLogLevel(c.logLevel);
			applyDebugLevel(ctx);
		});
		ctx.plugin(WebuiServer, config.webui);
		const handleOnline = async () => {
			console.log(`
  _                _            _     _ _ _ _
 | |    _   _  ___| | ___   _  | |   (_) | (_) __ _
 | |   | | | |/ __| |/ / | | | | |   | | | | |/ _\` |
 | |___| |_| | (__|   <| |_| | | |___| | | | | (_| |
 |_____|\\__,_|\\___|_|\\_\\\\__, | |_____|_|_|_|_|\\__,_|
                        |___/
                                        UIN: ${selfInfo.uin}
`);
			setLoginState({
				state: "logged_in",
				uin: selfInfo.uin,
				nickname: selfInfo.nick
			});
			if (!sessionLoaded) {
				config = ctx.config.get(false);
				ctx.config.listenChange((c) => {
					ctx.parallel("llob/config-updated", c);
				});
				ctx.parallel("llob/config-updated", config);
			}
			loadPluginAfterLogin();
		};
		ctx.on("qq/online", handleOnline);
		if (selfInfo.online && selfInfo.uid) handleOnline();
		ctx.on("llbot/self-nick-changed", (info) => {
			setLoginState({ nickname: info.nick });
		});
		ctx.on("protocol/disconnect", () => {
			ctx.logger.info("协议层断开，等待重连…");
		});
		startIpcServer();
		setLoginState({ state: "initializing" });
	});
	process.on("unhandledRejection", (reason) => {
		ctx.logger.error("[unhandledRejection]", reason);
	});
	process.on("uncaughtException", (err) => {
		ctx.logger.error("[uncaughtException]", err);
	});
}
onLoad().catch((e) => getLogger("main").error(e));
//#endregion
export {};

//# sourceMappingURL=llbot.js.map