import { buildChannelConfigSchema, emptyPluginConfigSchema, fetchWithSsrFGuard, isBlockedHostname, isPrivateIpAddress } from "minion/plugin-sdk";
import { DEFAULT_ACCOUNT_ID, applyAccountNameToChannelSection, createReplyPrefixOptions, formatDocsLink, normalizeAccountId, promptAccountId } from "openclaw/plugin-sdk";
import { z } from "zod";
import { format } from "node:util";
import { Readable } from "node:stream";

//#region \0rolldown/runtime.js
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);

//#endregion
//#region extensions/tlon/src/account-fields.ts
function buildTlonAccountFields(input) {
	return {
		...input.ship ? { ship: input.ship } : {},
		...input.url ? { url: input.url } : {},
		...input.code ? { code: input.code } : {},
		...typeof input.allowPrivateNetwork === "boolean" ? { allowPrivateNetwork: input.allowPrivateNetwork } : {},
		...input.groupChannels ? { groupChannels: input.groupChannels } : {},
		...input.dmAllowlist ? { dmAllowlist: input.dmAllowlist } : {},
		...typeof input.autoDiscoverChannels === "boolean" ? { autoDiscoverChannels: input.autoDiscoverChannels } : {}
	};
}

//#endregion
//#region extensions/tlon/src/config-schema.ts
const ShipSchema = z.string().min(1);
const ChannelNestSchema = z.string().min(1);
const TlonChannelRuleSchema = z.object({
	mode: z.enum(["restricted", "open"]).optional(),
	allowedShips: z.array(ShipSchema).optional()
});
const TlonAuthorizationSchema = z.object({ channelRules: z.record(z.string(), TlonChannelRuleSchema).optional() });
const TlonAccountSchema = z.object({
	name: z.string().optional(),
	enabled: z.boolean().optional(),
	ship: ShipSchema.optional(),
	url: z.string().optional(),
	code: z.string().optional(),
	allowPrivateNetwork: z.boolean().optional(),
	groupChannels: z.array(ChannelNestSchema).optional(),
	dmAllowlist: z.array(ShipSchema).optional(),
	autoDiscoverChannels: z.boolean().optional(),
	showModelSignature: z.boolean().optional(),
	responsePrefix: z.string().optional()
});
const TlonConfigSchema = z.object({
	name: z.string().optional(),
	enabled: z.boolean().optional(),
	ship: ShipSchema.optional(),
	url: z.string().optional(),
	code: z.string().optional(),
	allowPrivateNetwork: z.boolean().optional(),
	groupChannels: z.array(ChannelNestSchema).optional(),
	dmAllowlist: z.array(ShipSchema).optional(),
	autoDiscoverChannels: z.boolean().optional(),
	showModelSignature: z.boolean().optional(),
	responsePrefix: z.string().optional(),
	authorization: TlonAuthorizationSchema.optional(),
	defaultAuthorizedShips: z.array(ShipSchema).optional(),
	accounts: z.record(z.string(), TlonAccountSchema).optional()
});
const tlonChannelConfigSchema = buildChannelConfigSchema(TlonConfigSchema);

//#endregion
//#region extensions/tlon/src/runtime.ts
let runtime = null;
function setTlonRuntime(next) {
	runtime = next;
}
function getTlonRuntime() {
	if (!runtime) throw new Error("Tlon runtime not initialized");
	return runtime;
}

//#endregion
//#region extensions/tlon/src/targets.ts
const SHIP_RE = /^~?[a-z-]+$/i;
const NEST_RE = /^chat\/([^/]+)\/([^/]+)$/i;
function normalizeShip(raw) {
	const trimmed = raw.trim();
	if (!trimmed) return trimmed;
	return trimmed.startsWith("~") ? trimmed : `~${trimmed}`;
}
function parseChannelNest(raw) {
	const match = NEST_RE.exec(raw.trim());
	if (!match) return null;
	return {
		hostShip: normalizeShip(match[1]),
		channelName: match[2]
	};
}
function parseTlonTarget(raw) {
	const trimmed = raw?.trim();
	if (!trimmed) return null;
	const withoutPrefix = trimmed.replace(/^tlon:/i, "");
	const dmPrefix = withoutPrefix.match(/^dm[/:](.+)$/i);
	if (dmPrefix) return {
		kind: "direct",
		ship: normalizeShip(dmPrefix[1])
	};
	const groupPrefix = withoutPrefix.match(/^(group|room)[/:](.+)$/i);
	if (groupPrefix) {
		const groupTarget = groupPrefix[2].trim();
		if (groupTarget.startsWith("chat/")) {
			const parsed = parseChannelNest(groupTarget);
			if (!parsed) return null;
			return {
				kind: "group",
				nest: `chat/${parsed.hostShip}/${parsed.channelName}`,
				hostShip: parsed.hostShip,
				channelName: parsed.channelName
			};
		}
		const parts = groupTarget.split("/");
		if (parts.length === 2) {
			const hostShip = normalizeShip(parts[0]);
			const channelName = parts[1];
			return {
				kind: "group",
				nest: `chat/${hostShip}/${channelName}`,
				hostShip,
				channelName
			};
		}
		return null;
	}
	if (withoutPrefix.startsWith("chat/")) {
		const parsed = parseChannelNest(withoutPrefix);
		if (!parsed) return null;
		return {
			kind: "group",
			nest: `chat/${parsed.hostShip}/${parsed.channelName}`,
			hostShip: parsed.hostShip,
			channelName: parsed.channelName
		};
	}
	if (SHIP_RE.test(withoutPrefix)) return {
		kind: "direct",
		ship: normalizeShip(withoutPrefix)
	};
	return null;
}
function formatTargetHint() {
	return "dm/~sampel-palnet | ~sampel-palnet | chat/~host-ship/channel | group:~host-ship/channel";
}

//#endregion
//#region extensions/tlon/src/types.ts
function resolveTlonAccount(cfg, accountId) {
	const base = cfg.channels?.tlon;
	if (!base) return {
		accountId: accountId || "default",
		name: null,
		enabled: false,
		configured: false,
		ship: null,
		url: null,
		code: null,
		allowPrivateNetwork: null,
		groupChannels: [],
		dmAllowlist: [],
		autoDiscoverChannels: null,
		showModelSignature: null
	};
	const account = !accountId || accountId === "default" ? base : base.accounts?.[accountId];
	const ship = account?.ship ?? base.ship ?? null;
	const url = account?.url ?? base.url ?? null;
	const code = account?.code ?? base.code ?? null;
	const allowPrivateNetwork = account?.allowPrivateNetwork ?? base.allowPrivateNetwork ?? null;
	const groupChannels = account?.groupChannels ?? base.groupChannels ?? [];
	const dmAllowlist = account?.dmAllowlist ?? base.dmAllowlist ?? [];
	const autoDiscoverChannels = account?.autoDiscoverChannels ?? base.autoDiscoverChannels ?? null;
	const showModelSignature = account?.showModelSignature ?? base.showModelSignature ?? null;
	const configured = Boolean(ship && url && code);
	return {
		accountId: accountId || "default",
		name: account?.name ?? base.name ?? null,
		enabled: (account?.enabled ?? base.enabled ?? true) !== false,
		configured,
		ship,
		url,
		code,
		allowPrivateNetwork,
		groupChannels,
		dmAllowlist,
		autoDiscoverChannels,
		showModelSignature
	};
}
function listTlonAccountIds(cfg) {
	const base = cfg.channels?.tlon;
	if (!base) return [];
	const accounts = base.accounts ?? {};
	return [...base.ship ? ["default"] : [], ...Object.keys(accounts)];
}

//#endregion
//#region extensions/tlon/src/urbit/errors.ts
var UrbitError = class extends Error {
	constructor(code, message, options) {
		super(message, options);
		this.name = "UrbitError";
		this.code = code;
	}
};
var UrbitUrlError = class extends UrbitError {
	constructor(message, options) {
		super("invalid_url", message, options);
		this.name = "UrbitUrlError";
	}
};
var UrbitHttpError = class extends UrbitError {
	constructor(params) {
		const suffix = params.bodyText ? ` - ${params.bodyText}` : "";
		super("http_error", `${params.operation} failed: ${params.status}${suffix}`, { cause: params.cause });
		this.name = "UrbitHttpError";
		this.status = params.status;
		this.operation = params.operation;
		this.bodyText = params.bodyText;
	}
};
var UrbitAuthError = class extends UrbitError {
	constructor(code, message, options) {
		super(code, message, options);
		this.name = "UrbitAuthError";
	}
};

//#endregion
//#region extensions/tlon/src/urbit/base-url.ts
function hasScheme(value) {
	return /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(value);
}
function validateUrbitBaseUrl(raw) {
	const trimmed = String(raw ?? "").trim();
	if (!trimmed) return {
		ok: false,
		error: "Required"
	};
	const candidate = hasScheme(trimmed) ? trimmed : `https://${trimmed}`;
	let parsed;
	try {
		parsed = new URL(candidate);
	} catch {
		return {
			ok: false,
			error: "Invalid URL"
		};
	}
	if (!["http:", "https:"].includes(parsed.protocol)) return {
		ok: false,
		error: "URL must use http:// or https://"
	};
	if (parsed.username || parsed.password) return {
		ok: false,
		error: "URL must not include credentials"
	};
	const hostname = parsed.hostname.trim().toLowerCase().replace(/\.$/, "");
	if (!hostname) return {
		ok: false,
		error: "Invalid hostname"
	};
	const isIpv6 = hostname.includes(":");
	const host = parsed.port ? `${isIpv6 ? `[${hostname}]` : hostname}:${parsed.port}` : isIpv6 ? `[${hostname}]` : hostname;
	return {
		ok: true,
		baseUrl: `${parsed.protocol}//${host}`,
		hostname
	};
}
function isBlockedUrbitHostname(hostname) {
	const normalized = hostname.trim().toLowerCase().replace(/\.$/, "");
	if (!normalized) return false;
	return isBlockedHostname(normalized) || isPrivateIpAddress(normalized);
}

//#endregion
//#region extensions/tlon/src/urbit/fetch.ts
async function urbitFetch(params) {
	const validated = validateUrbitBaseUrl(params.baseUrl);
	if (!validated.ok) throw new UrbitUrlError(validated.error);
	return await fetchWithSsrFGuard({
		url: new URL(params.path, validated.baseUrl).toString(),
		fetchImpl: params.fetchImpl,
		init: params.init,
		timeoutMs: params.timeoutMs,
		maxRedirects: params.maxRedirects,
		signal: params.signal,
		policy: params.ssrfPolicy,
		lookupFn: params.lookupFn,
		auditContext: params.auditContext,
		pinDns: params.pinDns
	});
}

//#endregion
//#region extensions/tlon/src/urbit/auth.ts
async function authenticate(url, code, options = {}) {
	const { response, release } = await urbitFetch({
		baseUrl: url,
		path: "/~/login",
		init: {
			method: "POST",
			headers: { "Content-Type": "application/x-www-form-urlencoded" },
			body: new URLSearchParams({ password: code }).toString()
		},
		ssrfPolicy: options.ssrfPolicy,
		lookupFn: options.lookupFn,
		fetchImpl: options.fetchImpl,
		timeoutMs: options.timeoutMs ?? 15e3,
		maxRedirects: 3,
		auditContext: "tlon-urbit-login"
	});
	try {
		if (!response.ok) throw new UrbitAuthError("auth_failed", `Login failed with status ${response.status}`);
		await response.text().catch(() => {});
		const cookie = response.headers.get("set-cookie");
		if (!cookie) throw new UrbitAuthError("missing_cookie", "No authentication cookie received");
		return cookie;
	} finally {
		await release();
	}
}

//#endregion
//#region extensions/tlon/src/urbit/context.ts
function resolveShipFromHostname(hostname) {
	const trimmed = hostname.trim().toLowerCase().replace(/\.$/, "");
	if (!trimmed) return "";
	if (trimmed.includes(".")) return trimmed.split(".")[0] ?? trimmed;
	return trimmed;
}
function normalizeUrbitShip(ship, hostname) {
	return (ship?.replace(/^~/, "") ?? resolveShipFromHostname(hostname)).trim();
}
function normalizeUrbitCookie(cookie) {
	return cookie.split(";")[0] ?? cookie;
}
function getUrbitContext(url, ship) {
	const validated = validateUrbitBaseUrl(url);
	if (!validated.ok) throw new UrbitUrlError(validated.error);
	return {
		baseUrl: validated.baseUrl,
		hostname: validated.hostname,
		ship: normalizeUrbitShip(ship, validated.hostname)
	};
}
function ssrfPolicyFromAllowPrivateNetwork(allowPrivateNetwork) {
	return allowPrivateNetwork ? { allowPrivateNetwork: true } : void 0;
}

//#endregion
//#region node_modules/.pnpm/@urbit+aura@3.0.0/node_modules/@urbit/aura/dist/aura.cjs.production.min.js
var require_aura_cjs_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
	function n(n) {
		let t = !0, [e, r, u] = n.split("..");
		r = r || "0.0.0", u = u || "0000";
		let [s, c, l] = e.slice(1).split(".");
		"-" === s.at(-1) && (s = s.slice(0, -1), t = !1);
		const [d, p, g] = r.split("."), h = u.split(".").map(((n) => BigInt("0x" + n)));
		return function(n) {
			const t = n.pos ? a + BigInt(n.year) : a - (BigInt(n.year) - 1n), e = (() => {
				let e = i(t) ? f : o, r = n.time.day - 1n, a = n.month - 1n;
				for (; 0n !== a;) {
					const [n, ...t] = e;
					r += BigInt(n), a -= 1n, e = t;
				}
				let u = !0, s = t;
				for (; 1 == u;) s % 4n !== 0n ? (s -= 1n, r += i(s) ? 366n : 365n) : s % 100n !== 0n ? (s -= 4n, r += i(s) ? 1461n : 1460n) : s % 400n !== 0n ? (s -= 100n, r += i(s) ? 36525n : 36524n) : (r += s / 400n * (4n * 36524n + 1n), u = !1);
				return r;
			})();
			return n.time.day = e, m(n.time);
		}({
			pos: t,
			year: BigInt(s),
			month: BigInt(c),
			time: {
				day: BigInt(l),
				hour: BigInt(d),
				minute: BigInt(p),
				second: BigInt(g),
				ms: h
			}
		});
	}
	function t(n) {
		const t = {
			day: 0n,
			hour: 0n,
			minute: 0n,
			second: 0n,
			ms: []
		};
		n = n.slice(1);
		let [e, r] = n.split("..");
		return r = r || "0000", t.ms = r.split(".").map(((n) => BigInt("0x" + n))), e.split(".").forEach(((e) => {
			switch (e[0]) {
				case "d":
					t.day += BigInt(e.slice(1));
					break;
				case "h":
					t.hour += BigInt(e.slice(1));
					break;
				case "m":
					t.minute += BigInt(e.slice(1));
					break;
				case "s":
					t.second += BigInt(e.slice(1));
					break;
				default: throw new Error("bad dr: " + n);
			}
		})), r = r || "0000", m(t);
	}
	Object.defineProperty(exports, "__esModule", { value: !0 });
	const e = BigInt("170141184475152167957503069145530368000"), r = BigInt("18446744073709551616"), a = BigInt("292277024400");
	function i(n) {
		return n % 4n === 0n && n % 100n !== 0n || n % 400n === 0n;
	}
	const o = [
		31,
		28,
		31,
		30,
		31,
		30,
		31,
		31,
		30,
		31,
		30,
		31
	], f = [
		31,
		29,
		31,
		30,
		31,
		30,
		31,
		31,
		30,
		31,
		30,
		31
	], u = 86400n, s = 3600n, c = 60n, l = 146097n, d = 36524n;
	function m(n) {
		let t = n.second + u * n.day + s * n.hour + c * n.minute, e = n.ms, r = 0n, a = 3n;
		for (; 0 !== e.length;) {
			const [n, ...t] = e;
			r += n << 16n * a, e = t, a -= 1n;
		}
		return r | t << 64n;
	}
	function p(n) {
		let t = n >> 64n;
		const e = (BigInt("0xffffffffffffffff") & n).toString(16).padStart(16, "0").match(/.{4}/g).map(((n) => BigInt("0x" + n)));
		for (; 0n === e.at(-1);) e.pop();
		let r = t / u;
		t %= u;
		let a = t / s;
		t %= s;
		let i = t / c;
		return t %= c, {
			ms: e,
			day: r,
			minute: i,
			hour: a,
			second: t
		};
	}
	const g = (n, t) => ((n, t) => {
		const e = Number(255n & t), r = Number((65280n & t) / 256n), a = String.fromCharCode(e) + String.fromCharCode(r);
		return BigInt(((n, t) => {
			let e, r, a, i, o, f, u, s;
			for (e = 3 & n.length, r = n.length - e, a = t, o = 3432918353, f = 461845907, s = 0; s < r;) u = 255 & n.charCodeAt(s) | (255 & n.charCodeAt(++s)) << 8 | (255 & n.charCodeAt(++s)) << 16 | (255 & n.charCodeAt(++s)) << 24, ++s, u = (65535 & u) * o + (((u >>> 16) * o & 65535) << 16) & 4294967295, u = u << 15 | u >>> 17, u = (65535 & u) * f + (((u >>> 16) * f & 65535) << 16) & 4294967295, a ^= u, a = a << 13 | a >>> 19, i = 5 * (65535 & a) + ((5 * (a >>> 16) & 65535) << 16) & 4294967295, a = 27492 + (65535 & i) + ((58964 + (i >>> 16) & 65535) << 16);
			switch (u = 0, e) {
				case 3: u ^= (255 & n.charCodeAt(s + 2)) << 16;
				case 2: u ^= (255 & n.charCodeAt(s + 1)) << 8;
				case 1: u ^= 255 & n.charCodeAt(s), u = (65535 & u) * o + (((u >>> 16) * o & 65535) << 16) & 4294967295, u = u << 15 | u >>> 17, u = (65535 & u) * f + (((u >>> 16) * f & 65535) << 16) & 4294967295, a ^= u;
			}
			return a ^= n.length, a ^= a >>> 16, a = 2246822507 * (65535 & a) + ((2246822507 * (a >>> 16) & 65535) << 16) & 4294967295, a ^= a >>> 13, a = 3266489909 * (65535 & a) + ((3266489909 * (a >>> 16) & 65535) << 16) & 4294967295, a ^= a >>> 16, a >>> 0;
		})(a, n));
	})([
		3077398253,
		3995603712,
		2243735041,
		1261992695
	][n], t), h = (n) => y(4, 65535n, 65536n, 4294967295n, g, n), y = (n, t, e, r, a, i) => {
		const o = b(n, t, e, a, i);
		return o < r ? o : b(n, t, e, a, o);
	}, b = (n, t, e, r, a) => {
		const i = (a, o, f) => {
			if (a > n) return n % 2 != 0 || f === t ? t * f + o : t * o + f;
			{
				const n = BigInt(r(a - 1, f).toString());
				return i(a + 1, f, a % 2 != 0 ? (o + n) % t : (o + n) % e);
			}
		};
		return i(1, a % t, a / t);
	}, x = (n) => w(4, 65535n, 65536n, 4294967295n, g, n), w = (n, t, e, r, a, i) => {
		const o = B(n, t, e, a, i);
		return o < r ? o : B(n, t, e, a, o);
	}, B = (n, t, e, r, a) => {
		const i = (n, a, o) => {
			if (n < 1) return t * o + a;
			{
				const f = r(n - 1, a);
				return i(n - 1, n % 2 != 0 ? (o + t - f % t) % t : (o + e - f % e) % e, a);
			}
		}, o = n % 2 != 0 ? a / t : a % t, f = n % 2 != 0 ? a % t : a / t;
		return i(n, f === t ? o : f, f === t ? f : o);
	};
	var I = {
		F: g,
		fe: b,
		Fe: y,
		feis: h,
		fein: (n) => {
			const t = (n) => {
				const e = 4294967295n & n, r = 18446744069414584320n & n;
				return n >= 65536n && n <= 4294967295n ? 65536n + h(n - 65536n) : n >= 4294967296n && n <= 18446744073709551615n ? r | t(e) : n;
			};
			return t(n);
		},
		fen: B,
		Fen: w,
		tail: x,
		fynd: (n) => {
			const t = (n) => {
				const e = 4294967295n & n, r = 18446744069414584320n & n;
				return n >= 65536n && n <= 4294967295n ? 65536n + x(n - 65536n) : n >= 4294967296n && n <= 18446744073709551615n ? r | t(e) : n;
			};
			return t(BigInt(n));
		}
	};
	const v = /^~([a-z]{3}|([a-z]{6}(\-[a-z]{6}){0,3}(\-(\-[a-z]{6}){4})*))$/;
	function S(n) {
		const t = N(n), e = (n) => n.toString(2).padStart(8, "0"), r = t.reduce(((n, r, a) => a % 2 != 0 || 1 === t.length ? n + e(E.indexOf(r)) : n + e(C.indexOf(r))), ""), a = BigInt("0b" + r);
		return I.fynd(a);
	}
	function $(n) {
		const t = I.fein(n), e = Math.ceil(t.toString(16).length / 2), r = Math.ceil(t.toString(16).length / 4);
		return "~" + (e <= 1 ? E[Number(t)] : function n(t, e, a) {
			const i = 65535n & t, o = C[Number(i >> 8n)], f = E[Number(255n & i)];
			return e === r ? a : n(t >> 16n, e + 1, o + f + (3 & e ? "-" : 0 === e ? "" : "--") + a);
		}(t, 0, ""));
	}
	function A(n) {
		let t;
		return t = "bigint" == typeof n ? n : z(n), t <= 255n ? "czar" : t <= 65535n ? "king" : t <= 4294967295n ? "duke" : t <= 18446744073709551615n ? "earl" : "pawn";
	}
	function k(n) {
		switch (n) {
			case "czar": return "galaxy";
			case "king": return "star";
			case "duke": return "planet";
			case "earl": return "moon";
			case "pawn": return "comet";
		}
	}
	function z(n) {
		if (!function(n) {
			return v.test(n) && j(n) && n === $(S(n));
		}(n)) throw new Error("invalid @p literal: " + n);
		return S(n);
	}
	const C = "\ndozmarbinwansamlitsighidfidlissogdirwacsabwissibrigsoldopmodfoglidhopdardorlorhodfolrintogsilmirholpaslacrovlivdalsatlibtabhanticpidtorbolfosdotlosdilforpilramtirwintadbicdifrocwidbisdasmidloprilnardapmolsanlocnovsitnidtipsicropwitnatpanminritpodmottamtolsavposnapnopsomfinfonbanmorworsipronnorbotwicsocwatdolmagpicdavbidbaltimtasmalligsivtagpadsaldivdactansidfabtarmonranniswolmispallasdismaprabtobrollatlonnodnavfignomnibpagsopralbilhaddocridmocpacravripfaltodtiltinhapmicfanpattaclabmogsimsonpinlomrictapfirhasbosbatpochactidhavsaplindibhosdabbitbarracparloddosbortochilmactomdigfilfasmithobharmighinradmashalraglagfadtopmophabnilnosmilfopfamdatnoldinhatnacrisfotribhocnimlarfitwalrapsarnalmoslandondanladdovrivbacpollaptalpitnambonrostonfodponsovnocsorlavmatmipfip".match(/.{1,3}/g), E = "\nzodnecbudwessevpersutletfulpensytdurwepserwylsunrypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnexlunmeplutseppesdelsulpedtemledtulmetwenbynhexfebpyldulhetmevruttylwydtepbesdexsefwycburderneppurrysrebdennutsubpetrulsynregtydsupsemwynrecmegnetsecmulnymtevwebsummutnyxrextebfushepbenmuswyxsymselrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpelsyptermebsetdutdegtexsurfeltudnuxruxrenwytnubmedlytdusnebrumtynseglyxpunresredfunrevrefmectedrusbexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermertenlusnussyltecmexpubrymtucfyllepdebbermughuttunbylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmylwedducfurfexnulluclennerlexrupnedlecrydlydfenwelnydhusrelrudneshesfetdesretdunlernyrsebhulrylludremlysfynwerrycsugnysnyllyndyndemluxfedsedbecmunlyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes".match(/.{1,3}/g);
	function N(n) {
		return n.replace(/[\^~-]/g, "").match(/.{1,3}/g) || [];
	}
	function j(n) {
		const t = N(n);
		return !(t.length % 2 != 0 && 1 !== t.length) && t.every(((n, e) => e % 2 != 0 || 1 === t.length ? E.includes(n) : C.includes(n)));
	}
	function _(n, t) {
		let e = [], r = [e];
		for (let a = 0; a < n.length; a++) e.length < t ? e.push(n[a]) : (e = [n[a]], r.push(e));
		return r;
	}
	function q(n, t) {
		return n = M(n), function(n, t, e) {
			if ("nan" === n) return function(n, t) {
				return O(BigInt(n + 1)) << BigInt(t - 1);
			}(t, e);
			if ("inf" === n) return U(!0, t, e);
			if ("-inf" === n) return U(!1, t, e);
			let r = 0, a = !0;
			"-" === n[r] && (a = !1, r++);
			let i = "";
			for (; "." !== n[r] && "e" !== n[r] && void 0 !== n[r];) i += n[r++];
			"." === n[r] && r++;
			let o = "";
			for (; "e" !== n[r] && void 0 !== n[r];) o += n[r++];
			"e" === n[r] && r++;
			let f = !0;
			"-" === n[r] && (f = !1, r++);
			let u = "";
			for (; void 0 !== n[r];) u += n[r++];
			return BigInt("0b" + function(n, t, e, r, a, i, o) {
				return 0 !== o && (i ? (r += a.padEnd(o, "0").slice(0, o), a = a.slice(o)) : (a = r.padStart(o, "0").slice(-o) + a, r = r.slice(0, -o))), function(n, t, e, r, a, i) {
					function o(n) {
						return console.warn(n), 1;
					}
					const f = 2 ** (t - 1) - 1, u = 1 - f, s = f, c = u - n, l = 2 * f + 1 + n + 3, d = new Array(l), m = 10n ** a;
					var p, g, h, y, b, x, w = 0, B = !e;
					for (p = l; p; d[--p] = 0);
					for (p = f + 2; r && p; d[--p] = 1n & r, r >>= 1n);
					for (p = f + 1; i > 0n && p < l; (d[++p] = (i *= 2n) >= m ? 1 : 0) && (i -= m));
					for (p = -1; ++p < l && !d[p];);
					if (d[(g = n - 1 + (p = (w = f + 1 - p) >= u && w <= s ? p + 1 : f + 1 - (w = u - 1))) + 1]) {
						if (!(h = d[g])) for (y = g + 2; !h && y < l; h = d[y++]);
						for (y = g + 1; h && --y >= 0; (d[y] = (d[y] ? 0 : 1) - 0) && (h = 0));
					}
					for (p = p - 2 < 0 ? -1 : p - 3; ++p < l && !d[p];);
					for ((w = f + 1 - p) >= u && w <= s ? ++p : w < u && (w != f + 1 - l && w < c && o("r.construct underflow"), p = f + 1 - (w = u - 1)), r && (o(r ? "r.construct overflow" : "r.construct"), w = s + 1, p = f + 2), x = Math.abs(w + f), y = t + 1, b = ""; --y; b = (1 & x) + b, x = x >>= 1);
					return (B ? "1" : "0") + b + d.slice(p, p + n).join("");
				}(t, n, e, BigInt(r), BigInt(a.length), BigInt(a));
			}(t, e, a, i, o, f, Number(u)));
		}(t.slice(n.l.length), n.w, n.p);
	}
	function F(n, t) {
		return (n = M(n)).l + function(n) {
			if ("n" === n.t) return "nan";
			if ("i" === n.t) return n.s ? "inf" : "-inf";
			let t;
			return n.e - 4 > 0 || n.e + 2 < 0 ? t = 1 : (t = n.e + 1, n.e = 0), (n.s ? "" : "-") + function(n, t) {
				const e = Math.abs(n);
				if (n <= 0) return "0." + "".padEnd(e, "0") + t;
				{
					const n = t.length;
					return e >= n ? t + "".padEnd(e - n, "0") : t.slice(0, e) + "." + t.slice(e);
				}
			}(t, n.a) + (0 === n.e ? "" : "e" + n.e.toString());
		}(function(n, t, e) {
			const r = O(e), a = O(t), i = n & r, o = n >> BigInt(e) & a, f = 0n === (n >> BigInt(t + e) & 1n);
			let u, s, c, l;
			if (o === a) return 0n === i ? {
				t: "i",
				s: f
			} : { t: "n" };
			0n !== o ? (u = 1n << BigInt(e) | i, s = o - (2n ** (t - 1n) - 1n) - e, c = Number(e), l = 1n !== o && 0n === i) : (u = i, s = 1n - (2n ** (t - 1n) - 1n) - e, c = u.toString(2).length - 1, l = !1);
			const d = (2n ** e).toString(10).length + 1, m = function(n, t, e, r, a, i, o) {
				const f = BigInt(t);
				let u, s, c, l, d = 0, m = new Array(o).fill("0"), p = 0;
				if (0n === n) return m[0] = "0", p = 0, {
					digits: m.slice(0, 1).join(""),
					outExponent: p
				};
				r ? t > 0 ? (s = 4n * n, s <<= f, u = 4n, c = 1n << f, l = 1n << f + 1n) : (s = 4n * n, u = 1n << -f + 2n, c = 1n, l = 2n) : t > 0 ? (s = 2n * n, s <<= f, u = 2n, c = 1n << f, l = c) : (s = 2n * n, u = 1n << BigInt(1 - t), c = 1n, l = c);
				let g = Math.ceil(.3010299956639812 * (e + t) - .69);
				if (g > 0) u *= BigInt(10) ** BigInt(g);
				else if (g < 0) {
					const n = BigInt(10) ** BigInt(-g);
					s *= n, c *= n, l !== c && (l *= c);
				}
				s >= u ? g += 1 : (s *= 10n, c *= 10n, l !== c && (l *= 10n));
				let h = g - o;
				p = g - 1;
				let y = !1, b = !1, x = 0;
				for (; g -= 1, x = Number(s / u), s %= u, y = s < c, b = s + l > u, !y && !b && g !== h;) m[d] = String.fromCharCode("0".charCodeAt(0) + x), d += 1, s *= 10n, c *= 10n, l !== c && (l *= 10n);
				let w = y;
				if (y === b) {
					s *= 2n;
					let n = s < u ? -1 : s > u ? 1 : 0;
					w = n < 0, 0 === n && (w = 0 == (1 & x));
				}
				if (w) m[d] = String.fromCharCode("0".charCodeAt(0) + x), d += 1;
				else if (9 === x) for (;;) {
					if (0 === d) {
						m[d] = "1", d += 1, p += 1;
						break;
					}
					if (d -= 1, "9" !== m[d]) {
						m[d] = String.fromCharCode(m[d].charCodeAt(0) + 1), d += 1;
						break;
					}
				}
				else m[d] = String.fromCharCode("0".charCodeAt(0) + x + 1), d += 1;
				return {
					digits: m.slice(0, d).join(""),
					outExponent: p
				};
			}(u, Number(s), c, l, 0, 0, d);
			return {
				t: "d",
				s: f,
				e: m.outExponent,
				a: m.digits
			};
		}(t, BigInt(n.w), BigInt(n.p)));
	}
	function M(n) {
		return "h" === n ? {
			w: 5,
			p: 10,
			l: ".~~"
		} : "s" === n ? {
			w: 8,
			p: 23,
			l: "."
		} : "d" === n ? {
			w: 11,
			p: 52,
			l: ".~"
		} : "q" === n ? {
			w: 15,
			p: 112,
			l: ".~~~"
		} : n;
	}
	function O(n) {
		return 2n ** n - 1n;
	}
	function U(n, t, e) {
		return O(BigInt(n ? t : t + 1)) << BigInt(e);
	}
	function Z(n, t, e, r, a) {
		return void 0 === a && (a = !1), new RegExp(`^${a ? "\\-\\-?" : ""}${n}(0|${0 === r ? t : `${t}${e}{0,${r - 1}}`}${0 === r ? `${e}*` : `(\\.${e}{${r}})*`})$`);
	}
	function P(n) {
		return new RegExp(`^\\.~{${n}}(nan|\\-?(inf|(0|[1-9][0-9]*)(\\.[0-9]+)?(e\\-?(0|[1-9][0-9]*))?))$`);
	}
	const R = {
		c: /^~\-((~[0-9a-fA-F]+\.)|(~[~\.])|[0-9a-z\-\._])*$/,
		da: /^~(0|[1-9][0-9]*)\-?\.0*([1-9]|1[0-2])\.0*[1-9][0-9]*(\.\.([0-9]+)\.([0-9]+)\.([0-9]+)(\.(\.[0-9a-f]{4})+)?)?$/,
		dr: /^~((d|h|m|s)(0|[1-9][0-9]*))(\.(d|h|m|s)(0|[1-9][0-9]*))*(\.(\.[0-9a-f]{4})+)?$/,
		f: /^\.(y|n)$/,
		if: /^(\.(0|[1-9][0-9]{0,2})){4}$/,
		is: /^(\.(0|[1-9a-fA-F][0-9a-fA-F]{0,3})){8}$/,
		n: /^~$/,
		p: v,
		q: /^\.~(([a-z]{3}|[a-z]{6})(\-[a-z]{6})*)$/,
		rd: P(1),
		rh: P(2),
		rq: P(3),
		rs: P(0),
		sb: Z("0b", "1", "[01]", 4, !0),
		sd: Z("", "[1-9]", "[0-9]", 3, !0),
		si: Z("0i", "[1-9]", "[0-9]", 0, !0),
		sv: Z("0v", "[1-9a-v]", "[0-9a-v]", 5, !0),
		sw: Z("0w", "[1-9a-zA-Z~-]", "[0-9a-zA-Z~-]", 5, !0),
		sx: Z("0x", "[1-9a-f]", "[0-9a-f]", 4, !0),
		t: /^~~((~[0-9a-fA-F]+\.)|(~[~\.])|[0-9a-z\-\._])*$/,
		ta: /^~\.[0-9a-z\-\.~_]*$/,
		tas: /^[a-z][a-z0-9\-]*$/,
		ub: Z("0b", "1", "[01]", 4),
		ud: Z("", "[1-9]", "[0-9]", 3),
		ui: Z("0i", "[1-9]", "[0-9]", 0),
		uv: Z("0v", "[1-9a-v]", "[0-9a-v]", 5),
		uw: Z("0w", "[1-9a-zA-Z~-]", "[0-9a-zA-Z~-]", 5),
		ux: Z("0x", "[1-9a-f]", "[0-9a-f]", 4)
	}, T = D;
	function D(n, t) {
		const e = H(n, t);
		if (!e) throw new Error("slav: failed to parse @" + n + " from string: " + t);
		return e;
	}
	const G = H;
	function H(n, t) {
		if (n in R && !R[n].test(t)) return null;
		const e = J(t);
		return e && "dime" === e.type && e.aura === n ? e.atom : null;
	}
	function J(e) {
		if ("" === e) return null;
		const r = e[0];
		if (r >= "a" && r <= "z") return R.tas.test(e) ? {
			type: "dime",
			aura: "tas",
			atom: Q(e)
		} : null;
		if (r >= "0" && r <= "9") {
			const n = K(e);
			return n ? {
				type: "dime",
				...n
			} : null;
		}
		if ("-" === r) {
			let n = !0;
			"-" == e[1] ? e = e.slice(2) : (e = e.slice(1), n = !1);
			const t = K(e);
			return t ? (n ? t.atom = 2n * t.atom : 0n !== t.atom && (t.atom = 1n + 2n * (t.atom - 1n)), {
				type: "dime",
				aura: t.aura.replace("u", "s"),
				atom: t.atom
			}) : null;
		}
		if ("." === r) {
			if (".y" === e) return {
				type: "dime",
				aura: "f",
				atom: 0n
			};
			if (".n" === e) return {
				type: "dime",
				aura: "f",
				atom: 1n
			};
			if (R.is.test(e)) {
				const n = e.slice(1).split(".").reduce(((n, t) => n + t.padStart(4, "0")), "");
				return {
					type: "dime",
					aura: "is",
					atom: BigInt("0x" + n)
				};
			}
			if (R.if.test(e)) return {
				type: "dime",
				aura: "if",
				atom: e.slice(1).split(".").reduce(((n, t, e) => n + (BigInt(t) << BigInt(8 * (3 - e)))), 0n)
			};
			if ("~" === e[1] && (R.rd.test(e) || R.rh.test(e) || R.rq.test(e)) || R.rs.test(e)) {
				let n, t = 0;
				for (; "~" === e[t + 1];) t++;
				switch (t) {
					case 0:
						n = "rs";
						break;
					case 1:
						n = "rd";
						break;
					case 2:
						n = "rh";
						break;
					case 3:
						n = "rq";
						break;
					default: throw new Error("parsing invalid @r*");
				}
				return {
					type: "dime",
					aura: n,
					atom: q(n[1], e)
				};
			}
			if ("~" === e[1] && R.q.test(e)) {
				const n = function(n) {
					try {
						return function(n) {
							const t = n.slice(2).split("-"), e = (n) => {
								if (n < 0) throw new Error("malformed @q");
								return n.toString(16).padStart(2, "0");
							}, r = t.map(((n, t) => {
								let r = function(n, t) {
									return [t.slice(0, 3), t.slice(3)];
								}(0, n);
								return "" === r[1] && 0 === t ? e(E.indexOf(r[0])) : e(C.indexOf(r[0])) + e(E.indexOf(r[1]));
							}));
							return BigInt("0x" + (0 === n.length ? "00" : r.join("")));
						}(n);
					} catch (n) {
						return null;
					}
				}(e);
				return null === n ? null : {
					type: "dime",
					aura: "q",
					atom: n
				};
			}
			if ("_" === e[1] && /^\.(_([0-9a-zA-Z\-\.]|~\-|~~)+)*__$/.test(e)) {
				const n = e.slice(1, -2).split("_").slice(1).map(((n) => J(n = n.replaceAll("~-", "_").replaceAll("~~", "~"))));
				return n.some(((n) => null === n)) ? null : {
					type: "many",
					list: n
				};
			}
			return null;
		}
		if ("~" === r) {
			if ("~" === e) return {
				type: "dime",
				aura: "n",
				atom: 0n
			};
			if (R.da.test(e)) return {
				type: "dime",
				aura: "da",
				atom: n(e)
			};
			if (R.dr.test(e)) return {
				type: "dime",
				aura: "dr",
				atom: t(e)
			};
			if (R.p.test(e)) {
				const n = function(n) {
					if (!v.test(n) || !j(n)) return null;
					const t = S(n);
					return n === $(t) ? t : null;
				}(e);
				return null === n ? null : {
					type: "dime",
					aura: "p",
					atom: n
				};
			}
			return "." === e[1] && R.ta.test(e) ? {
				type: "dime",
				aura: "ta",
				atom: Q(e.slice(2))
			} : "~" === e[1] && R.t.test(e) ? {
				type: "dime",
				aura: "t",
				atom: Q(L(e.slice(2)))
			} : "-" === e[1] && R.c.test(e) ? /^~\-~[0-9a-f]+\.$/.test(e) ? {
				type: "dime",
				aura: "c",
				atom: BigInt("0x" + e.slice(3, -1))
			} : {
				type: "dime",
				aura: "c",
				atom: Q(L(e.slice(2)))
			} : "0" === e[1] && /^~0[0-9a-v]+$/.test(e) ? {
				type: "blob",
				jam: X(5, W, e.slice(2))
			} : null;
		}
		return null;
	}
	function K(n) {
		switch (n.slice(0, 2)) {
			case "0b": return R.ub.test(n) ? {
				aura: "ub",
				atom: BigInt(n.replaceAll(".", ""))
			} : null;
			case "0c": return console.log("aura-js: @uc parsing unsupported (bisk)"), null;
			case "0i": return R.ui.test(n) ? {
				aura: "ui",
				atom: BigInt(n.slice(2))
			} : null;
			case "0x": return R.ux.test(n) ? {
				aura: "ux",
				atom: BigInt(n.replaceAll(".", ""))
			} : null;
			case "0v": return R.uv.test(n) ? {
				aura: "uv",
				atom: X(5, W, n.slice(2))
			} : null;
			case "0w": return R.uw.test(n) ? {
				aura: "uw",
				atom: X(6, V, n.slice(2))
			} : null;
			default: return R.ud.test(n) ? {
				aura: "ud",
				atom: BigInt(n.replaceAll(".", ""))
			} : null;
		}
	}
	function L(n) {
		let t = "", e = 0;
		for (; e < n.length;) switch (n[e]) {
			case ".":
				t += " ", e++;
				continue;
			case "~": switch (n[++e]) {
				case "~":
					t += "~", e++;
					continue;
				case ".":
					t += ".", e++;
					continue;
				default:
					let r = 0;
					do
						r = r << 4 | Number.parseInt(n[e++], 16);
					while ("." !== n[e]);
					t += String.fromCodePoint(r), e++;
					continue;
			}
			default:
				t += n[e++];
				continue;
		}
		return t;
	}
	function Q(n) {
		return function(n) {
			if (0 === n.length) return 0n;
			if ("undefined" != typeof Buffer) return BigInt("0x" + Buffer.from(n.reverse()).toString("hex"));
			let t, e = [];
			for (var r = n.length - 1; r >= 0; --r) t = n[r], e.push(t < 16 ? "0" + t.toString(16) : t.toString(16));
			return BigInt("0x" + e.join(""));
		}(new TextEncoder().encode(n));
	}
	const V = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~", W = "0123456789abcdefghijklmnopqrstuv";
	function X(n, t, e) {
		let r = 0n;
		const a = BigInt(n);
		for (; "" !== e;) "." !== e[0] && (r = (r << a) + BigInt(t.indexOf(e[0]))), e = e.slice(1);
		return r;
	}
	const Y = nn;
	function nn(n, t) {
		return tn({
			type: "dime",
			aura: n,
			atom: t
		});
	}
	function tn(n) {
		switch (n.type) {
			case "blob": return "~0" + n.jam.toString(32);
			case "many": return "." + n.list.reduce(((n, t) => n + "_" + tn(t).replaceAll("~", "~~").replaceAll("_", "~-")), "") + "__";
			case "dime": switch (n.aura[0]) {
				case "c": return n.atom < 127n ? "~-" + rn(String.fromCharCode(Number(n.atom))) : "~-~" + n.atom.toString(16) + ".";
				case "d": switch (n.aura[1]) {
					case "a": return function(n) {
						const { pos: t, year: e, month: r, time: i } = function(n) {
							const t = p(n), [e, r, i] = function(n) {
								let t = 0n, e = 0n, r = !1;
								t = n / l, (n %= l) < d + 1n ? r = !0 : (r = !1, e = 1n, e += (n -= d + 1n) / d, n %= d);
								let a = 400n * t + 100n * e, i = !0;
								for (; 1 == i;) {
									let t = r ? 366n : 365n;
									if (n < t) {
										i = !1;
										let e = 0n;
										for (;;) {
											let t = BigInt((r ? f : o)[Number(e)]);
											if (n < t) return [
												a,
												e + 1n,
												n + 1n
											];
											e += 1n, n -= t;
										}
									} else a += 1n, n -= t, r = a % 4n === 0n;
								}
								return [
									0n,
									0n,
									0n
								];
							}(t.day);
							t.day = i;
							const u = e > a;
							return {
								pos: u,
								year: u ? e - a : a + 1n - e,
								month: r,
								time: t
							};
						}(n);
						let u = `~${e}${t ? "" : "-"}.${r}.${i.day}`;
						return 0n === i.hour && 0n === i.minute && 0n === i.second && 0 === i.ms.length || (u += `..${i.hour.toString().padStart(2, "0")}.${i.minute.toString().padStart(2, "0")}.${i.second.toString().padStart(2, "0")}`, 0 !== i.ms.length && (u += `..${i.ms.map(((n) => n.toString(16).padStart(4, "0"))).join(".")}`)), u;
					}(n.atom);
					case "r": return function(n) {
						if (0n === n) return "~s0";
						const { day: t, hour: e, minute: r, second: a, ms: i } = p(n);
						let o = [];
						return 0n !== t && o.push("d" + t.toString()), 0n !== e && o.push("h" + e.toString()), 0n !== r && o.push("m" + r.toString()), 0n !== a && o.push("s" + a.toString()), 0 !== i.length && (0 === o.length && o.push("s0"), o.push("." + i.map(((n) => n.toString(16).padStart(4, "0"))).join("."))), "~" + o.join(".");
					}(n.atom);
					default: return en(n.atom);
				}
				case "f": switch (n.atom) {
					case 0n: return ".y";
					case 1n: return ".n";
					default: return en(n.atom);
				}
				case "n": return "~";
				case "i": switch (n.aura[1]) {
					case "f": return "." + fn(n.atom, 1, 4, 10);
					case "s": return "." + fn(n.atom, 2, 8, 16);
					default: return en(n.atom);
				}
				case "p": return $(n.atom);
				case "q": return function(n) {
					const t = n.toString(16), e = t.length, r = Buffer.from(t.padStart(e + e % 2, "0"), "hex"), a = r.length % 2 != 0 && r.length > 1 ? [[r[0]]].concat(_(Array.from(r.slice(1)), 2)) : _(Array.from(r), 2);
					return a.reduce(((n, t) => {
						return n + (".~" === n ? "" : "-") + ((e = t).length % 2 != 0 && a.length > 1 ? void 0 === (r = e)[1] ? E[r[0]] : C[r[0]] + E[r[1]] : ((n) => void 0 === n[1] ? E[n[0]] : C[n[0]] + E[n[1]])(e));
						var e, r;
					}), ".~");
				}(n.atom);
				case "r": switch (n.aura[1]) {
					case "d": return F("d", n.atom);
					case "h": return F("h", n.atom);
					case "q": return F("q", n.atom);
					case "s": return F("s", n.atom);
					default: return en(n.atom);
				}
				case "u": switch (n.aura[1]) {
					case "c": throw new Error("aura-js: @uc rendering unsupported");
					case "b": return "0b" + on(n.atom.toString(2), 4);
					case "i": return "0i" + n.atom.toString(10).padStart(1, "0");
					case "x": return "0x" + on(n.atom.toString(16), 4);
					case "v": return "0v" + on(n.atom.toString(32), 5);
					case "w": return "0w" + on(function(n, t, e) {
						if (0n === e) return t[0];
						let r = "";
						const a = BigInt(6);
						for (; 0n !== e;) r = t[Number(BigInt.asUintN(6, e))] + r, e >>= a;
						return r;
					}(0, an, n.atom), 5);
					default: return on(n.atom.toString(10), 3);
				}
				case "s":
					const t = 1n & n.atom;
					return n.atom = t + (n.atom >> 1n), n.aura = n.aura.replace("s", "u"), (0n === t ? "--" : "-") + tn(n);
				case "t": return "a" === n.aura[1] ? "s" === n.aura[2] ? un(n.atom) : "~." + un(n.atom) : "~~" + rn(un(n.atom));
				default: return en(n.atom);
			}
		}
	}
	function en(n) {
		return "0x" + function(n, t) {
			return t.toString(16).padStart(1, "0");
		}(0, n);
	}
	function rn(n) {
		let t = "";
		for (let e = 0; e < n.length; e += 1) {
			const r = n[e];
			let a = "";
			switch (r) {
				case " ":
					a = ".";
					break;
				case ".":
					a = "~.";
					break;
				case "~":
					a = "~~";
					break;
				default: {
					const t = n.codePointAt(e);
					if (!t) break;
					t > 65535 && (e += 1), a = t >= 97 && t <= 122 || t >= 48 && t <= 57 || "-" === r ? r : `~${t.toString(16)}.`;
				}
			}
			t += a;
		}
		return t;
	}
	const an = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~";
	function on(n, t) {
		return n.replace(new RegExp(`(?=(?:.{${t}})+$)(?!^)`, "g"), ".");
	}
	function fn(n, t, e, r) {
		void 0 === r && (r = 10);
		let a = "";
		const i = 8n * BigInt(t), o = (1n << i) - 1n;
		for (; e-- > 0;) "" !== a && (a = "." + a), a = (n & o).toString(r) + a, n >>= i;
		return a;
	}
	function un(n) {
		return new TextDecoder("utf-8").decode(function(n) {
			if (0n === n) return new Uint8Array(0);
			const t = n.toString(16), e = t.length % 2 == 0 ? t : "0" + t, r = new Uint8Array(e.length / 2);
			for (let n = 0; n < e.length; n += 2) {
				const t = e.slice(n, n + 2), a = parseInt(t, 16) << 24 >> 24;
				r[n / 2] = a;
			}
			return r;
		}(n).reverse());
	}
	const sn = {
		toSeconds: function(n) {
			const { day: t, hour: e, minute: r, second: a } = p(n);
			return 60n * (60n * (24n * t + e) + r) + a;
		},
		fromSeconds: function(n) {
			return m({
				day: 0n,
				hour: 0n,
				minute: 0n,
				second: n,
				ms: []
			});
		}
	}, cn = {
		cite: function(n) {
			let t;
			return t = "bigint" == typeof n ? n : z(n), t <= 4294967295n ? $(t) : t <= 18446744073709551615n ? $(4294967295n & t).replace("-", "^") : $(BigInt("0x" + t.toString(16).slice(0, 4))) + "_" + $(65535n & t).slice(1);
		},
		sein: function(n) {
			let t;
			t = "bigint" == typeof n ? n : z(n);
			let e = A(t);
			const r = "czar" === e ? t : "king" === e ? 255n & t : "duke" === e ? 65535n & t : "earl" === e ? 4294967295n & t : 65535n & t;
			return "bigint" == typeof n ? r : $(r);
		},
		clan: A,
		kind: function(n) {
			return k(A(n));
		},
		rankToSize: k,
		sizeToRank: function(n) {
			switch (n) {
				case "galaxy": return "czar";
				case "star": return "king";
				case "planet": return "duke";
				case "moon": return "earl";
				case "comet": return "pawn";
			}
		}
	};
	exports.da = {
		toUnix: function(n) {
			return Math.round(Number(1000n * (r / 2000n + (n - e)) / r));
		},
		fromUnix: function(n) {
			return e + BigInt(n) * r / 1000n;
		}
	}, exports.dr = sn, exports.nuck = J, exports.p = cn, exports.parse = T, exports.rend = tn, exports.render = Y, exports.scot = nn, exports.slav = D, exports.slaw = H, exports.tryParse = G, exports.valid = function(n, t) {
		return null !== H(n, t);
	};
}));

//#endregion
//#region node_modules/.pnpm/@urbit+aura@3.0.0/node_modules/@urbit/aura/dist/index.js
var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
	module.exports = require_aura_cjs_production_min();
}));

//#endregion
//#region extensions/tlon/src/urbit/send.ts
var import_dist = require_dist();
async function sendDm({ api, fromShip, toShip, text }) {
	const story = [{ inline: [text] }];
	const sentAt = Date.now();
	const id = `${fromShip}/${(0, import_dist.scot)("ud", import_dist.da.fromUnix(sentAt))}`;
	const action = {
		ship: toShip,
		diff: {
			id,
			delta: { add: {
				memo: {
					content: story,
					author: fromShip,
					sent: sentAt
				},
				kind: null,
				time: null
			} }
		}
	};
	await api.poke({
		app: "chat",
		mark: "chat-dm-action",
		json: action
	});
	return {
		channel: "tlon",
		messageId: id
	};
}
async function sendGroupMessage({ api, fromShip, hostShip, channelName, text, replyToId }) {
	const story = [{ inline: [text] }];
	const sentAt = Date.now();
	let formattedReplyId = replyToId;
	if (replyToId && /^\d+$/.test(replyToId)) try {
		formattedReplyId = (0, import_dist.scot)("ud", BigInt(replyToId));
	} catch {}
	const action = { channel: {
		nest: `chat/${hostShip}/${channelName}`,
		action: formattedReplyId ? { post: { reply: {
			id: formattedReplyId,
			action: { add: {
				content: story,
				author: fromShip,
				sent: sentAt
			} }
		} } } : { post: { add: {
			content: story,
			author: fromShip,
			sent: sentAt,
			kind: "/chat",
			blob: null,
			meta: null
		} } }
	} };
	await api.poke({
		app: "channels",
		mark: "channel-action-1",
		json: action
	});
	return {
		channel: "tlon",
		messageId: `${fromShip}/${sentAt}`
	};
}
function buildMediaText(text, mediaUrl) {
	const cleanText = text?.trim() ?? "";
	const cleanUrl = mediaUrl?.trim() ?? "";
	if (cleanText && cleanUrl) return `${cleanText}\n${cleanUrl}`;
	if (cleanUrl) return cleanUrl;
	return cleanText;
}

//#endregion
//#region extensions/tlon/src/urbit/channel-ops.ts
async function pokeUrbitChannel(deps, params) {
	const pokeId = Date.now();
	const pokeData = {
		id: pokeId,
		action: "poke",
		ship: deps.ship,
		app: params.app,
		mark: params.mark,
		json: params.json
	};
	const { response, release } = await urbitFetch({
		baseUrl: deps.baseUrl,
		path: `/~/channel/${deps.channelId}`,
		init: {
			method: "PUT",
			headers: {
				"Content-Type": "application/json",
				Cookie: deps.cookie
			},
			body: JSON.stringify([pokeData])
		},
		ssrfPolicy: deps.ssrfPolicy,
		lookupFn: deps.lookupFn,
		fetchImpl: deps.fetchImpl,
		timeoutMs: 3e4,
		auditContext: params.auditContext
	});
	try {
		if (!response.ok && response.status !== 204) {
			const errorText = await response.text().catch(() => "");
			throw new Error(`Poke failed: ${response.status}${errorText ? ` - ${errorText}` : ""}`);
		}
		return pokeId;
	} finally {
		await release();
	}
}
async function scryUrbitPath(deps, params) {
	const scryPath = `/~/scry${params.path}`;
	const { response, release } = await urbitFetch({
		baseUrl: deps.baseUrl,
		path: scryPath,
		init: {
			method: "GET",
			headers: { Cookie: deps.cookie }
		},
		ssrfPolicy: deps.ssrfPolicy,
		lookupFn: deps.lookupFn,
		fetchImpl: deps.fetchImpl,
		timeoutMs: 3e4,
		auditContext: params.auditContext
	});
	try {
		if (!response.ok) throw new Error(`Scry failed: ${response.status} for path ${params.path}`);
		return await response.json();
	} finally {
		await release();
	}
}
async function createUrbitChannel(deps, params) {
	const { response, release } = await urbitFetch({
		baseUrl: deps.baseUrl,
		path: `/~/channel/${deps.channelId}`,
		init: {
			method: "PUT",
			headers: {
				"Content-Type": "application/json",
				Cookie: deps.cookie
			},
			body: JSON.stringify(params.body)
		},
		ssrfPolicy: deps.ssrfPolicy,
		lookupFn: deps.lookupFn,
		fetchImpl: deps.fetchImpl,
		timeoutMs: 3e4,
		auditContext: params.auditContext
	});
	try {
		if (!response.ok && response.status !== 204) throw new UrbitHttpError({
			operation: "Channel creation",
			status: response.status
		});
	} finally {
		await release();
	}
}
async function wakeUrbitChannel(deps) {
	const { response, release } = await urbitFetch({
		baseUrl: deps.baseUrl,
		path: `/~/channel/${deps.channelId}`,
		init: {
			method: "PUT",
			headers: {
				"Content-Type": "application/json",
				Cookie: deps.cookie
			},
			body: JSON.stringify([{
				id: Date.now(),
				action: "poke",
				ship: deps.ship,
				app: "hood",
				mark: "helm-hi",
				json: "Opening API channel"
			}])
		},
		ssrfPolicy: deps.ssrfPolicy,
		lookupFn: deps.lookupFn,
		fetchImpl: deps.fetchImpl,
		timeoutMs: 3e4,
		auditContext: "tlon-urbit-channel-wake"
	});
	try {
		if (!response.ok && response.status !== 204) throw new UrbitHttpError({
			operation: "Channel activation",
			status: response.status
		});
	} finally {
		await release();
	}
}
async function ensureUrbitChannelOpen(deps, params) {
	await createUrbitChannel(deps, {
		body: params.createBody,
		auditContext: params.createAuditContext
	});
	await wakeUrbitChannel(deps);
}

//#endregion
//#region extensions/tlon/src/urbit/sse-client.ts
var UrbitSSEClient = class {
	constructor(url, cookie, options = {}) {
		this.subscriptions = [];
		this.eventHandlers = /* @__PURE__ */ new Map();
		this.aborted = false;
		this.streamController = null;
		this.reconnectAttempts = 0;
		this.isConnected = false;
		this.streamRelease = null;
		const ctx = getUrbitContext(url, options.ship);
		this.url = ctx.baseUrl;
		this.cookie = normalizeUrbitCookie(cookie);
		this.ship = ctx.ship;
		this.channelId = `${Math.floor(Date.now() / 1e3)}-${Math.random().toString(36).substring(2, 8)}`;
		this.channelUrl = new URL(`/~/channel/${this.channelId}`, this.url).toString();
		this.onReconnect = options.onReconnect ?? null;
		this.autoReconnect = options.autoReconnect !== false;
		this.maxReconnectAttempts = options.maxReconnectAttempts ?? 10;
		this.reconnectDelay = options.reconnectDelay ?? 1e3;
		this.maxReconnectDelay = options.maxReconnectDelay ?? 3e4;
		this.logger = options.logger ?? {};
		this.ssrfPolicy = options.ssrfPolicy;
		this.lookupFn = options.lookupFn;
		this.fetchImpl = options.fetchImpl;
	}
	async subscribe(params) {
		const subId = this.subscriptions.length + 1;
		const subscription = {
			id: subId,
			action: "subscribe",
			ship: this.ship,
			app: params.app,
			path: params.path
		};
		this.subscriptions.push(subscription);
		this.eventHandlers.set(subId, {
			event: params.event,
			err: params.err,
			quit: params.quit
		});
		if (this.isConnected) try {
			await this.sendSubscription(subscription);
		} catch (error) {
			this.eventHandlers.get(subId)?.err?.(error);
		}
		return subId;
	}
	async sendSubscription(subscription) {
		const { response, release } = await urbitFetch({
			baseUrl: this.url,
			path: `/~/channel/${this.channelId}`,
			init: {
				method: "PUT",
				headers: {
					"Content-Type": "application/json",
					Cookie: this.cookie
				},
				body: JSON.stringify([subscription])
			},
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl,
			timeoutMs: 3e4,
			auditContext: "tlon-urbit-subscribe"
		});
		try {
			if (!response.ok && response.status !== 204) {
				const errorText = await response.text().catch(() => "");
				throw new Error(`Subscribe failed: ${response.status}${errorText ? ` - ${errorText}` : ""}`);
			}
		} finally {
			await release();
		}
	}
	async connect() {
		await ensureUrbitChannelOpen({
			baseUrl: this.url,
			cookie: this.cookie,
			ship: this.ship,
			channelId: this.channelId,
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl
		}, {
			createBody: this.subscriptions,
			createAuditContext: "tlon-urbit-channel-create"
		});
		await this.openStream();
		this.isConnected = true;
		this.reconnectAttempts = 0;
	}
	async openStream() {
		const controller = new AbortController();
		const timeoutId = setTimeout(() => controller.abort(), 6e4);
		this.streamController = controller;
		const { response, release } = await urbitFetch({
			baseUrl: this.url,
			path: `/~/channel/${this.channelId}`,
			init: {
				method: "GET",
				headers: {
					Accept: "text/event-stream",
					Cookie: this.cookie
				}
			},
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl,
			signal: controller.signal,
			auditContext: "tlon-urbit-sse-stream"
		});
		this.streamRelease = release;
		clearTimeout(timeoutId);
		if (!response.ok) {
			await release();
			this.streamRelease = null;
			throw new Error(`Stream connection failed: ${response.status}`);
		}
		this.processStream(response.body).catch((error) => {
			if (!this.aborted) {
				this.logger.error?.(`Stream error: ${String(error)}`);
				for (const { err } of this.eventHandlers.values()) if (err) err(error);
			}
		});
	}
	async processStream(body) {
		if (!body) return;
		const stream = body instanceof ReadableStream ? Readable.fromWeb(body) : body;
		let buffer = "";
		try {
			for await (const chunk of stream) {
				if (this.aborted) break;
				buffer += chunk.toString();
				let eventEnd;
				while ((eventEnd = buffer.indexOf("\n\n")) !== -1) {
					const eventData = buffer.substring(0, eventEnd);
					buffer = buffer.substring(eventEnd + 2);
					this.processEvent(eventData);
				}
			}
		} finally {
			if (this.streamRelease) {
				const release = this.streamRelease;
				this.streamRelease = null;
				await release();
			}
			this.streamController = null;
			if (!this.aborted && this.autoReconnect) {
				this.isConnected = false;
				this.logger.log?.("[SSE] Stream ended, attempting reconnection...");
				await this.attemptReconnect();
			}
		}
	}
	processEvent(eventData) {
		const lines = eventData.split("\n");
		let data = null;
		for (const line of lines) if (line.startsWith("data: ")) data = line.substring(6);
		if (!data) return;
		try {
			const parsed = JSON.parse(data);
			if (parsed.response === "quit") {
				if (parsed.id) {
					const handlers = this.eventHandlers.get(parsed.id);
					if (handlers?.quit) handlers.quit();
				}
				return;
			}
			if (parsed.id && this.eventHandlers.has(parsed.id)) {
				const { event } = this.eventHandlers.get(parsed.id) ?? {};
				if (event && parsed.json) event(parsed.json);
			} else if (parsed.json) {
				for (const { event } of this.eventHandlers.values()) if (event) event(parsed.json);
			}
		} catch (error) {
			this.logger.error?.(`Error parsing SSE event: ${String(error)}`);
		}
	}
	async poke(params) {
		return await pokeUrbitChannel({
			baseUrl: this.url,
			cookie: this.cookie,
			ship: this.ship,
			channelId: this.channelId,
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl
		}, {
			...params,
			auditContext: "tlon-urbit-poke"
		});
	}
	async scry(path) {
		return await scryUrbitPath({
			baseUrl: this.url,
			cookie: this.cookie,
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl
		}, {
			path,
			auditContext: "tlon-urbit-scry"
		});
	}
	async attemptReconnect() {
		if (this.aborted || !this.autoReconnect) {
			this.logger.log?.("[SSE] Reconnection aborted or disabled");
			return;
		}
		if (this.reconnectAttempts >= this.maxReconnectAttempts) {
			this.logger.error?.(`[SSE] Max reconnection attempts (${this.maxReconnectAttempts}) reached. Giving up.`);
			return;
		}
		this.reconnectAttempts += 1;
		const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1), this.maxReconnectDelay);
		this.logger.log?.(`[SSE] Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms...`);
		await new Promise((resolve) => setTimeout(resolve, delay));
		try {
			this.channelId = `${Math.floor(Date.now() / 1e3)}-${Math.random().toString(36).substring(2, 8)}`;
			this.channelUrl = new URL(`/~/channel/${this.channelId}`, this.url).toString();
			if (this.onReconnect) await this.onReconnect(this);
			await this.connect();
			this.logger.log?.("[SSE] Reconnection successful!");
		} catch (error) {
			this.logger.error?.(`[SSE] Reconnection failed: ${String(error)}`);
			await this.attemptReconnect();
		}
	}
	async close() {
		this.aborted = true;
		this.isConnected = false;
		this.streamController?.abort();
		try {
			const unsubscribes = this.subscriptions.map((sub) => ({
				id: sub.id,
				action: "unsubscribe",
				subscription: sub.id
			}));
			{
				const { response, release } = await urbitFetch({
					baseUrl: this.url,
					path: `/~/channel/${this.channelId}`,
					init: {
						method: "PUT",
						headers: {
							"Content-Type": "application/json",
							Cookie: this.cookie
						},
						body: JSON.stringify(unsubscribes)
					},
					ssrfPolicy: this.ssrfPolicy,
					lookupFn: this.lookupFn,
					fetchImpl: this.fetchImpl,
					timeoutMs: 3e4,
					auditContext: "tlon-urbit-unsubscribe"
				});
				try {
					response.body?.cancel();
				} finally {
					await release();
				}
			}
			{
				const { response, release } = await urbitFetch({
					baseUrl: this.url,
					path: `/~/channel/${this.channelId}`,
					init: {
						method: "DELETE",
						headers: { Cookie: this.cookie }
					},
					ssrfPolicy: this.ssrfPolicy,
					lookupFn: this.lookupFn,
					fetchImpl: this.fetchImpl,
					timeoutMs: 3e4,
					auditContext: "tlon-urbit-channel-close"
				});
				try {
					response.body?.cancel();
				} finally {
					await release();
				}
			}
		} catch (error) {
			this.logger.error?.(`Error closing channel: ${String(error)}`);
		}
		if (this.streamRelease) {
			const release = this.streamRelease;
			this.streamRelease = null;
			await release();
		}
	}
};

//#endregion
//#region extensions/tlon/src/monitor/utils.ts
function formatModelName(modelString) {
	if (!modelString) return "AI";
	const modelName = modelString.includes("/") ? modelString.split("/")[1] : modelString;
	const modelMappings = {
		"claude-opus-4-6": "Claude Opus 4.6",
		"claude-opus-4-5": "Claude Opus 4.5",
		"claude-sonnet-4-5": "Claude Sonnet 4.5",
		"claude-sonnet-3-5": "Claude Sonnet 3.5",
		"gpt-4o": "GPT-4o",
		"gpt-4-turbo": "GPT-4 Turbo",
		"gpt-4": "GPT-4",
		"gemini-2.0-flash": "Gemini 2.0 Flash",
		"gemini-pro": "Gemini Pro"
	};
	if (modelMappings[modelName]) return modelMappings[modelName];
	return modelName.replace(/-/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
}
function isBotMentioned(messageText, botShipName) {
	if (!messageText || !botShipName) return false;
	const escapedShip = normalizeShip(botShipName).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
	return new RegExp(`(^|\\s)${escapedShip}(?=\\s|$)`, "i").test(messageText);
}
function isDmAllowed(senderShip, allowlist) {
	if (!allowlist || allowlist.length === 0) return true;
	const normalizedSender = normalizeShip(senderShip);
	return allowlist.map((ship) => normalizeShip(ship)).some((ship) => ship === normalizedSender);
}
function extractMessageText(content) {
	if (!content || !Array.isArray(content)) return "";
	return content.map((block) => {
		if (block.inline && Array.isArray(block.inline)) return block.inline.map((item) => {
			if (typeof item === "string") return item;
			if (item && typeof item === "object") {
				if (item.ship) return item.ship;
				if (item.break !== void 0) return "\n";
				if (item.link && item.link.href) return item.link.href;
			}
			return "";
		}).join("");
		return "";
	}).join("\n").trim();
}
function isSummarizationRequest(messageText) {
	return [
		/summarize\s+(this\s+)?(channel|chat|conversation)/i,
		/what\s+did\s+i\s+miss/i,
		/catch\s+me\s+up/i,
		/channel\s+summary/i,
		/tldr/i
	].some((pattern) => pattern.test(messageText));
}
function formatChangesDate(daysAgo = 5) {
	const now = /* @__PURE__ */ new Date();
	const targetDate = /* @__PURE__ */ new Date(now.getTime() - daysAgo * 24 * 60 * 60 * 1e3);
	return `~${targetDate.getFullYear()}.${targetDate.getMonth() + 1}.${targetDate.getDate()}..20.19.51..9b9d`;
}

//#endregion
//#region extensions/tlon/src/monitor/discovery.ts
async function fetchGroupChanges(api, runtime, daysAgo = 5) {
	try {
		const changeDate = formatChangesDate(daysAgo);
		runtime.log?.(`[tlon] Fetching group changes since ${daysAgo} days ago (${changeDate})...`);
		const changes = await api.scry(`/groups-ui/v5/changes/${changeDate}.json`);
		if (changes) {
			runtime.log?.("[tlon] Successfully fetched changes data");
			return changes;
		}
		return null;
	} catch (error) {
		runtime.log?.(`[tlon] Failed to fetch changes (falling back to full init): ${error?.message ?? String(error)}`);
		return null;
	}
}
async function fetchAllChannels(api, runtime) {
	try {
		runtime.log?.("[tlon] Attempting auto-discovery of group channels...");
		const changes = await fetchGroupChanges(api, runtime, 5);
		let initData;
		if (changes) {
			runtime.log?.("[tlon] Changes data received, using full init for channel extraction");
			initData = await api.scry("/groups-ui/v6/init.json");
		} else initData = await api.scry("/groups-ui/v6/init.json");
		const channels = [];
		if (initData && initData.groups) {
			for (const groupData of Object.values(initData.groups)) if (groupData && typeof groupData === "object" && groupData.channels) {
				for (const channelNest of Object.keys(groupData.channels)) if (channelNest.startsWith("chat/")) channels.push(channelNest);
			}
		}
		if (channels.length > 0) {
			runtime.log?.(`[tlon] Auto-discovered ${channels.length} chat channel(s)`);
			runtime.log?.(`[tlon] Channels: ${channels.slice(0, 5).join(", ")}${channels.length > 5 ? "..." : ""}`);
		} else {
			runtime.log?.("[tlon] No chat channels found via auto-discovery");
			runtime.log?.("[tlon] Add channels manually to config: channels.tlon.groupChannels");
		}
		return channels;
	} catch (error) {
		runtime.log?.(`[tlon] Auto-discovery failed: ${error?.message ?? String(error)}`);
		runtime.log?.("[tlon] To monitor group channels, add them to config: channels.tlon.groupChannels");
		runtime.log?.("[tlon] Example: [\"chat/~host-ship/channel-name\"]");
		return [];
	}
}

//#endregion
//#region extensions/tlon/src/monitor/history.ts
const messageCache = /* @__PURE__ */ new Map();
const MAX_CACHED_MESSAGES = 100;
function cacheMessage(channelNest, message) {
	if (!messageCache.has(channelNest)) messageCache.set(channelNest, []);
	const cache = messageCache.get(channelNest);
	if (!cache) return;
	cache.unshift(message);
	if (cache.length > MAX_CACHED_MESSAGES) cache.pop();
}
async function fetchChannelHistory(api, channelNest, count = 50, runtime) {
	try {
		const scryPath = `/channels/v4/${channelNest}/posts/newest/${count}/outline.json`;
		runtime?.log?.(`[tlon] Fetching history: ${scryPath}`);
		const data = await api.scry(scryPath);
		if (!data) return [];
		let posts = [];
		if (Array.isArray(data)) posts = data;
		else if (data.posts && typeof data.posts === "object") posts = Object.values(data.posts);
		else if (typeof data === "object") posts = Object.values(data);
		const messages = posts.map((item) => {
			const essay = item.essay || item["r-post"]?.set?.essay;
			const seal = item.seal || item["r-post"]?.set?.seal;
			return {
				author: essay?.author || "unknown",
				content: extractMessageText(essay?.content || []),
				timestamp: essay?.sent || Date.now(),
				id: seal?.id
			};
		}).filter((msg) => msg.content);
		runtime?.log?.(`[tlon] Extracted ${messages.length} messages from history`);
		return messages;
	} catch (error) {
		runtime?.log?.(`[tlon] Error fetching channel history: ${error?.message ?? String(error)}`);
		return [];
	}
}
async function getChannelHistory(api, channelNest, count = 50, runtime) {
	const cache = messageCache.get(channelNest) ?? [];
	if (cache.length >= count) {
		runtime?.log?.(`[tlon] Using cached messages (${cache.length} available)`);
		return cache.slice(0, count);
	}
	runtime?.log?.(`[tlon] Cache has ${cache.length} messages, need ${count}, fetching from scry...`);
	return await fetchChannelHistory(api, channelNest, count, runtime);
}

//#endregion
//#region extensions/tlon/src/monitor/processed-messages.ts
function createProcessedMessageTracker(limit = 2e3) {
	const seen = /* @__PURE__ */ new Set();
	const order = [];
	const mark = (id) => {
		const trimmed = id?.trim();
		if (!trimmed) return true;
		if (seen.has(trimmed)) return false;
		seen.add(trimmed);
		order.push(trimmed);
		if (order.length > limit) {
			const overflow = order.length - limit;
			for (let i = 0; i < overflow; i += 1) {
				const oldest = order.shift();
				if (oldest) seen.delete(oldest);
			}
		}
		return true;
	};
	const has = (id) => {
		const trimmed = id?.trim();
		if (!trimmed) return false;
		return seen.has(trimmed);
	};
	return {
		mark,
		has,
		size: () => seen.size
	};
}

//#endregion
//#region extensions/tlon/src/monitor/index.ts
function formatError(err) {
	if (err instanceof Error) return err.message;
	return String(err);
}
function resolveChannelAuthorization(cfg, channelNest) {
	const tlonConfig = cfg.channels?.tlon;
	const rule = (tlonConfig?.authorization?.channelRules ?? {})[channelNest];
	const allowedShips = rule?.allowedShips ?? tlonConfig?.defaultAuthorizedShips ?? [];
	return {
		mode: rule?.mode ?? "restricted",
		allowedShips
	};
}
async function monitorTlonProvider(opts = {}) {
	const core = getTlonRuntime();
	const cfg = core.config.loadConfig();
	if (cfg.channels?.tlon?.enabled === false) return;
	const logger = core.logging.getChildLogger({ module: "tlon-auto-reply" });
	const formatRuntimeMessage = (...args) => format(...args);
	const runtime = opts.runtime ?? {
		log: (...args) => {
			logger.info(formatRuntimeMessage(...args));
		},
		error: (...args) => {
			logger.error(formatRuntimeMessage(...args));
		},
		exit: (code) => {
			throw new Error(`exit ${code}`);
		}
	};
	const account = resolveTlonAccount(cfg, opts.accountId ?? void 0);
	if (!account.enabled) return;
	if (!account.configured || !account.ship || !account.url || !account.code) throw new Error("Tlon account not configured (ship/url/code required)");
	const botShipName = normalizeShip(account.ship);
	runtime.log?.(`[tlon] Starting monitor for ${botShipName}`);
	let api = null;
	try {
		const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(account.allowPrivateNetwork);
		runtime.log?.(`[tlon] Attempting authentication to ${account.url}...`);
		const cookie = await authenticate(account.url, account.code, { ssrfPolicy });
		api = new UrbitSSEClient(account.url, cookie, {
			ship: botShipName,
			ssrfPolicy,
			logger: {
				log: (message) => runtime.log?.(message),
				error: (message) => runtime.error?.(message)
			}
		});
	} catch (error) {
		runtime.error?.(`[tlon] Failed to authenticate: ${formatError(error)}`);
		throw error;
	}
	const processedTracker = createProcessedMessageTracker(2e3);
	let groupChannels = [];
	if (account.autoDiscoverChannels !== false) try {
		const discoveredChannels = await fetchAllChannels(api, runtime);
		if (discoveredChannels.length > 0) groupChannels = discoveredChannels;
	} catch (error) {
		runtime.error?.(`[tlon] Auto-discovery failed: ${formatError(error)}`);
	}
	if (groupChannels.length === 0 && account.groupChannels.length > 0) {
		groupChannels = account.groupChannels;
		runtime.log?.(`[tlon] Using manual groupChannels config: ${groupChannels.join(", ")}`);
	}
	if (groupChannels.length > 0) runtime.log?.(`[tlon] Monitoring ${groupChannels.length} group channel(s): ${groupChannels.join(", ")}`);
	else runtime.log?.("[tlon] No group channels to monitor (DMs only)");
	const handleIncomingDM = async (update) => {
		try {
			const memo = update?.response?.add?.memo;
			if (!memo) return;
			const messageId = update.id != null ? String(update.id) : void 0;
			if (!processedTracker.mark(messageId)) return;
			const senderShip = normalizeShip(memo.author ?? "");
			if (!senderShip || senderShip === botShipName) return;
			const messageText = extractMessageText(memo.content);
			if (!messageText) return;
			if (!isDmAllowed(senderShip, account.dmAllowlist)) {
				runtime.log?.(`[tlon] Blocked DM from ${senderShip}: not in allowlist`);
				return;
			}
			await processMessage({
				messageId: messageId ?? "",
				senderShip,
				messageText,
				isGroup: false,
				timestamp: memo.sent || Date.now()
			});
		} catch (error) {
			runtime.error?.(`[tlon] Error handling DM: ${formatError(error)}`);
		}
	};
	const handleIncomingGroupMessage = (channelNest) => async (update) => {
		try {
			const parsed = parseChannelNest(channelNest);
			if (!parsed) return;
			const post = update?.response?.post?.["r-post"];
			const essay = post?.set?.essay;
			const memo = post?.reply?.["r-reply"]?.set?.memo;
			if (!essay && !memo) return;
			const content = memo || essay;
			if (!content) return;
			const isThreadReply = Boolean(memo);
			const rawMessageId = isThreadReply ? post?.reply?.id : update?.response?.post?.id;
			const messageId = rawMessageId != null ? String(rawMessageId) : void 0;
			if (!processedTracker.mark(messageId)) return;
			const senderShip = normalizeShip(content.author ?? "");
			if (!senderShip || senderShip === botShipName) return;
			const messageText = extractMessageText(content.content);
			if (!messageText) return;
			cacheMessage(channelNest, {
				author: senderShip,
				content: messageText,
				timestamp: content.sent || Date.now(),
				id: messageId
			});
			if (!isBotMentioned(messageText, botShipName)) return;
			const { mode, allowedShips } = resolveChannelAuthorization(cfg, channelNest);
			if (mode === "restricted") {
				if (allowedShips.length === 0) {
					runtime.log?.(`[tlon] Access denied: ${senderShip} in ${channelNest} (no allowlist)`);
					return;
				}
				if (!allowedShips.map(normalizeShip).includes(senderShip)) {
					runtime.log?.(`[tlon] Access denied: ${senderShip} in ${channelNest} (allowed: ${allowedShips.join(", ")})`);
					return;
				}
			}
			const seal = isThreadReply ? update?.response?.post?.["r-post"]?.reply?.["r-reply"]?.set?.seal : update?.response?.post?.["r-post"]?.set?.seal;
			const parentId = seal?.["parent-id"] || seal?.parent || null;
			await processMessage({
				messageId: messageId ?? "",
				senderShip,
				messageText,
				isGroup: true,
				groupChannel: channelNest,
				groupName: `${parsed.hostShip}/${parsed.channelName}`,
				timestamp: content.sent || Date.now(),
				parentId
			});
		} catch (error) {
			runtime.error?.(`[tlon] Error handling group message: ${formatError(error)}`);
		}
	};
	const processMessage = async (params) => {
		const { messageId, senderShip, isGroup, groupChannel, groupName, timestamp, parentId } = params;
		let messageText = params.messageText;
		if (isGroup && groupChannel && isSummarizationRequest(messageText)) try {
			const history = await getChannelHistory(api, groupChannel, 50, runtime);
			if (history.length === 0) {
				const noHistoryMsg = "I couldn't fetch any messages for this channel. It might be empty or there might be a permissions issue.";
				if (isGroup) {
					const parsed = parseChannelNest(groupChannel);
					if (parsed) await sendGroupMessage({
						api,
						fromShip: botShipName,
						hostShip: parsed.hostShip,
						channelName: parsed.channelName,
						text: noHistoryMsg
					});
				} else await sendDm({
					api,
					fromShip: botShipName,
					toShip: senderShip,
					text: noHistoryMsg
				});
				return;
			}
			const historyText = history.map((msg) => `[${new Date(msg.timestamp).toLocaleString()}] ${msg.author}: ${msg.content}`).join("\n");
			messageText = `Please summarize this channel conversation (${history.length} recent messages):\n\n${historyText}\n\nProvide a concise summary highlighting:
1. Main topics discussed
2. Key decisions or conclusions
3. Action items if any
4. Notable participants`;
		} catch (error) {
			const errorMsg = `Sorry, I encountered an error while fetching the channel history: ${formatError(error)}`;
			if (isGroup && groupChannel) {
				const parsed = parseChannelNest(groupChannel);
				if (parsed) await sendGroupMessage({
					api,
					fromShip: botShipName,
					hostShip: parsed.hostShip,
					channelName: parsed.channelName,
					text: errorMsg
				});
			} else await sendDm({
				api,
				fromShip: botShipName,
				toShip: senderShip,
				text: errorMsg
			});
			return;
		}
		const route = core.channel.routing.resolveAgentRoute({
			cfg,
			channel: "tlon",
			accountId: opts.accountId ?? void 0,
			peer: {
				kind: isGroup ? "group" : "direct",
				id: isGroup ? groupChannel ?? senderShip : senderShip
			}
		});
		const fromLabel = isGroup ? `${senderShip} in ${groupName}` : senderShip;
		const body = core.channel.reply.formatAgentEnvelope({
			channel: "Tlon",
			from: fromLabel,
			timestamp,
			body: messageText
		});
		const ctxPayload = core.channel.reply.finalizeInboundContext({
			Body: body,
			BodyForAgent: messageText,
			RawBody: messageText,
			CommandBody: messageText,
			From: isGroup ? `tlon:group:${groupChannel}` : `tlon:${senderShip}`,
			To: `tlon:${botShipName}`,
			SessionKey: route.sessionKey,
			AccountId: route.accountId,
			ChatType: isGroup ? "group" : "direct",
			ConversationLabel: fromLabel,
			SenderName: senderShip,
			SenderId: senderShip,
			Provider: "tlon",
			Surface: "tlon",
			MessageSid: messageId,
			OriginatingChannel: "tlon",
			OriginatingTo: `tlon:${isGroup ? groupChannel : botShipName}`
		});
		const dispatchStartTime = Date.now();
		const { onModelSelected, ...prefixOptions } = createReplyPrefixOptions({
			cfg,
			agentId: route.agentId,
			channel: "tlon",
			accountId: route.accountId
		});
		const humanDelay = core.channel.reply.resolveHumanDelayConfig(cfg, route.agentId);
		await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
			ctx: ctxPayload,
			cfg,
			dispatcherOptions: {
				...prefixOptions,
				humanDelay,
				deliver: async (payload) => {
					let replyText = payload.text;
					if (!replyText) return;
					if (account.showModelSignature ?? cfg.channels?.tlon?.showModelSignature ?? false) {
						const extPayload = payload;
						const extRoute = route;
						const modelInfo = extPayload.metadata?.model || extPayload.model || extRoute.model || cfg.agents?.defaults?.model?.primary;
						replyText = `${replyText}\n\n_[Generated by ${formatModelName(modelInfo)}]_`;
					}
					if (isGroup && groupChannel) {
						const parsed = parseChannelNest(groupChannel);
						if (!parsed) return;
						await sendGroupMessage({
							api,
							fromShip: botShipName,
							hostShip: parsed.hostShip,
							channelName: parsed.channelName,
							text: replyText,
							replyToId: parentId ?? void 0
						});
					} else await sendDm({
						api,
						fromShip: botShipName,
						toShip: senderShip,
						text: replyText
					});
				},
				onError: (err, info) => {
					const dispatchDuration = Date.now() - dispatchStartTime;
					runtime.error?.(`[tlon] ${info.kind} reply failed after ${dispatchDuration}ms: ${String(err)}`);
				}
			},
			replyOptions: { onModelSelected }
		});
	};
	const subscribedChannels = /* @__PURE__ */ new Set();
	const subscribedDMs = /* @__PURE__ */ new Set();
	async function subscribeToChannel(channelNest) {
		if (subscribedChannels.has(channelNest)) return;
		if (!parseChannelNest(channelNest)) {
			runtime.error?.(`[tlon] Invalid channel format: ${channelNest}`);
			return;
		}
		try {
			await api.subscribe({
				app: "channels",
				path: `/${channelNest}`,
				event: (data) => {
					handleIncomingGroupMessage(channelNest)(data);
				},
				err: (error) => {
					runtime.error?.(`[tlon] Group subscription error for ${channelNest}: ${String(error)}`);
				},
				quit: () => {
					runtime.log?.(`[tlon] Group subscription ended for ${channelNest}`);
					subscribedChannels.delete(channelNest);
				}
			});
			subscribedChannels.add(channelNest);
			runtime.log?.(`[tlon] Subscribed to group channel: ${channelNest}`);
		} catch (error) {
			runtime.error?.(`[tlon] Failed to subscribe to ${channelNest}: ${formatError(error)}`);
		}
	}
	async function subscribeToDM(dmShip) {
		if (subscribedDMs.has(dmShip)) return;
		try {
			await api.subscribe({
				app: "chat",
				path: `/dm/${dmShip}`,
				event: (data) => {
					handleIncomingDM(data);
				},
				err: (error) => {
					runtime.error?.(`[tlon] DM subscription error for ${dmShip}: ${String(error)}`);
				},
				quit: () => {
					runtime.log?.(`[tlon] DM subscription ended for ${dmShip}`);
					subscribedDMs.delete(dmShip);
				}
			});
			subscribedDMs.add(dmShip);
			runtime.log?.(`[tlon] Subscribed to DM with ${dmShip}`);
		} catch (error) {
			runtime.error?.(`[tlon] Failed to subscribe to DM with ${dmShip}: ${formatError(error)}`);
		}
	}
	async function refreshChannelSubscriptions() {
		try {
			const dmShips = await api.scry("/chat/dm.json");
			if (Array.isArray(dmShips)) for (const dmShip of dmShips) await subscribeToDM(dmShip);
			if (account.autoDiscoverChannels !== false) {
				const discoveredChannels = await fetchAllChannels(api, runtime);
				for (const channelNest of discoveredChannels) await subscribeToChannel(channelNest);
			}
		} catch (error) {
			runtime.error?.(`[tlon] Channel refresh failed: ${formatError(error)}`);
		}
	}
	try {
		runtime.log?.("[tlon] Subscribing to updates...");
		let dmShips = [];
		try {
			const dmList = await api.scry("/chat/dm.json");
			if (Array.isArray(dmList)) {
				dmShips = dmList;
				runtime.log?.(`[tlon] Found ${dmShips.length} DM conversation(s)`);
			}
		} catch (error) {
			runtime.error?.(`[tlon] Failed to fetch DM list: ${formatError(error)}`);
		}
		for (const dmShip of dmShips) await subscribeToDM(dmShip);
		for (const channelNest of groupChannels) await subscribeToChannel(channelNest);
		runtime.log?.("[tlon] All subscriptions registered, connecting to SSE stream...");
		await api.connect();
		runtime.log?.("[tlon] Connected! All subscriptions active");
		const pollInterval = setInterval(() => {
			if (!opts.abortSignal?.aborted) refreshChannelSubscriptions().catch((error) => {
				runtime.error?.(`[tlon] Channel refresh error: ${formatError(error)}`);
			});
		}, 120 * 1e3);
		if (opts.abortSignal) {
			const signal = opts.abortSignal;
			await new Promise((resolve) => {
				signal.addEventListener("abort", () => {
					clearInterval(pollInterval);
					resolve(null);
				}, { once: true });
			});
		} else await new Promise(() => {});
	} finally {
		try {
			await api?.close();
		} catch (error) {
			runtime.error?.(`[tlon] Cleanup error: ${formatError(error)}`);
		}
	}
}

//#endregion
//#region extensions/tlon/src/onboarding.ts
const channel = "tlon";
function isConfigured(account) {
	return Boolean(account.ship && account.url && account.code);
}
function applyAccountConfig(params) {
	const { cfg, accountId, input } = params;
	const useDefault = accountId === DEFAULT_ACCOUNT_ID;
	const base = cfg.channels?.tlon ?? {};
	const nextValues = {
		enabled: true,
		...input.name ? { name: input.name } : {},
		...buildTlonAccountFields(input)
	};
	if (useDefault) return {
		...cfg,
		channels: {
			...cfg.channels,
			tlon: {
				...base,
				...nextValues
			}
		}
	};
	return {
		...cfg,
		channels: {
			...cfg.channels,
			tlon: {
				...base,
				enabled: base.enabled ?? true,
				accounts: {
					...base.accounts,
					[accountId]: {
						...base.accounts?.[accountId],
						...nextValues
					}
				}
			}
		}
	};
}
async function noteTlonHelp(prompter) {
	await prompter.note([
		"You need your Urbit ship URL and login code.",
		"Example URL: https://your-ship-host",
		"Example ship: ~sampel-palnet",
		"If your ship URL is on a private network (LAN/localhost), you must explicitly allow it during setup.",
		`Docs: ${formatDocsLink("/channels/tlon", "channels/tlon")}`
	].join("\n"), "Tlon setup");
}
function parseList(value) {
	return value.split(/[\n,;]+/g).map((entry) => entry.trim()).filter(Boolean);
}
const tlonOnboardingAdapter = {
	channel,
	getStatus: async ({ cfg }) => {
		const accountIds = listTlonAccountIds(cfg);
		const configured = accountIds.length > 0 ? accountIds.some((accountId) => isConfigured(resolveTlonAccount(cfg, accountId))) : isConfigured(resolveTlonAccount(cfg, DEFAULT_ACCOUNT_ID));
		return {
			channel,
			configured,
			statusLines: [`Tlon: ${configured ? "configured" : "needs setup"}`],
			selectionHint: configured ? "configured" : "urbit messenger",
			quickstartScore: configured ? 1 : 4
		};
	},
	configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
		const override = accountOverrides[channel]?.trim();
		const defaultAccountId = DEFAULT_ACCOUNT_ID;
		let accountId = override ? normalizeAccountId(override) : defaultAccountId;
		if (shouldPromptAccountIds && !override) accountId = await promptAccountId({
			cfg,
			prompter,
			label: "Tlon",
			currentId: accountId,
			listAccountIds: listTlonAccountIds,
			defaultAccountId
		});
		const resolved = resolveTlonAccount(cfg, accountId);
		await noteTlonHelp(prompter);
		const ship = await prompter.text({
			message: "Ship name",
			placeholder: "~sampel-palnet",
			initialValue: resolved.ship ?? void 0,
			validate: (value) => String(value ?? "").trim() ? void 0 : "Required"
		});
		const url = await prompter.text({
			message: "Ship URL",
			placeholder: "https://your-ship-host",
			initialValue: resolved.url ?? void 0,
			validate: (value) => {
				const next = validateUrbitBaseUrl(String(value ?? ""));
				if (!next.ok) return next.error;
			}
		});
		const validatedUrl = validateUrbitBaseUrl(String(url).trim());
		if (!validatedUrl.ok) throw new Error(`Invalid URL: ${validatedUrl.error}`);
		let allowPrivateNetwork = resolved.allowPrivateNetwork ?? false;
		if (isBlockedUrbitHostname(validatedUrl.hostname)) {
			allowPrivateNetwork = await prompter.confirm({
				message: "Ship URL looks like a private/internal host. Allow private network access? (SSRF risk)",
				initialValue: allowPrivateNetwork
			});
			if (!allowPrivateNetwork) throw new Error("Refusing private/internal Ship URL without explicit approval");
		}
		const code = await prompter.text({
			message: "Login code",
			placeholder: "lidlut-tabwed-pillex-ridrup",
			initialValue: resolved.code ?? void 0,
			validate: (value) => String(value ?? "").trim() ? void 0 : "Required"
		});
		const wantsGroupChannels = await prompter.confirm({
			message: "Add group channels manually? (optional)",
			initialValue: false
		});
		let groupChannels;
		if (wantsGroupChannels) {
			const entry = await prompter.text({
				message: "Group channels (comma-separated)",
				placeholder: "chat/~host-ship/general, chat/~host-ship/support"
			});
			const parsed = parseList(String(entry ?? ""));
			groupChannels = parsed.length > 0 ? parsed : void 0;
		}
		const wantsAllowlist = await prompter.confirm({
			message: "Restrict DMs with an allowlist?",
			initialValue: false
		});
		let dmAllowlist;
		if (wantsAllowlist) {
			const entry = await prompter.text({
				message: "DM allowlist (comma-separated ship names)",
				placeholder: "~zod, ~nec"
			});
			const parsed = parseList(String(entry ?? ""));
			dmAllowlist = parsed.length > 0 ? parsed : void 0;
		}
		const autoDiscoverChannels = await prompter.confirm({
			message: "Enable auto-discovery of group channels?",
			initialValue: resolved.autoDiscoverChannels ?? true
		});
		return {
			cfg: applyAccountConfig({
				cfg,
				accountId,
				input: {
					ship: String(ship).trim(),
					url: String(url).trim(),
					code: String(code).trim(),
					allowPrivateNetwork,
					groupChannels,
					dmAllowlist,
					autoDiscoverChannels
				}
			}),
			accountId
		};
	}
};

//#endregion
//#region extensions/tlon/src/urbit/channel-client.ts
var UrbitChannelClient = class {
	constructor(url, cookie, options = {}) {
		this.channelId = null;
		const ctx = getUrbitContext(url, options.ship);
		this.baseUrl = ctx.baseUrl;
		this.cookie = normalizeUrbitCookie(cookie);
		this.ship = ctx.ship;
		this.ssrfPolicy = options.ssrfPolicy;
		this.lookupFn = options.lookupFn;
		this.fetchImpl = options.fetchImpl;
	}
	get channelPath() {
		const id = this.channelId;
		if (!id) throw new Error("Channel not opened");
		return `/~/channel/${id}`;
	}
	async open() {
		if (this.channelId) return;
		const channelId = `${Math.floor(Date.now() / 1e3)}-${Math.random().toString(36).substring(2, 8)}`;
		this.channelId = channelId;
		try {
			await ensureUrbitChannelOpen({
				baseUrl: this.baseUrl,
				cookie: this.cookie,
				ship: this.ship,
				channelId,
				ssrfPolicy: this.ssrfPolicy,
				lookupFn: this.lookupFn,
				fetchImpl: this.fetchImpl
			}, {
				createBody: [],
				createAuditContext: "tlon-urbit-channel-open"
			});
		} catch (error) {
			this.channelId = null;
			throw error;
		}
	}
	async poke(params) {
		await this.open();
		const channelId = this.channelId;
		if (!channelId) throw new Error("Channel not opened");
		return await pokeUrbitChannel({
			baseUrl: this.baseUrl,
			cookie: this.cookie,
			ship: this.ship,
			channelId,
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl
		}, {
			...params,
			auditContext: "tlon-urbit-poke"
		});
	}
	async scry(path) {
		return await scryUrbitPath({
			baseUrl: this.baseUrl,
			cookie: this.cookie,
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl
		}, {
			path,
			auditContext: "tlon-urbit-scry"
		});
	}
	async getOurName() {
		const { response, release } = await urbitFetch({
			baseUrl: this.baseUrl,
			path: "/~/name",
			init: {
				method: "GET",
				headers: { Cookie: this.cookie }
			},
			ssrfPolicy: this.ssrfPolicy,
			lookupFn: this.lookupFn,
			fetchImpl: this.fetchImpl,
			timeoutMs: 3e4,
			auditContext: "tlon-urbit-name"
		});
		try {
			if (!response.ok) throw new Error(`Name request failed: ${response.status}`);
			return (await response.text()).trim();
		} finally {
			await release();
		}
	}
	async close() {
		if (!this.channelId) return;
		const channelPath = this.channelPath;
		this.channelId = null;
		try {
			const { response, release } = await urbitFetch({
				baseUrl: this.baseUrl,
				path: channelPath,
				init: {
					method: "DELETE",
					headers: { Cookie: this.cookie }
				},
				ssrfPolicy: this.ssrfPolicy,
				lookupFn: this.lookupFn,
				fetchImpl: this.fetchImpl,
				timeoutMs: 3e4,
				auditContext: "tlon-urbit-channel-close"
			});
			try {
				response.body?.cancel();
			} finally {
				await release();
			}
		} catch {}
	}
};

//#endregion
//#region extensions/tlon/src/channel.ts
const TLON_CHANNEL_ID = "tlon";
function applyTlonSetupConfig(params) {
	const { cfg, accountId, input } = params;
	const useDefault = accountId === DEFAULT_ACCOUNT_ID;
	const namedConfig = applyAccountNameToChannelSection({
		cfg,
		channelKey: "tlon",
		accountId,
		name: input.name
	});
	const base = namedConfig.channels?.tlon ?? {};
	const payload = buildTlonAccountFields(input);
	if (useDefault) return {
		...namedConfig,
		channels: {
			...namedConfig.channels,
			tlon: {
				...base,
				enabled: true,
				...payload
			}
		}
	};
	return {
		...namedConfig,
		channels: {
			...namedConfig.channels,
			tlon: {
				...base,
				enabled: base.enabled ?? true,
				accounts: {
					...base.accounts,
					[accountId]: {
						...base.accounts?.[accountId],
						enabled: true,
						...payload
					}
				}
			}
		}
	};
}
const tlonOutbound = {
	deliveryMode: "direct",
	textChunkLimit: 1e4,
	resolveTarget: ({ to }) => {
		const parsed = parseTlonTarget(to ?? "");
		if (!parsed) return {
			ok: false,
			error: /* @__PURE__ */ new Error(`Invalid Tlon target. Use ${formatTargetHint()}`)
		};
		if (parsed.kind === "direct") return {
			ok: true,
			to: parsed.ship
		};
		return {
			ok: true,
			to: parsed.nest
		};
	},
	sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
		const account = resolveTlonAccount(cfg, accountId ?? void 0);
		if (!account.configured || !account.ship || !account.url || !account.code) throw new Error("Tlon account not configured");
		const parsed = parseTlonTarget(to);
		if (!parsed) throw new Error(`Invalid Tlon target. Use ${formatTargetHint()}`);
		const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(account.allowPrivateNetwork);
		const cookie = await authenticate(account.url, account.code, { ssrfPolicy });
		const api = new UrbitChannelClient(account.url, cookie, {
			ship: account.ship.replace(/^~/, ""),
			ssrfPolicy
		});
		try {
			const fromShip = normalizeShip(account.ship);
			if (parsed.kind === "direct") return await sendDm({
				api,
				fromShip,
				toShip: parsed.ship,
				text
			});
			const replyId = replyToId ?? threadId ? String(replyToId ?? threadId) : void 0;
			return await sendGroupMessage({
				api,
				fromShip,
				hostShip: parsed.hostShip,
				channelName: parsed.channelName,
				text,
				replyToId: replyId
			});
		} finally {
			await api.close();
		}
	},
	sendMedia: async ({ cfg, to, text, mediaUrl, accountId, replyToId, threadId }) => {
		const mergedText = buildMediaText(text, mediaUrl);
		return await tlonOutbound.sendText({
			cfg,
			to,
			text: mergedText,
			accountId,
			replyToId,
			threadId
		});
	}
};
const tlonPlugin = {
	id: TLON_CHANNEL_ID,
	meta: {
		id: TLON_CHANNEL_ID,
		label: "Tlon",
		selectionLabel: "Tlon (Urbit)",
		docsPath: "/channels/tlon",
		docsLabel: "tlon",
		blurb: "Decentralized messaging on Urbit",
		aliases: ["urbit"],
		order: 90
	},
	capabilities: {
		chatTypes: [
			"direct",
			"group",
			"thread"
		],
		media: false,
		reply: true,
		threads: true
	},
	onboarding: tlonOnboardingAdapter,
	reload: { configPrefixes: ["channels.tlon"] },
	configSchema: tlonChannelConfigSchema,
	config: {
		listAccountIds: (cfg) => listTlonAccountIds(cfg),
		resolveAccount: (cfg, accountId) => resolveTlonAccount(cfg, accountId ?? void 0),
		defaultAccountId: () => "default",
		setAccountEnabled: ({ cfg, accountId, enabled }) => {
			if (!accountId || accountId === "default") return {
				...cfg,
				channels: {
					...cfg.channels,
					tlon: {
						...cfg.channels?.tlon,
						enabled
					}
				}
			};
			return {
				...cfg,
				channels: {
					...cfg.channels,
					tlon: {
						...cfg.channels?.tlon,
						accounts: {
							...cfg.channels?.tlon?.accounts,
							[accountId]: {
								...cfg.channels?.tlon?.accounts?.[accountId],
								enabled
							}
						}
					}
				}
			};
		},
		deleteAccount: ({ cfg, accountId }) => {
			if (!accountId || accountId === "default") {
				const { ship, code, url, name, ...rest } = cfg.channels?.tlon ?? {};
				return {
					...cfg,
					channels: {
						...cfg.channels,
						tlon: rest
					}
				};
			}
			const { [accountId]: removed, ...remainingAccounts } = cfg.channels?.tlon?.accounts ?? {};
			return {
				...cfg,
				channels: {
					...cfg.channels,
					tlon: {
						...cfg.channels?.tlon,
						accounts: remainingAccounts
					}
				}
			};
		},
		isConfigured: (account) => account.configured,
		describeAccount: (account) => ({
			accountId: account.accountId,
			name: account.name,
			enabled: account.enabled,
			configured: account.configured,
			ship: account.ship,
			url: account.url
		})
	},
	setup: {
		resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
		applyAccountName: ({ cfg, accountId, name }) => applyAccountNameToChannelSection({
			cfg,
			channelKey: "tlon",
			accountId,
			name
		}),
		validateInput: ({ cfg, accountId, input }) => {
			const setupInput = input;
			const resolved = resolveTlonAccount(cfg, accountId ?? void 0);
			const ship = setupInput.ship?.trim() || resolved.ship;
			const url = setupInput.url?.trim() || resolved.url;
			const code = setupInput.code?.trim() || resolved.code;
			if (!ship) return "Tlon requires --ship.";
			if (!url) return "Tlon requires --url.";
			if (!code) return "Tlon requires --code.";
			return null;
		},
		applyAccountConfig: ({ cfg, accountId, input }) => applyTlonSetupConfig({
			cfg,
			accountId,
			input
		})
	},
	messaging: {
		normalizeTarget: (target) => {
			const parsed = parseTlonTarget(target);
			if (!parsed) return target.trim();
			if (parsed.kind === "direct") return parsed.ship;
			return parsed.nest;
		},
		targetResolver: {
			looksLikeId: (target) => Boolean(parseTlonTarget(target)),
			hint: formatTargetHint()
		}
	},
	outbound: tlonOutbound,
	status: {
		defaultRuntime: {
			accountId: "default",
			running: false,
			lastStartAt: null,
			lastStopAt: null,
			lastError: null
		},
		collectStatusIssues: (accounts) => {
			return accounts.flatMap((account) => {
				if (!account.configured) return [{
					channel: TLON_CHANNEL_ID,
					accountId: account.accountId,
					kind: "config",
					message: "Account not configured (missing ship, code, or url)"
				}];
				return [];
			});
		},
		buildChannelSummary: ({ snapshot }) => ({
			configured: snapshot.configured ?? false,
			ship: snapshot.ship ?? null,
			url: snapshot.url ?? null
		}),
		probeAccount: async ({ account }) => {
			if (!account.configured || !account.ship || !account.url || !account.code) return {
				ok: false,
				error: "Not configured"
			};
			try {
				const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(account.allowPrivateNetwork);
				const cookie = await authenticate(account.url, account.code, { ssrfPolicy });
				const api = new UrbitChannelClient(account.url, cookie, {
					ship: account.ship.replace(/^~/, ""),
					ssrfPolicy
				});
				try {
					await api.getOurName();
					return { ok: true };
				} finally {
					await api.close();
				}
			} catch (error) {
				return {
					ok: false,
					error: error?.message ?? String(error)
				};
			}
		},
		buildAccountSnapshot: ({ account, runtime, probe }) => ({
			accountId: account.accountId,
			name: account.name,
			enabled: account.enabled,
			configured: account.configured,
			ship: account.ship,
			url: account.url,
			running: runtime?.running ?? false,
			lastStartAt: runtime?.lastStartAt ?? null,
			lastStopAt: runtime?.lastStopAt ?? null,
			lastError: runtime?.lastError ?? null,
			probe
		})
	},
	gateway: { startAccount: async (ctx) => {
		const account = ctx.account;
		ctx.setStatus({
			accountId: account.accountId,
			ship: account.ship,
			url: account.url
		});
		ctx.log?.info(`[${account.accountId}] starting Tlon provider for ${account.ship ?? "tlon"}`);
		return monitorTlonProvider({
			runtime: ctx.runtime,
			abortSignal: ctx.abortSignal,
			accountId: account.accountId
		});
	} }
};

//#endregion
//#region extensions/tlon/index.ts
const plugin = {
	id: "tlon",
	name: "Tlon",
	description: "Tlon/Urbit channel plugin",
	configSchema: emptyPluginConfigSchema(),
	register(api) {
		setTlonRuntime(api.runtime);
		api.registerChannel({ plugin: tlonPlugin });
	}
};

//#endregion
export { plugin as default };