@crvouga/mockingbird-service-google-maps 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../core/src/clock.ts", "../../core/src/collection.ts", "../../core/src/control.ts", "../../core/src/credentials.ts", "../../core/src/rng.ts", "../../core/src/faults.ts", "../../../openapi/core/src/refs.ts", "../../../openapi/core/src/types.ts", "../../../openapi/core/src/document.ts", "../../../http/codec/src/form.ts", "../../../http/codec/src/content.ts", "../../core/src/http.ts", "../../core/src/ids.ts", "../../core/src/journal.ts", "../../core/src/metrics.ts", "../../../core/src/timeline.ts", "../../../sqlite/src/default.ts", "../../../sqlite/src/migrate.ts", "../../../sqlite/src/schema.ts", "../../../ui/src/reset.ts", "../../core/src/admin-client.ts", "../../core/src/surface.ts", "../../core/src/admin-ui.ts", "../../../openapi/metadata/src/types.ts", "../../../openapi/metadata/src/read.ts", "../../core/src/service.ts", "../../core/src/validation.ts", "../../core/src/snapshot.ts", "../../core/src/state-view.ts", "../../core/src/version.ts", "../../core/src/signing.ts", "../../core/src/webhooks.ts", "../../core/src/runtime.ts", "../src/generated/openapi.ts", "../src/corpus.ts", "../src/places.ts", "../src/shim.ts", "../src/state.ts", "../src/validation.ts", "../src/runtime.ts", "../src/index.ts"],
4
- "sourcesContent": ["/**\n * The single source of time for a service.\n *\n * Every timestamp a mock writes reads from here, so a suite moves time instead of\n * sleeping: appointment windows, result delays and expiries become reachable in\n * milliseconds. A frozen clock also makes timestamps reproducible from a seed.\n */\nexport type ClockState = {\n /** Current epoch milliseconds. */\n now: number\n /** True while time does not advance on its own. */\n frozen: boolean\n /** Milliseconds this clock adds to its underlying source. */\n offsetMs: number\n}\n\nexport type Clock = {\n now(): number\n /** Pin the clock to an exact instant, keeping it frozen if it already was. */\n set(epochMs: number): void\n /** Move the clock forward, or back with a negative delta. */\n advance(deltaMs: number): void\n /** Stop time at the current instant. */\n freeze(): void\n /** Resume from the current instant. */\n unfreeze(): void\n /** Drop back to the underlying source, live. */\n reset(): void\n state(): ClockState\n}\n\n/** A {@link Clock} over `source` (default `Date.now`), live and unfrozen. */\nexport const createClock = (source: () => number = Date.now): Clock => {\n let offsetMs = 0\n let frozenAt: number | undefined\n const now = () => frozenAt ?? source() + offsetMs\n return {\n now,\n set: (epochMs) => {\n if (frozenAt !== undefined) frozenAt = epochMs\n else offsetMs = epochMs - source()\n },\n advance: (deltaMs) => {\n if (frozenAt !== undefined) frozenAt += deltaMs\n else offsetMs += deltaMs\n },\n freeze: () => {\n frozenAt = now()\n },\n unfreeze: () => {\n if (frozenAt === undefined) return\n offsetMs = frozenAt - source()\n frozenAt = undefined\n },\n reset: () => {\n offsetMs = 0\n frozenAt = undefined\n },\n state: () => ({ now: now(), frozen: frozenAt !== undefined, offsetMs }),\n }\n}\n", "import type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\n\n/** Every stored record carries a monotonically increasing sequence for stable ordering. */\nexport type Stored<T> = { seq: number; value: T }\n\nexport type ListRecordsOptions<T> = {\n /** Keep only records passing the predicate. */\n where?: (value: T, seq: number) => boolean\n /** Sort order; default newest first. */\n order?: \"newest\" | \"oldest\"\n}\n\ntype RecordRow = { id: string; seq: number; value: string }\n\n/**\n * A SQLite-backed table of JSON records addressed by id. Ordering is by insertion\n * sequence, never by id lexicographic order, so list semantics stay stable.\n */\nexport class Collection<T> {\n constructor(\n private readonly sqlite: SqliteClient,\n /** Storage namespace. Admin introspection uses this to ignore another namespace's tables. */\n readonly namespace: string,\n /** Table name inside the namespace. Stable across resets of the rows themselves. */\n readonly collectionName: string,\n ) {}\n\n private bumpCollectionSeq(): number {\n const row = this.sqlite\n .prepare(\n \"SELECT value FROM mockingbird_sequences WHERE namespace = ? AND name = ? AND kind = 'collection'\",\n )\n .get<{ value: number }>(this.namespace, this.collectionName)\n const next = (row?.value ?? 0) + 1\n this.sqlite\n .prepare(\n `INSERT INTO mockingbird_sequences (namespace, name, kind, value) VALUES (?, ?, 'collection', ?)\n ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`,\n )\n .run(this.namespace, this.collectionName, next)\n return next\n }\n\n nextSequence(): number {\n return this.sqlite.transaction(() => this.bumpCollectionSeq())\n }\n\n get(id: string): T | undefined {\n const row = this.sqlite\n .prepare(\n \"SELECT value FROM mockingbird_records WHERE namespace = ? AND collection = ? AND id = ?\",\n )\n .get<{ value: string }>(this.namespace, this.collectionName, id)\n if (!row) return undefined\n return (JSON.parse(row.value) as Stored<T>).value\n }\n\n has(id: string): boolean {\n const row = this.sqlite\n .prepare(\n \"SELECT 1 AS ok FROM mockingbird_records WHERE namespace = ? AND collection = ? AND id = ?\",\n )\n .get<{ ok: number }>(this.namespace, this.collectionName, id)\n return row !== undefined\n }\n\n /** Insert a new record, assigning it the next sequence number. */\n insert(id: string, value: T): Stored<T> {\n return this.sqlite.transaction(() => {\n const seq = this.bumpCollectionSeq()\n const stored = { seq, value }\n this.sqlite\n .prepare(\n `INSERT INTO mockingbird_records (namespace, collection, id, seq, value)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(namespace, collection, id) DO UPDATE SET seq = excluded.seq, value = excluded.value`,\n )\n .run(this.namespace, this.collectionName, id, seq, JSON.stringify(stored))\n return stored\n })\n }\n\n /** Replace an existing record's value, keeping its position. */\n update(id: string, value: T): Stored<T> | undefined {\n return this.sqlite.transaction(() => {\n const row = this.sqlite\n .prepare(\n \"SELECT seq, value FROM mockingbird_records WHERE namespace = ? AND collection = ? AND id = ?\",\n )\n .get<{ seq: number; value: string }>(this.namespace, this.collectionName, id)\n if (!row) return undefined\n const stored = { seq: row.seq, value }\n this.sqlite\n .prepare(\n \"UPDATE mockingbird_records SET value = ? WHERE namespace = ? AND collection = ? AND id = ?\",\n )\n .run(JSON.stringify(stored), this.namespace, this.collectionName, id)\n return stored\n })\n }\n\n delete(id: string): boolean {\n const result = this.sqlite\n .prepare(\"DELETE FROM mockingbird_records WHERE namespace = ? AND collection = ? AND id = ?\")\n .run(this.namespace, this.collectionName, id)\n return result.changes > 0\n }\n\n /** How many records the collection holds, without reading them. */\n count(): number {\n const row = this.sqlite\n .prepare(\n \"SELECT COUNT(*) AS n FROM mockingbird_records WHERE namespace = ? AND collection = ?\",\n )\n .get<{ n: number }>(this.namespace, this.collectionName)\n return Number(row?.n ?? 0)\n }\n\n list(options: ListRecordsOptions<T> = {}): Array<Stored<T> & { id: string }> {\n const rows = this.sqlite\n .prepare(\n \"SELECT id, seq, value FROM mockingbird_records WHERE namespace = ? AND collection = ?\",\n )\n .all<RecordRow>(this.namespace, this.collectionName)\n const out: Array<Stored<T> & { id: string }> = []\n for (const row of rows) {\n const stored = JSON.parse(row.value) as Stored<T>\n if (options.where && !options.where(stored.value, stored.seq)) continue\n out.push({ id: row.id, seq: stored.seq, value: stored.value })\n }\n out.sort((a, b) => (options.order === \"oldest\" ? a.seq - b.seq : b.seq - a.seq))\n return out\n }\n}\n", "import type { Clock } from \"./clock.js\"\nimport type { FaultRegistry, FaultRule } from \"./faults.js\"\nimport type { Journal } from \"./journal.js\"\nimport type { Metrics } from \"./metrics.js\"\n\n/** Unauthenticated readiness probe, served ahead of every vendor auth gate. */\nexport const HEALTH_PATH = \"/health\"\n/** Prefix of every control-plane route; never part of a vendor contract. */\nexport const ADMIN_PREFIX = \"/__admin\"\n/** Carries the admin key, which is separate from any vendor credential. */\nexport const ADMIN_KEY_HEADER = \"x-mockingbird-admin-key\"\n/** Selects the isolated namespace a request reads and writes. */\nexport const NAMESPACE_HEADER = \"x-mockingbird-namespace\"\n\nexport type AdminRequest = {\n request: Request\n url: URL\n /** `:param` segments of the matched route. */\n params: Record<string, string>\n /** Namespace the request targets: `?namespace=`, then the header, then the default. */\n namespace: string\n /** Parsed JSON body, or `undefined` when there is none. */\n body: unknown\n}\n\nexport type AdminRoute = (request: AdminRequest) => Response | Promise<Response>\n\n/**\n * Service-specific admin routes, keyed `METHOD /path` relative to `/__admin`, with\n * `:param` segments \u2014 e.g. `\"POST /orders/:id/transition\"`.\n */\nexport type AdminRoutes = Record<string, AdminRoute>\n\nexport type ControlContext = {\n name: string\n startedAt: number\n wallNow: () => number\n clock: Clock\n faults: FaultRegistry\n metrics: Metrics\n journal: Journal\n defaultNamespace: string\n namespaces(): string[]\n reset(namespace: string | \"*\"): Promise<void>\n timeTravel: {\n checkpoint(\n namespace: string,\n branch: string,\n ): { id: string; branch: string; parent: string | null; at: number; records?: number }\n branch(\n name: string,\n options: { namespace: string; at?: string },\n ): { id: string; branch: string; parent: string | null; at: number }\n checkout(checkpoint: string, options: { namespace: string; branch: string }): void\n retain(namespace: string, checkpoint: string): void\n release(namespace: string, checkpoint: string): boolean\n inspect(namespace: string): {\n branches: Readonly<Record<string, string>>\n checkpoints: readonly { id: string; branch: string; parent: string | null; at: number }[]\n }\n }\n /** Extra fields for `GET /health`, such as the loaded corpus version. */\n describe(): Record<string, unknown>\n routes: AdminRoutes\n adminKey: string | undefined\n /** Expand a named fault preset; enables `POST /faults {\"preset\": \"<name>\"}`. */\n applyPreset?(name: string, namespace: string, overrides: Partial<FaultRule>): FaultRule[]\n}\n\nexport type ControlPlane = {\n /** The control-plane response for `request`, or `undefined` for a vendor request. */\n handle(request: Request): Promise<Response | undefined>\n /**\n * Namespace a vendor request targets, from {@link NAMESPACE_HEADER}. Only admin routes\n * also accept `?namespace=`, so a vendor query parameter of that name can never\n * silently reroute a request.\n */\n namespaceOf(request: Request): string\n}\n\nconst json = (status: number, body: unknown): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json\" },\n })\n\n/** Admin errors use one documented shape, distinct from any vendor's error body. */\nconst adminError = (status: number, message: string): Response =>\n json(status, { error: { type: \"mockingbird_admin\", message } })\n\nconst UNITS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n}\n\n/** Milliseconds from a number, or a duration like `\"90s\"`, `\"15m\"`, `\"2h\"`, `\"3d\"`. */\nexport const parseDuration = (value: unknown): number | undefined => {\n if (typeof value === \"number\" && Number.isFinite(value)) return value\n if (typeof value !== \"string\") return undefined\n const match = /^(-?\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/.exec(value.trim())\n if (!match) return undefined\n return Number(match[1]) * (UNITS[match[2] as string] as number)\n}\n\n/** Epoch milliseconds from a number or an ISO-8601 string. */\nconst parseInstant = (value: unknown): number | undefined => {\n if (typeof value === \"number\" && Number.isFinite(value)) return value\n if (typeof value !== \"string\") return undefined\n const parsed = Date.parse(value)\n return Number.isNaN(parsed) ? undefined : parsed\n}\n\nconst matchRoute = (pattern: string, path: string): Record<string, string> | undefined => {\n const want = pattern.split(\"/\").filter(Boolean)\n const have = path.split(\"/\").filter(Boolean)\n if (want.length !== have.length) return undefined\n const params: Record<string, string> = {}\n for (let i = 0; i < want.length; i++) {\n const segment = want[i] as string\n const actual = have[i] as string\n if (segment.startsWith(\":\")) params[segment.slice(1)] = decodeURIComponent(actual)\n else if (segment !== actual) return undefined\n }\n return params\n}\n\nconst readJson = async (request: Request): Promise<unknown> => {\n const text = await request.text()\n if (text.trim() === \"\") return undefined\n return JSON.parse(text) as unknown\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nexport const createControlPlane = (context: ControlContext): ControlPlane => {\n // Legacy snapshot ids are opaque aliases to pinned Timeline checkpoints. Timeline remains the\n // only history owner; this map carries no state value and can be removed with the alias.\n const snapshots = new Map<string, { namespace: string; checkpoint: string }>()\n let snapshotCounter = 0\n\n const headerNamespace = (request: Request): string =>\n request.headers.get(NAMESPACE_HEADER) ?? context.defaultNamespace\n const adminNamespace = (request: Request, url: URL): string =>\n url.searchParams.get(\"namespace\") ?? headerNamespace(request)\n\n const builtin: AdminRoutes = {\n \"GET /\": () =>\n json(200, {\n service: context.name,\n routes: [...Object.keys(builtin), ...Object.keys(context.routes)].sort(),\n }),\n\n \"POST /reset\": async ({ url, namespace }) => {\n const target = url.searchParams.get(\"all\") === \"1\" ? \"*\" : namespace\n await context.reset(target)\n return json(200, { status: \"ok\", reset: target === \"*\" ? context.namespaces() : [target] })\n },\n\n \"GET /namespaces\": () =>\n json(200, { default: context.defaultNamespace, namespaces: context.namespaces() }),\n\n \"GET /clock\": () => json(200, context.clock.state()),\n \"POST /clock\": ({ body }) => {\n if (!isRecord(body)) return adminError(400, \"expected a JSON object\")\n if (body.reset === true) context.clock.reset()\n if (body.set !== undefined) {\n const instant = parseInstant(body.set)\n if (instant === undefined) return adminError(400, \"set: expected epoch ms or ISO-8601\")\n context.clock.set(instant)\n }\n if (body.advance !== undefined) {\n const delta = parseDuration(body.advance)\n if (delta === undefined) return adminError(400, 'advance: expected ms or \"15m\"-style')\n context.clock.advance(delta)\n }\n if (body.freeze === true) context.clock.freeze()\n if (body.freeze === false) context.clock.unfreeze()\n return json(200, context.clock.state())\n },\n\n \"GET /faults\": () => json(200, { faults: context.faults.list() }),\n \"POST /faults\": ({ body, namespace }) => {\n if (isRecord(body) && typeof body.preset === \"string\") {\n if (!context.applyPreset) return adminError(400, `${context.name} has no fault presets`)\n const { preset, ...overrides } = body\n try {\n return json(201, {\n preset,\n rules: context.applyPreset(preset, namespace, overrides as Partial<FaultRule>),\n })\n } catch (error) {\n return adminError(404, error instanceof Error ? error.message : String(error))\n }\n }\n if (\n !isRecord(body) ||\n (typeof body.status !== \"number\" &&\n typeof body.delayMs !== \"number\" &&\n typeof body.latencyMs !== \"number\" &&\n body.drop !== true &&\n typeof body.effect !== \"string\")\n ) {\n return adminError(\n 400,\n \"a fault needs a numeric status, a delayMs/latencyMs, drop: true, an effect, or a preset\",\n )\n }\n const rule = {\n // Scoped to the caller's namespace unless it asks for every one, so one worker's\n // injected failure never lands on another's request.\n namespace,\n ...body,\n id: typeof body.id === \"string\" ? body.id : `fault_${context.faults.list().length + 1}`,\n } as FaultRule\n return json(201, context.faults.add(rule))\n },\n \"DELETE /faults\": ({ url }) => {\n const id = url.searchParams.get(\"id\")\n if (id === null) {\n context.faults.clear()\n return json(200, { status: \"ok\" })\n }\n return context.faults.remove(id)\n ? json(200, { status: \"ok\" })\n : adminError(404, `no fault ${id}`)\n },\n\n \"POST /snapshots\": ({ namespace }) => {\n const point = context.timeTravel.checkpoint(namespace, \"main\")\n context.timeTravel.retain(namespace, point.id)\n snapshotCounter++\n const id = `snap_${snapshotCounter}`\n snapshots.set(id, { namespace, checkpoint: point.id })\n return json(201, { id, namespace, records: point.records ?? 0 })\n },\n \"POST /snapshots/:id/restore\": ({ params, namespace }) => {\n const alias = snapshots.get(params.id as string)\n if (!alias) return adminError(404, `no snapshot ${params.id}`)\n if (alias.namespace !== namespace) {\n return adminError(409, `snapshot ${params.id} belongs to namespace ${alias.namespace}`)\n }\n context.timeTravel.checkout(alias.checkpoint, { namespace, branch: \"main\" })\n return json(200, { status: \"ok\", id: params.id, namespace })\n },\n \"DELETE /snapshots/:id\": ({ params }) => {\n const id = params.id as string\n const alias = snapshots.get(id)\n if (!alias) return adminError(404, `no snapshot ${id}`)\n snapshots.delete(id)\n context.timeTravel.release(alias.namespace, alias.checkpoint)\n return json(200, { status: \"ok\" })\n },\n\n \"GET /timeline\": ({ namespace }) => json(200, context.timeTravel.inspect(namespace)),\n \"POST /checkpoints\": ({ body, namespace }) => {\n const branch = isRecord(body) && typeof body.branch === \"string\" ? body.branch : \"main\"\n try {\n return json(201, context.timeTravel.checkpoint(namespace, branch))\n } catch (error) {\n return adminError(409, error instanceof Error ? error.message : String(error))\n }\n },\n \"POST /branches/:name\": ({ params, body, namespace }) => {\n const at = isRecord(body) && typeof body.at === \"string\" ? body.at : undefined\n try {\n return json(\n 201,\n context.timeTravel.branch(params.name as string, {\n namespace,\n ...(at !== undefined ? { at } : {}),\n }),\n )\n } catch (error) {\n return adminError(409, error instanceof Error ? error.message : String(error))\n }\n },\n \"POST /branches/:name/checkout\": ({ params, body, namespace }) => {\n if (!isRecord(body) || typeof body.checkpoint !== \"string\") {\n return adminError(400, 'expected {\"checkpoint\":\"cp_...\"}')\n }\n try {\n context.timeTravel.checkout(body.checkpoint, {\n namespace,\n branch: params.name as string,\n })\n return json(200, { status: \"ok\", branch: params.name, checkpoint: body.checkpoint })\n } catch (error) {\n return adminError(409, error instanceof Error ? error.message : String(error))\n }\n },\n\n \"GET /requests\": ({ url, namespace }) => {\n const status = url.searchParams.get(\"status\")\n const since = url.searchParams.get(\"since\")\n const limit = url.searchParams.get(\"limit\")\n const sinceMs =\n since === null ? undefined : parseInstant(/^\\d+$/.test(since) ? Number(since) : since)\n if (since !== null && sinceMs === undefined) {\n return adminError(400, \"since: expected epoch ms or ISO-8601\")\n }\n if (status !== null && !/^\\d{3}$/.test(status))\n return adminError(400, \"status: expected an HTTP status\")\n if (limit !== null && !/^\\d+$/.test(limit)) return adminError(400, \"limit: expected a count\")\n const operationId = url.searchParams.get(\"operationId\")\n const everyNamespace = url.searchParams.get(\"all\") === \"1\"\n return json(200, {\n size: context.journal.size,\n requests: context.journal.list({\n ...(everyNamespace ? {} : { namespace }),\n ...(operationId !== null ? { operationId } : {}),\n ...(status !== null ? { status: Number(status) } : {}),\n ...(sinceMs !== undefined ? { since: sinceMs } : {}),\n ...(limit !== null ? { limit: Number(limit) } : {}),\n }),\n })\n },\n \"DELETE /requests\": ({ url, namespace }) => {\n context.journal.clear(url.searchParams.get(\"all\") === \"1\" ? undefined : namespace)\n return json(200, { status: \"ok\" })\n },\n\n \"GET /metrics\": () => json(200, context.metrics.report()),\n \"DELETE /metrics\": () => {\n context.metrics.reset()\n return json(200, { status: \"ok\" })\n },\n }\n\n const routes = [...Object.entries(context.routes), ...Object.entries(builtin)].map(\n ([key, handler]) => {\n const space = key.indexOf(\" \")\n return { method: key.slice(0, space), pattern: key.slice(space + 1), handler }\n },\n )\n\n return {\n namespaceOf: headerNamespace,\n async handle(request) {\n const url = new URL(request.url)\n if (url.pathname === HEALTH_PATH && request.method === \"GET\") {\n return json(200, {\n status: \"ok\",\n service: context.name,\n uptimeMs: context.wallNow() - context.startedAt,\n clock: context.clock.state(),\n namespaces: context.namespaces().length,\n adminUi: `${ADMIN_PREFIX}/ui`,\n ...context.describe(),\n })\n }\n if (url.pathname !== ADMIN_PREFIX && !url.pathname.startsWith(`${ADMIN_PREFIX}/`)) {\n return undefined\n }\n const path = url.pathname.slice(ADMIN_PREFIX.length) || \"/\"\n // The shell has no data. Panel markup stays on GET /ui/manifest, which is locked.\n const shell = request.method === \"GET\" && (path === \"/ui\" || path === \"/ui/\")\n if (\n !shell &&\n context.adminKey !== undefined &&\n request.headers.get(ADMIN_KEY_HEADER) !== context.adminKey\n ) {\n return adminError(401, `missing or wrong ${ADMIN_KEY_HEADER}`)\n }\n for (const route of routes) {\n if (route.method !== request.method) continue\n const params = matchRoute(route.pattern, path)\n if (!params) continue\n let body: unknown\n try {\n body = await readJson(request)\n } catch {\n return adminError(400, \"request body is not valid JSON\")\n }\n return route.handler({\n request,\n url,\n params,\n namespace: adminNamespace(request, url),\n body,\n })\n }\n return adminError(\n 404,\n `no admin route ${request.method} ${path}; GET ${ADMIN_PREFIX} lists them`,\n )\n },\n }\n}\n", "/**\n * Reading the vendor credential a request carries.\n *\n * Several vendor SDKs (Stripe, AWS, PostHog, Twilio) cannot add a namespace header, so a\n * runtime can also pick a request's namespace from its credential: a suite maps each\n * worker's API key, token or account SID to a namespace through `PUT /__admin/credentials`.\n * These helpers pull the credential out of the usual carriers.\n */\n\n/** The token after `Bearer `, or `undefined`. */\nexport const bearerToken = (request: Request): string | undefined => {\n const header = request.headers.get(\"authorization\")\n if (!header) return undefined\n const match = /^Bearer\\s+(.+)$/i.exec(header.trim())\n return match?.[1]?.trim() || undefined\n}\n\nexport type BasicCredentials = { username: string; password: string }\n\n/** `{ username, password }` from `Authorization: Basic \u2026`, or `undefined`. */\nexport const basicAuth = (request: Request): BasicCredentials | undefined => {\n const header = request.headers.get(\"authorization\")\n if (!header) return undefined\n const match = /^Basic\\s+(.+)$/i.exec(header.trim())\n if (!match?.[1]) return undefined\n let decoded: string\n try {\n decoded = atob(match[1].trim())\n } catch {\n return undefined\n }\n const colon = decoded.indexOf(\":\")\n if (colon < 0) return { username: decoded, password: \"\" }\n return { username: decoded.slice(0, colon), password: decoded.slice(colon + 1) }\n}\n\n/**\n * The access key id of an AWS SigV4-signed request (`Credential=AKID/date/region/service/\u2026`),\n * from the `Authorization` header or a presigned `X-Amz-Credential` query parameter.\n */\nexport const sigV4AccessKeyId = (request: Request): string | undefined => {\n const header = request.headers.get(\"authorization\")\n const fromHeader = header ? /Credential=([^/,\\s]+)\\//.exec(header)?.[1] : undefined\n if (fromHeader) return fromHeader\n const query = new URL(request.url).searchParams.get(\"X-Amz-Credential\")\n return query ? (query.split(\"/\")[0] ?? undefined) : undefined\n}\n\n/** The credential in any of the common carriers: Bearer, Basic username, SigV4, or `x-api-key`. */\nexport const anyCredential = (request: Request): string | undefined =>\n bearerToken(request) ??\n basicAuth(request)?.username ??\n sigV4AccessKeyId(request) ??\n request.headers.get(\"x-api-key\") ??\n undefined\n\n/** Credential \u2192 namespace mapping behind `PUT /__admin/credentials`. */\nexport type CredentialRegistry = {\n set(credential: string, namespace: string): void\n get(credential: string): string | undefined\n remove(credential: string): boolean\n clear(): void\n entries(): { credential: string; namespace: string }[]\n}\n\nexport const createCredentialRegistry = (): CredentialRegistry => {\n const map = new Map<string, string>()\n return {\n set: (credential, namespace) => {\n map.set(credential, namespace)\n },\n get: (credential) => map.get(credential),\n remove: (credential) => map.delete(credential),\n clear: () => map.clear(),\n entries: () =>\n [...map]\n .map(([credential, namespace]) => ({ credential, namespace }))\n .sort((a, b) => a.credential.localeCompare(b.credential)),\n }\n}\n\n/** A credential shown in admin output: enough to recognise it, never the whole secret. */\nexport const maskCredential = (credential: string): string =>\n credential.length <= 8\n ? `${credential.slice(0, 2)}\u2026`\n : `${credential.slice(0, 6)}\u2026${credential.slice(-2)}`\n", "/**\n * Seeded pseudo-random numbers, so anything a mock invents \u2014 ids, jitter, which\n * request a percentage fault hits \u2014 is reproducible from a seed.\n *\n * mulberry32: small, fast, and stable across runtimes, which matters more here\n * than statistical quality.\n */\nexport type Rng = {\n /** Next value in `[0, 1)`. */\n next(): number\n /** Next integer in `[min, max]`. */\n int(min: number, max: number): number\n /** Restart the stream from its seed. */\n reset(): void\n /** Serializable engine state used by deterministic checkpoints. */\n state(): number\n /** Restore a state previously returned by {@link state}. */\n setState(state: number): void\n seed: number\n}\n\n/** Hash an arbitrary string into a 32-bit seed, so callers can seed by name. */\nexport const seedFrom = (value: string): number => {\n let hash = 2166136261\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 16777619)\n }\n return hash >>> 0\n}\n\nexport const createRng = (seed: number | string = 0): Rng => {\n const numeric = typeof seed === \"string\" ? seedFrom(seed) : seed >>> 0\n let state = numeric\n const next = () => {\n state = (state + 0x6d2b79f5) >>> 0\n let t = state\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n return {\n next,\n int: (min, max) => min + Math.floor(next() * (max - min + 1)),\n reset: () => {\n state = numeric\n },\n state: () => state,\n setState: (next) => {\n if (!Number.isSafeInteger(next) || next < 0 || next > 0xffffffff) {\n throw new RangeError(\"rng state must be an unsigned 32-bit integer\")\n }\n state = next >>> 0\n },\n seed: numeric,\n }\n}\n", "import { createRng, type Rng } from \"./rng.js\"\n\n/**\n * A deliberate failure injected in front of an operation.\n *\n * This is how a suite reaches the vendor's failure modes without the vendor: the\n * quota error that only appears when a shared sandbox is full, the 429 that only\n * appears under load, the 5xx that proves a retry path works.\n */\nexport type FaultRule = {\n /** Stable id, so a suite can retire exactly the rule it added. */\n id: string\n /** Fault only this operation. Omit to match every operation. */\n operationId?: string\n /** Fault only this HTTP method, case-insensitive. Omit to match every method. */\n method?: string\n /** Fault only paths starting with this prefix. Omit to match every path. */\n pathPrefix?: string\n /**\n * Fault only this namespace. Omit (or `\"*\"`) to fault every namespace \u2014 which is what\n * an in-process caller usually wants, and what a parallel worker usually does not:\n * rules added through `POST /__admin/faults` default to the calling namespace.\n */\n namespace?: string\n /**\n * Status of the injected response. Omit for a rule that only delays (`delayMs` /\n * `latencyMs`), only drops the connection (`drop`), or only switches on an `effect`:\n * the request then still reaches the service.\n */\n status?: number\n /** Response body, serialized as JSON. A string is sent as-is. */\n body?: unknown\n headers?: Record<string, string>\n /** Retire the rule after this many faults. Omit to keep it until removed. */\n count?: number\n /** Fault this fraction of matching requests, `0`\u2013`1`. Default `1`. */\n rate?: number\n /** Hold the response back this long, to exercise timeouts. */\n delayMs?: number\n /** Alias of `delayMs`. */\n latencyMs?: number\n /**\n * Drop the connection instead of answering: an in-process `fetch` rejects with a\n * `TypeError`, and a served mock destroys the socket. Models \"unknown outcome\" failures.\n */\n drop?: boolean\n /**\n * A named service behaviour to switch on for the matching request instead of (or\n * before) a canned response, e.g. `created_but_500` or `numeric_tracking_id`. Services\n * read it with `faultEffects(request)`.\n */\n effect?: string\n /** Parameters for `effect`. */\n params?: Record<string, unknown>\n /** From the preset this rule was expanded from, if any. */\n preset?: string\n}\n\n/** A fault that fired for one request. */\nexport type FaultHit = {\n id: string\n /** The injected response; absent when the rule only delays, drops, or sets an effect. */\n response?: Response\n drop?: boolean\n effect?: { name: string; params: Record<string, unknown> }\n}\n\n/**\n * A named, documented fault a suite switches on by name\n * (`POST /__admin/faults {\"preset\": \"rate_limited\"}`): one or more rules, and optionally a\n * webhook delivery fault.\n */\nexport type FaultPreset = {\n description: string\n rules?: Omit<FaultRule, \"id\">[]\n webhook?: { mode: \"duplicate\" | \"reorder\" | \"drop\"; count?: number }\n}\n\n/**\n * Body of `GET /__admin/faults/presets`.\n * `presets` is a list of named presets. A record keyed by name is not this type:\n * the admin page maps the list.\n */\nexport type FaultPresetList = {\n presets: readonly { name: string }[]\n}\n\ntype _AssertFaultPresetList<T extends FaultPresetList> = T\n// @ts-expect-error presets is a list of { name }, not a record keyed by name\ntype _RecordIsNotAPresetList = _AssertFaultPresetList<{ presets: Record<string, { name: string }> }>\n\n/** What a request looks like to the fault matcher. */\nexport type FaultCandidate = {\n operationId: string | undefined\n method: string\n path: string\n namespace: string\n}\n\nexport type FaultRegistry = {\n add(rule: FaultRule): FaultRule\n list(): (FaultRule & { remaining: number | null; hits: number })[]\n remove(id: string): boolean\n clear(): void\n /**\n * Every fault this request should get, in rule order, stopping at the first that answers\n * or drops (effect-only and delay-only rules let later rules match too). Consumes one of\n * each matching rule's remaining uses.\n */\n take(candidate: FaultCandidate): Promise<FaultHit[]>\n}\n\ntype Entry = { rule: FaultRule; remaining: number | null; hits: number }\n\nconst matches = (rule: FaultRule, candidate: FaultCandidate): boolean => {\n if (\n rule.namespace !== undefined &&\n rule.namespace !== \"*\" &&\n rule.namespace !== candidate.namespace\n ) {\n return false\n }\n if (rule.operationId !== undefined && rule.operationId !== candidate.operationId) return false\n if (rule.method !== undefined && rule.method.toUpperCase() !== candidate.method.toUpperCase()) {\n return false\n }\n if (rule.pathPrefix !== undefined && !candidate.path.startsWith(rule.pathPrefix)) return false\n return true\n}\n\nconst faultResponse = (rule: FaultRule): Response => {\n const status = rule.status ?? 500\n const headers = { \"content-type\": \"application/json\", ...rule.headers }\n if (typeof rule.body === \"string\") return new Response(rule.body, { status, headers })\n if (rule.body === null) return new Response(null, { status, headers: rule.headers ?? {} })\n const body = rule.body === undefined ? { detail: \"Injected by Mockingbird\" } : rule.body\n return new Response(JSON.stringify(body), { status, headers })\n}\n\n/**\n * Rules are matched in the order they were added, so a narrow rule added first\n * wins over a later catch-all. `rate` draws from `rng`, which is seeded, so a\n * partial-failure run replays identically.\n */\nexport const createFaultRegistry = (\n rng: Rng = createRng(0),\n sleep: (ms: number) => Promise<void> = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n): FaultRegistry => {\n const entries: Entry[] = []\n return {\n add(rule) {\n const existing = entries.findIndex((e) => e.rule.id === rule.id)\n const entry: Entry = { rule, remaining: rule.count ?? null, hits: 0 }\n if (existing >= 0) entries[existing] = entry\n else entries.push(entry)\n return rule\n },\n list: () => entries.map((e) => ({ ...e.rule, remaining: e.remaining, hits: e.hits })),\n remove(id) {\n const index = entries.findIndex((e) => e.rule.id === id)\n if (index < 0) return false\n entries.splice(index, 1)\n return true\n },\n clear() {\n entries.length = 0\n },\n async take(candidate) {\n const hits: FaultHit[] = []\n for (const entry of entries) {\n if (entry.remaining === 0) continue\n if (!matches(entry.rule, candidate)) continue\n const rate = entry.rule.rate ?? 1\n // Draw even when the rule always fires, so a seeded stream stays aligned.\n if (rng.next() >= rate) continue\n entry.hits++\n if (entry.remaining !== null) entry.remaining--\n const delay = entry.rule.delayMs ?? entry.rule.latencyMs\n if (delay !== undefined && delay > 0) {\n await sleep(delay)\n }\n const hit: FaultHit = { id: entry.rule.id }\n if (entry.rule.effect !== undefined) {\n hit.effect = { name: entry.rule.effect, params: entry.rule.params ?? {} }\n }\n if (entry.rule.drop === true) hit.drop = true\n else if (entry.rule.status !== undefined) hit.response = faultResponse(entry.rule)\n hits.push(hit)\n if (hit.drop || hit.response) break\n }\n return hits\n },\n }\n}\n", "import type { OpenAPIDocument, ReferenceObject } from \"./types.js\"\n\nexport class OpenAPIReferenceError extends Error {\n constructor(readonly ref: string) {\n super(`unresolvable $ref: ${ref}`)\n this.name = \"OpenAPIReferenceError\"\n }\n}\n\nconst unescapePointer = (segment: string) => segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\")\n\n/** True when `value` is a `{ $ref }` object. */\nexport const isReference = (value: unknown): value is ReferenceObject =>\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { $ref?: unknown }).$ref === \"string\"\n\n/** Resolve a local JSON pointer reference (`#/components/schemas/customer`) inside `document`. */\nexport const resolveRef = (document: OpenAPIDocument, ref: string): unknown => {\n if (!ref.startsWith(\"#/\")) throw new OpenAPIReferenceError(ref)\n let cursor: unknown = document\n for (const raw of ref.slice(2).split(\"/\")) {\n const segment = unescapePointer(raw)\n if (typeof cursor !== \"object\" || cursor === null || !(segment in cursor)) {\n throw new OpenAPIReferenceError(ref)\n }\n cursor = (cursor as Record<string, unknown>)[segment]\n }\n if (cursor === undefined) throw new OpenAPIReferenceError(ref)\n return cursor\n}\n\n/**\n * Follow `$ref` chains until a concrete object is reached. Guards against cycles.\n * Sibling keys next to `$ref` are ignored, as in OpenAPI 3.0/3.1 for non-schema objects.\n */\nexport const deref = <T>(document: OpenAPIDocument, value: T | ReferenceObject): T => {\n let current: unknown = value\n const seen = new Set<string>()\n while (isReference(current)) {\n if (seen.has(current.$ref)) throw new OpenAPIReferenceError(`${current.$ref} (cycle)`)\n seen.add(current.$ref)\n current = resolveRef(document, current.$ref)\n }\n return current as T\n}\n\n/** The component name at the end of a `#/components/<kind>/<name>` reference, if any. */\nexport const componentNameOf = (ref: string): string | undefined => {\n const match = /^#\\/components\\/[^/]+\\/(.+)$/.exec(ref)\n return match?.[1] === undefined ? undefined : unescapePointer(match[1])\n}\n", "/**\n * The slice of OpenAPI 3.1 (and JSON Schema 2020-12) Mockingbird understands.\n * Unknown keys (including `x-*` extensions) are preserved on every object.\n */\n\nexport type JsonPrimitive = string | number | boolean | null\nexport type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }\n\nexport type ReferenceObject = { $ref: string; description?: string; summary?: string }\n\nexport type SchemaType = \"string\" | \"number\" | \"integer\" | \"boolean\" | \"object\" | \"array\" | \"null\"\n\nexport type SchemaObject = {\n $ref?: string\n type?: SchemaType | SchemaType[]\n title?: string\n description?: string\n format?: string\n enum?: JsonValue[]\n const?: JsonValue\n default?: JsonValue\n example?: JsonValue\n examples?: JsonValue[]\n nullable?: boolean\n deprecated?: boolean\n readOnly?: boolean\n writeOnly?: boolean\n minimum?: number\n maximum?: number\n exclusiveMinimum?: number\n exclusiveMaximum?: number\n multipleOf?: number\n minLength?: number\n maxLength?: number\n pattern?: string\n minItems?: number\n maxItems?: number\n uniqueItems?: boolean\n items?: SchemaObject\n prefixItems?: SchemaObject[]\n minProperties?: number\n maxProperties?: number\n required?: string[]\n properties?: Record<string, SchemaObject>\n additionalProperties?: boolean | SchemaObject\n propertyNames?: SchemaObject\n oneOf?: SchemaObject[]\n anyOf?: SchemaObject[]\n allOf?: SchemaObject[]\n not?: SchemaObject\n discriminator?: { propertyName: string; mapping?: Record<string, string> }\n [extension: `x-${string}`]: unknown\n}\n\nexport type ParameterLocation = \"path\" | \"query\" | \"header\" | \"cookie\"\n\nexport type ParameterObject = {\n name: string\n in: ParameterLocation\n description?: string\n required?: boolean\n deprecated?: boolean\n style?: string\n explode?: boolean\n schema?: SchemaObject\n content?: Record<string, MediaTypeObject>\n example?: JsonValue\n [extension: `x-${string}`]: unknown\n}\n\nexport type MediaTypeObject = {\n schema?: SchemaObject\n example?: JsonValue\n examples?: Record<string, unknown>\n encoding?: Record<string, unknown>\n [extension: `x-${string}`]: unknown\n}\n\nexport type RequestBodyObject = {\n description?: string\n required?: boolean\n content: Record<string, MediaTypeObject>\n [extension: `x-${string}`]: unknown\n}\n\nexport type HeaderObject = {\n description?: string\n required?: boolean\n schema?: SchemaObject\n [extension: `x-${string}`]: unknown\n}\n\nexport type ResponseObject = {\n description: string\n headers?: Record<string, HeaderObject | ReferenceObject>\n content?: Record<string, MediaTypeObject>\n [extension: `x-${string}`]: unknown\n}\n\nexport type ResponsesObject = Record<string, ResponseObject | ReferenceObject>\n\nexport type SecurityRequirementObject = Record<string, string[]>\n\nexport type OperationObject = {\n operationId?: string\n summary?: string\n description?: string\n tags?: string[]\n deprecated?: boolean\n parameters?: Array<ParameterObject | ReferenceObject>\n requestBody?: RequestBodyObject | ReferenceObject\n responses: ResponsesObject\n security?: SecurityRequirementObject[]\n [extension: `x-${string}`]: unknown\n}\n\nexport const HTTP_METHODS = [\n \"get\",\n \"put\",\n \"post\",\n \"delete\",\n \"options\",\n \"head\",\n \"patch\",\n \"trace\",\n] as const\nexport type HttpMethod = (typeof HTTP_METHODS)[number]\n\nexport type PathItemObject = {\n summary?: string\n description?: string\n parameters?: Array<ParameterObject | ReferenceObject>\n [extension: `x-${string}`]: unknown\n} & Partial<Record<HttpMethod, OperationObject>>\n\nexport type SecuritySchemeObject = {\n type: \"apiKey\" | \"http\" | \"oauth2\" | \"openIdConnect\" | \"mutualTLS\"\n description?: string\n name?: string\n in?: ParameterLocation\n scheme?: string\n bearerFormat?: string\n flows?: Record<string, unknown>\n openIdConnectUrl?: string\n [extension: `x-${string}`]: unknown\n}\n\nexport type ComponentsObject = {\n schemas?: Record<string, SchemaObject>\n responses?: Record<string, ResponseObject>\n parameters?: Record<string, ParameterObject>\n requestBodies?: Record<string, RequestBodyObject>\n headers?: Record<string, HeaderObject>\n securitySchemes?: Record<string, SecuritySchemeObject>\n [extension: `x-${string}`]: unknown\n}\n\nexport type ServerObject = {\n url: string\n description?: string\n variables?: Record<string, unknown>\n [extension: `x-${string}`]: unknown\n}\n\nexport type InfoObject = {\n title: string\n version: string\n description?: string\n [extension: `x-${string}`]: unknown\n}\n\nexport type OpenAPIDocument = {\n openapi: string\n info: InfoObject\n servers?: ServerObject[]\n paths: Record<string, PathItemObject>\n components?: ComponentsObject\n security?: SecurityRequirementObject[]\n tags?: Array<{ name: string; description?: string }>\n [extension: `x-${string}`]: unknown\n}\n\n/** One concrete HTTP operation discovered in a document. */\nexport type Operation = {\n operationId: string\n method: HttpMethod\n /** OpenAPI path template, e.g. `/v1/customers/{customer}`. */\n path: string\n operation: OperationObject\n /** Path-level parameters merged with operation-level ones (operation wins), `$ref`s resolved. */\n parameters: ParameterObject[]\n requestBody: RequestBodyObject | undefined\n responses: Record<string, ResponseObject>\n}\n", "import { deref, isReference, resolveRef } from \"./refs.js\"\nimport {\n HTTP_METHODS,\n type HttpMethod,\n type OpenAPIDocument,\n type Operation,\n type ParameterObject,\n type PathItemObject,\n type RequestBodyObject,\n type ResponseObject,\n} from \"./types.js\"\n\nexport class OpenAPIDocumentError extends Error {\n constructor(readonly issues: string[]) {\n super(`invalid OpenAPI document:\\n${issues.map((issue) => ` - ${issue}`).join(\"\\n\")}`)\n this.name = \"OpenAPIDocumentError\"\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\n/**\n * Accept an already-parsed JSON/YAML value and return it typed as an {@link OpenAPIDocument}.\n * Performs the structural checks Mockingbird relies on (see {@link validateOpenAPIDocument}) and\n * throws {@link OpenAPIDocumentError} listing every problem.\n */\nexport const parseOpenAPIDocument = (value: unknown): OpenAPIDocument => {\n const issues: string[] = []\n if (!isRecord(value)) throw new OpenAPIDocumentError([\"document must be an object\"])\n if (typeof value.openapi !== \"string\" || !/^3\\.[01]\\./.test(value.openapi)) {\n issues.push(\n `openapi must be a 3.0.x or 3.1.x version string, got ${JSON.stringify(value.openapi)}`,\n )\n }\n if (\n !isRecord(value.info) ||\n typeof value.info.title !== \"string\" ||\n typeof value.info.version !== \"string\"\n ) {\n issues.push(\"info.title and info.version are required strings\")\n }\n if (!isRecord(value.paths)) issues.push(\"paths must be an object\")\n if (issues.length > 0) throw new OpenAPIDocumentError(issues)\n const document = value as unknown as OpenAPIDocument\n const problems = validateOpenAPIDocument(document)\n if (problems.length > 0) throw new OpenAPIDocumentError(problems)\n return document\n}\n\nconst walkRefs = (\n document: OpenAPIDocument,\n node: unknown,\n at: string,\n issues: string[],\n seen: Set<unknown>,\n) => {\n if (typeof node !== \"object\" || node === null || seen.has(node)) return\n seen.add(node)\n if (isReference(node)) {\n try {\n resolveRef(document, node.$ref)\n } catch {\n issues.push(`${at}: unresolvable $ref ${node.$ref}`)\n }\n }\n for (const [key, child] of Object.entries(node))\n walkRefs(document, child, `${at}/${key}`, issues, seen)\n}\n\nconst templateParams = (path: string) =>\n [...path.matchAll(/\\{([^}]+)\\}/g)].map((m) => m[1] as string)\n\n/**\n * Mockingbird's document rules:\n * - every operation has a unique `operationId`\n * - every `$ref` resolves\n * - every `{param}` in a path template has a matching required path parameter\n * - every path parameter appears in the template\n */\nexport const validateOpenAPIDocument = (document: OpenAPIDocument): string[] => {\n const issues: string[] = []\n walkRefs(document, document, \"#\", issues, new Set())\n if (issues.length > 0) return issues\n const seenIds = new Map<string, string>()\n for (const [path, item] of Object.entries(document.paths)) {\n if (!isRecord(item)) {\n issues.push(`paths.${path}: must be an object`)\n continue\n }\n const inTemplate = new Set(templateParams(path))\n for (const method of HTTP_METHODS) {\n const operation = item[method]\n if (operation === undefined) continue\n const label = `${method.toUpperCase()} ${path}`\n if (typeof operation.operationId !== \"string\" || operation.operationId.length === 0) {\n issues.push(`${label}: operationId is required`)\n continue\n }\n const previous = seenIds.get(operation.operationId)\n if (previous !== undefined)\n issues.push(`${label}: duplicate operationId ${operation.operationId} (also ${previous})`)\n seenIds.set(operation.operationId, label)\n if (!isRecord(operation.responses) || Object.keys(operation.responses).length === 0) {\n issues.push(`${label}: responses must declare at least one status`)\n }\n const parameters = mergeParameters(document, item, operation.parameters)\n const declared = new Set(parameters.filter((p) => p.in === \"path\").map((p) => p.name))\n for (const name of inTemplate) {\n if (!declared.has(name)) issues.push(`${label}: path parameter {${name}} is not declared`)\n }\n for (const parameter of parameters) {\n if (parameter.in === \"path\") {\n if (!inTemplate.has(parameter.name))\n issues.push(`${label}: path parameter ${parameter.name} is not in the template`)\n if (parameter.required !== true)\n issues.push(`${label}: path parameter ${parameter.name} must be required`)\n }\n }\n }\n }\n return issues\n}\n\nconst mergeParameters = (\n document: OpenAPIDocument,\n item: PathItemObject,\n own: PathItemObject[\"parameters\"],\n): ParameterObject[] => {\n const merged = new Map<string, ParameterObject>()\n for (const raw of item.parameters ?? []) {\n const parameter = deref<ParameterObject>(document, raw)\n merged.set(`${parameter.in}:${parameter.name}`, parameter)\n }\n for (const raw of own ?? []) {\n const parameter = deref<ParameterObject>(document, raw)\n merged.set(`${parameter.in}:${parameter.name}`, parameter)\n }\n return [...merged.values()]\n}\n\n/** Enumerate every operation in the document in path, then method order. */\nexport const listOperations = (document: OpenAPIDocument): Operation[] => {\n const operations: Operation[] = []\n for (const [path, item] of Object.entries(document.paths)) {\n for (const method of HTTP_METHODS) {\n const operation = item[method]\n if (operation?.operationId === undefined) continue\n const responses: Record<string, ResponseObject> = {}\n for (const [status, response] of Object.entries(operation.responses)) {\n responses[status] = deref<ResponseObject>(document, response)\n }\n operations.push({\n operationId: operation.operationId,\n method,\n path,\n operation,\n parameters: mergeParameters(document, item, operation.parameters),\n requestBody:\n operation.requestBody === undefined\n ? undefined\n : deref<RequestBodyObject>(document, operation.requestBody),\n responses,\n })\n }\n }\n return operations\n}\n\n/** Find one operation by id. */\nexport const findOperation = (\n document: OpenAPIDocument,\n operationId: string,\n): Operation | undefined =>\n listOperations(document).find((operation) => operation.operationId === operationId)\n\n/** Parameter names inside a path template, in order. */\nexport const pathTemplateParameters = templateParams\n\n/** Substitute `{name}` placeholders. Values are percent-encoded as path segments. */\nexport const expandPathTemplate = (template: string, values: Record<string, string>): string =>\n template.replace(/\\{([^}]+)\\}/g, (_, name: string) => {\n const value = values[name]\n if (value === undefined) throw new RangeError(`missing path parameter ${name}`)\n return encodeURIComponent(value)\n })\n\n/** The response object matching an HTTP status: exact match, then `2XX`-style range, then `default`. */\nexport const responseForStatus = (\n responses: Record<string, ResponseObject>,\n status: number,\n): ResponseObject | undefined =>\n responses[String(status)] ?? responses[`${Math.floor(status / 100)}XX`] ?? responses.default\n\nexport type { HttpMethod }\n", "/**\n * Rails/PHP/Stripe-style bracket notation for `application/x-www-form-urlencoded` bodies and\n * query strings:\n *\n * address[city]=Paris -> { address: { city: \"Paris\" } }\n * items[0][name]=a -> { items: [{ name: \"a\" }] }\n * tags[]=x&tags[]=y -> { tags: [\"x\", \"y\"] }\n * metadata[k]=v -> { metadata: { k: \"v\" } }\n *\n * Decoding yields only strings, arrays and plain objects \u2014 coercion is the caller's concern,\n * exactly like a real HTTP server.\n */\n\nexport type FormValue = string | FormValue[] | { [key: string]: FormValue }\n\nexport type FormObject = { [key: string]: FormValue }\n\nconst encodeComponent = (value: string) =>\n encodeURIComponent(value).replace(\n /[!'()*]/g,\n (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,\n )\n\nconst flatten = (prefix: string, value: unknown, out: Array<[string, string]>) => {\n if (value === undefined) return\n if (value === null) {\n out.push([prefix, \"\"])\n return\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n out.push([prefix, \"\"])\n return\n }\n value.forEach((item, index) => {\n flatten(`${prefix}[${index}]`, item, out)\n })\n return\n }\n if (typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.length === 0) {\n out.push([prefix, \"\"])\n return\n }\n for (const [key, item] of entries) flatten(`${prefix}[${key}]`, item, out)\n return\n }\n out.push([prefix, String(value)])\n}\n\n/**\n * Encode a JSON-like value as bracket-notation pairs. Nested arrays use explicit indices\n * (`a[0]`), which every bracket parser (including Stripe's) accepts; empty arrays/objects\n * encode as an empty string, matching how Stripe unsets fields.\n */\nexport const encodeFormPairs = (value: Record<string, unknown>): Array<[string, string]> => {\n const out: Array<[string, string]> = []\n for (const [key, item] of Object.entries(value)) flatten(key, item, out)\n return out\n}\n\n/** Encode to a full `application/x-www-form-urlencoded` string. */\nexport const encodeForm = (value: Record<string, unknown>): string =>\n encodeFormPairs(value)\n .map(([k, v]) => `${encodeComponent(k)}=${encodeComponent(v)}`)\n .join(\"&\")\n\nconst parsePath = (rawKey: string): string[] => {\n const open = rawKey.indexOf(\"[\")\n if (open === -1) return [rawKey]\n const path = [rawKey.slice(0, open)]\n const rest = rawKey.slice(open)\n const pattern = /\\[([^\\]]*)\\]/g\n let match: RegExpExecArray | null = pattern.exec(rest)\n let consumed = 0\n while (match !== null) {\n if (match.index !== consumed) return [rawKey]\n path.push(match[1] ?? \"\")\n consumed = match.index + match[0].length\n match = pattern.exec(rest)\n }\n if (consumed !== rest.length) return [rawKey]\n return path\n}\n\nconst isIndex = (segment: string) => /^(0|[1-9][0-9]*)$/.test(segment)\n\n/**\n * Write an own property. `__proto__` is the one key with an inherited setter, so it needs\n * `defineProperty`; every other key shadows its inherited namesake by plain assignment.\n */\nconst put = (target: object, key: string | number, value: FormValue): void => {\n if (key === \"__proto__\") {\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n })\n return\n }\n ;(target as Record<string | number, FormValue>)[key] = value\n}\n\nconst assign = (target: FormObject, path: string[], value: string) => {\n let cursor: FormValue = target\n for (let i = 0; i < path.length; i++) {\n const segment = path[i] as string\n const last = i === path.length - 1\n if (Array.isArray(cursor)) {\n const index: number | undefined =\n segment === \"\" ? cursor.length : isIndex(segment) ? Number(segment) : undefined\n if (index === undefined) return\n if (last) {\n put(cursor, index, value)\n return\n }\n const next: FormValue | undefined = Object.hasOwn(cursor, index)\n ? (cursor as Record<number, FormValue>)[index]\n : undefined\n if (next === undefined || typeof next === \"string\") {\n const created: FormValue = path[i + 1] === \"\" || isIndex(path[i + 1] as string) ? [] : {}\n put(cursor, index, created)\n cursor = created\n } else {\n cursor = next\n }\n continue\n }\n if (typeof cursor === \"string\") return\n if (last) {\n put(cursor, segment, value)\n return\n }\n const nextSegment = path[i + 1] as string\n const existing: FormValue | undefined = Object.hasOwn(cursor, segment)\n ? (cursor as Record<string, FormValue>)[segment]\n : undefined\n if (existing === undefined || typeof existing === \"string\") {\n const created: FormValue = nextSegment === \"\" || isIndex(nextSegment) ? [] : {}\n put(cursor, segment, created)\n cursor = created\n } else {\n cursor = existing\n }\n }\n}\n\n/** Decode `key=value&...` pairs (already percent-decoded) into a nested object. */\nexport const decodeFormPairs = (pairs: Iterable<[string, string]>): FormObject => {\n const out: FormObject = {}\n for (const [rawKey, value] of pairs) assign(out, parsePath(rawKey), value)\n return densify(out) as FormObject\n}\n\n/** Sparse arrays (`a[2]=x` without `a[0]`) become dense in bracket parsers. */\nconst densify = (value: FormValue): FormValue => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value)) return value.filter((item) => item !== undefined).map(densify)\n const out: FormObject = {}\n for (const [key, item] of Object.entries(value)) put(out, key, densify(item))\n return out\n}\n\n/** Decode an `application/x-www-form-urlencoded` body or a query string (with or without `?`). */\nexport const decodeForm = (text: string): FormObject => {\n const source = text.startsWith(\"?\") ? text.slice(1) : text\n return decodeFormPairs(new URLSearchParams(source).entries())\n}\n", "import { decodeForm, encodeForm } from \"./form.js\"\n\nexport const JSON_MEDIA_TYPE = \"application/json\"\nexport const FORM_MEDIA_TYPE = \"application/x-www-form-urlencoded\"\n\n/** The essence of a `Content-Type` header: lower-cased media type without parameters. */\nexport const mediaTypeOf = (contentType: string | null | undefined): string | undefined => {\n if (!contentType) return undefined\n const essence = contentType.split(\";\")[0]?.trim().toLowerCase()\n return essence ? essence : undefined\n}\n\nconst isJsonMediaType = (mediaType: string) =>\n mediaType === JSON_MEDIA_TYPE || mediaType.endsWith(\"+json\") || mediaType === \"text/json\"\n\nexport type DecodedBody =\n | { kind: \"empty\" }\n | { kind: \"json\"; value: unknown }\n | { kind: \"form\"; value: Record<string, unknown> }\n | { kind: \"text\"; value: string }\n | { kind: \"bytes\"; value: Uint8Array }\n | { kind: \"invalid\"; mediaType: string; text: string; error: string }\n\nconst utf8 = new TextDecoder(\"utf-8\", { fatal: false })\n\n/**\n * Decode raw bytes according to a `Content-Type`. Never throws: malformed payloads come back as\n * `{ kind: \"invalid\" }` so callers (mock servers, the differential runner) can respond like a real\n * server would instead of crashing.\n */\nexport const decodeBody = (\n contentType: string | null | undefined,\n bytes: Uint8Array,\n): DecodedBody => {\n if (bytes.byteLength === 0) return { kind: \"empty\" }\n const mediaType = mediaTypeOf(contentType)\n if (mediaType === undefined) return { kind: \"bytes\", value: bytes }\n if (isJsonMediaType(mediaType)) {\n const text = utf8.decode(bytes)\n try {\n return { kind: \"json\", value: JSON.parse(text) }\n } catch (error) {\n return {\n kind: \"invalid\",\n mediaType,\n text,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n }\n if (mediaType === FORM_MEDIA_TYPE) {\n return { kind: \"form\", value: decodeForm(utf8.decode(bytes)) }\n }\n if (mediaType.startsWith(\"text/\")) return { kind: \"text\", value: utf8.decode(bytes) }\n return { kind: \"bytes\", value: bytes }\n}\n\n/** Read and decode a Request/Response body. */\nexport const readBody = async (message: Request | Response): Promise<DecodedBody> => {\n const bytes = new Uint8Array(await message.arrayBuffer())\n return decodeBody(message.headers.get(\"content-type\"), bytes)\n}\n\nexport type EncodedBody = {\n contentType: string\n body: string\n}\n\n/** Encode a JSON-like value for the given media type. Throws for unsupported media types. */\nexport const encodeBody = (mediaType: string, value: unknown): EncodedBody => {\n const essence = mediaTypeOf(mediaType) ?? mediaType\n if (isJsonMediaType(essence)) return { contentType: essence, body: JSON.stringify(value) }\n if (essence === FORM_MEDIA_TYPE) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new TypeError(`${FORM_MEDIA_TYPE} bodies must be objects`)\n }\n return { contentType: essence, body: encodeForm(value as Record<string, unknown>) }\n }\n if (essence.startsWith(\"text/\")) return { contentType: essence, body: String(value) }\n throw new TypeError(`unsupported request media type: ${mediaType}`)\n}\n", "import { JSON_MEDIA_TYPE } from \"@crvouga/mockingbird-http-codec\"\n\n/** JSON response with a normalised content type. */\nexport const jsonRes = (\n status: number,\n body: unknown,\n headers: Record<string, string> = {},\n): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": JSON_MEDIA_TYPE, ...headers },\n })\n\n/** Thrown by handlers to produce a provider-shaped error response via `onError`. */\nexport class HttpError extends Error {\n constructor(\n readonly status: number,\n readonly body: unknown,\n readonly headers: Record<string, string> = {},\n ) {\n super(`HTTP ${status}`)\n this.name = \"HttpError\"\n }\n\n toResponse(): Response {\n const contentType = this.headers[\"content-type\"]?.split(\";\", 1)[0]?.trim().toLowerCase()\n if (contentType === \"text/plain\") {\n return new Response(String(this.body), {\n status: this.status,\n headers: this.headers,\n })\n }\n return jsonRes(this.status, this.body, this.headers)\n }\n}\n\nexport type FieldResult<T> = { ok: true; value: T } | { ok: false; reason: string }\n\nconst ok = <T>(value: T): FieldResult<T> => ({ ok: true, value })\nconst fail = <T>(reason: string): FieldResult<T> => ({ ok: false, reason })\n\n/** Form bodies decode to strings; these coerce the way HTTP servers do, reporting why not. */\nexport const coerce = {\n string(value: unknown): FieldResult<string> {\n return typeof value === \"string\" ? ok(value) : fail(\"expected a string\")\n },\n integer(value: unknown): FieldResult<number> {\n if (typeof value === \"number\" && Number.isInteger(value)) return ok(value)\n if (typeof value === \"string\" && /^-?\\d+$/.test(value.trim())) {\n const parsed = Number(value)\n return Number.isSafeInteger(parsed) ? ok(parsed) : fail(\"integer out of range\")\n }\n return fail(\"expected an integer\")\n },\n boolean(value: unknown): FieldResult<boolean> {\n if (typeof value === \"boolean\") return ok(value)\n if (value === \"true\" || value === \"1\") return ok(true)\n if (value === \"false\" || value === \"0\") return ok(false)\n return fail(\"expected a boolean\")\n },\n enumeration<T extends string>(value: unknown, allowed: readonly T[]): FieldResult<T> {\n const match = allowed.find((candidate) => candidate === value)\n return match === undefined ? fail(`expected one of ${allowed.join(\", \")}`) : ok(match)\n },\n /** Flat string-to-string map, the shape of Stripe-style `metadata`. */\n stringMap(value: unknown): FieldResult<Record<string, string>> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value))\n return fail(\"expected an object\")\n const out: Record<string, string> = {}\n for (const [key, item] of Object.entries(value)) {\n if (typeof item !== \"string\") return fail(`expected a string at ${key}`)\n out[key] = item\n }\n return ok(out)\n },\n}\n\n/** Count Unicode code points, the way JSON Schema and most APIs measure string length. */\nexport const codePointLength = (value: string) => [...value].length\n", "import type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\n\nconst ALPHABET = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n\n/** FNV-1a over a string, mixed once more so consecutive counters look unrelated. */\nconst mix = (input: string): number => {\n let hash = 0x811c9dc5\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i)\n hash = Math.imul(hash, 0x01000193) >>> 0\n }\n hash ^= hash >>> 16\n hash = Math.imul(hash, 0x85ebca6b) >>> 0\n hash ^= hash >>> 13\n return hash >>> 0\n}\n\n/** Deterministic, opaque-looking alphanumeric token of `length` characters derived from `input`. */\nexport const opaqueToken = (input: string, length: number): string => {\n let out = \"\"\n let round = 0\n while (out.length < length) {\n let hash = mix(`${input}:${round++}`)\n for (let i = 0; i < 5 && out.length < length; i++) {\n out += ALPHABET.charAt(hash % ALPHABET.length)\n hash = Math.floor(hash / ALPHABET.length)\n }\n }\n return out\n}\n\n/**\n * Sequential id source persisted in SQLite. Ids are deterministic for a given\n * sequence history (`cus_` + 14 opaque chars), so reproductions stay stable.\n */\nexport class IdSequence {\n constructor(\n private readonly sqlite: SqliteClient,\n private readonly namespace: string,\n private readonly salt = \"mockingbird\",\n ) {}\n\n next(prefix: string, length = 14): string {\n return this.sqlite.transaction(() => {\n const row = this.sqlite\n .prepare(\n \"SELECT value FROM mockingbird_sequences WHERE namespace = ? AND name = ? AND kind = 'id'\",\n )\n .get<{ value: number }>(this.namespace, prefix)\n const value = (row?.value ?? 0) + 1\n this.sqlite\n .prepare(\n `INSERT INTO mockingbird_sequences (namespace, name, kind, value) VALUES (?, ?, 'id', ?)\n ON CONFLICT(namespace, name, kind) DO UPDATE SET value = excluded.value`,\n )\n .run(this.namespace, prefix, value)\n return `${prefix}${opaqueToken(`${this.salt}:${prefix}:${value}`, length)}`\n })\n }\n}\n", "import type { RequestLog } from \"./metrics.js\"\nimport type { BodyIssue } from \"./validation.js\"\n\n/** One journal entry: a request log stamped with when (on the mock clock) it was handled. */\nexport type JournalEntry = RequestLog & { at: string }\n\nexport type JournalQuery = {\n /** Only this namespace. Omit for every namespace, oldest first across all of them. */\n namespace?: string\n operationId?: string\n status?: number\n /** Only entries at or after this instant (epoch ms). */\n since?: number\n /** At most this many, the most recent kept. */\n limit?: number\n}\n\nexport type Journal = {\n readonly size: number\n record(entry: JournalEntry): void\n list(query?: JournalQuery): JournalEntry[]\n /** Forget one namespace's entries, or every namespace's. */\n clear(namespace?: string): void\n}\n\n/** Default number of entries each namespace keeps. */\nexport const DEFAULT_JOURNAL_SIZE = 1000\n\n/**\n * The last `size` requests per namespace, in a ring buffer: what the mock actually saw,\n * so a test can prove a request arrived (or never did) without reading logs.\n */\nexport const createJournal = (size: number = DEFAULT_JOURNAL_SIZE): Journal => {\n const capacity = Math.max(0, Math.floor(size))\n const rings = new Map<string, { entries: JournalEntry[]; next: number }>()\n let sequence = 0\n const order = new WeakMap<JournalEntry, number>()\n const inOrder = (ring: { entries: JournalEntry[]; next: number }): JournalEntry[] =>\n ring.entries.length < capacity\n ? ring.entries\n : [...ring.entries.slice(ring.next), ...ring.entries.slice(0, ring.next)]\n return {\n size: capacity,\n record(entry) {\n if (capacity === 0) return\n order.set(entry, sequence++)\n let ring = rings.get(entry.namespace)\n if (!ring) {\n ring = { entries: [], next: 0 }\n rings.set(entry.namespace, ring)\n }\n if (ring.entries.length < capacity) ring.entries.push(entry)\n else {\n ring.entries[ring.next] = entry\n ring.next = (ring.next + 1) % capacity\n }\n },\n list(query = {}) {\n const source =\n query.namespace !== undefined\n ? inOrder(rings.get(query.namespace) ?? { entries: [], next: 0 })\n : [...rings.values()]\n .flatMap(inOrder)\n .sort((a, b) => (order.get(a) ?? 0) - (order.get(b) ?? 0))\n const matched = source.filter(\n (entry) =>\n (query.operationId === undefined || entry.operationId === query.operationId) &&\n (query.status === undefined || entry.status === query.status) &&\n (query.since === undefined || Date.parse(entry.at) >= query.since),\n )\n return query.limit !== undefined ? matched.slice(-Math.max(0, query.limit)) : matched\n },\n clear(namespace) {\n if (namespace === undefined) rings.clear()\n else rings.delete(namespace)\n },\n }\n}\n\n/** What a service knows about a request that the runtime cannot see from outside. */\nexport type ResponseNotes = {\n /** Resource ids the handler touched, e.g. `{ userId, orderId }`. */\n ids?: Record<string, string>\n /** Set when the handler created a resource the request referred to but did not exist. */\n adopted?: boolean\n /** The body validation issues behind a rejection; the runtime logs them, never the body. */\n issues?: BodyIssue[]\n}\n\nconst notes = new WeakMap<Response, ResponseNotes>()\n\n/**\n * Attach notes to a response for the request journal and structured log. They travel\n * beside the response, never in it, so nothing the vendor would not send reaches a client.\n */\nexport const annotateResponse = (response: Response, extra: ResponseNotes): Response => {\n const existing = notes.get(response)\n notes.set(response, {\n ...existing,\n ...extra,\n ...(existing?.ids || extra.ids ? { ids: { ...existing?.ids, ...extra.ids } } : {}),\n })\n return response\n}\n\nexport const responseNotes = (response: Response): ResponseNotes | undefined => notes.get(response)\n", "import type { BodyIssue } from \"./validation.js\"\n\n/**\n * What the mock received from a request it rejected, so a 4xx can be attributed after the\n * fact (an empty body, a missing `content-type`, a schema violation) without logging the body.\n */\nexport type RejectedRequest = {\n /** The raw `content-type` header, or `null` when the request sent none. */\n contentType: string | null\n /** Bytes of body received from `content-length` (`0` for none), or `null` when the client sent no length (a streamed / chunked body). */\n bodyBytes: number | null\n /** The raw `transfer-encoding` header (`chunked`), or `null`. */\n transferEncoding: string | null\n}\n\n/** One handled request, as the structured log sees it. */\nexport type RequestLog = {\n service: string\n namespace: string\n operationId: string | undefined\n method: string\n path: string\n status: number\n durationMs: number\n /** True when the path matched no operation in the contract. */\n unmatched: boolean\n /** Set when a fault rule produced the response. */\n faultId?: string\n /** Resource ids the handler touched (`userId`, `orderId`, \u2026), when the service reports them. */\n ids?: Record<string, string>\n /** Set when the service created a resource the request referred to but that did not exist. */\n adopted?: boolean\n /** Set on a rejection (status \u2265 400) the mock produced itself, never on a scripted fault. */\n request?: RejectedRequest\n /** The validation issues behind a rejection, when the service found any. */\n issues?: BodyIssue[]\n}\n\nexport type MetricsReport = {\n requests: number\n /** Counts keyed `<operationId> <status>`. */\n byOperation: Record<string, number>\n /**\n * Paths that matched no operation, most frequent first.\n *\n * This is the early-warning signal: a consumer calling something the mock does\n * not implement shows up here as a count, before it fails a suite as a 404.\n */\n unmatched: { method: string; path: string; count: number }[]\n faults: number\n totalDurationMs: number\n}\n\nexport type Metrics = {\n record(entry: RequestLog): void\n report(): MetricsReport\n reset(): void\n}\n\nexport const createMetrics = (): Metrics => {\n let requests = 0\n let faults = 0\n let totalDurationMs = 0\n const byOperation = new Map<string, number>()\n const unmatched = new Map<string, number>()\n return {\n record(entry) {\n requests++\n totalDurationMs += entry.durationMs\n if (entry.faultId !== undefined) faults++\n const key = `${entry.operationId ?? \"(unmatched)\"} ${entry.status}`\n byOperation.set(key, (byOperation.get(key) ?? 0) + 1)\n if (entry.unmatched) {\n const route = `${entry.method} ${entry.path}`\n unmatched.set(route, (unmatched.get(route) ?? 0) + 1)\n }\n },\n report: () => ({\n requests,\n byOperation: Object.fromEntries([...byOperation].sort(([a], [b]) => a.localeCompare(b))),\n unmatched: [...unmatched]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .map(([route, count]) => {\n const space = route.indexOf(\" \")\n return { method: route.slice(0, space), path: route.slice(space + 1), count }\n }),\n faults,\n totalDurationMs,\n }),\n reset() {\n requests = 0\n faults = 0\n totalDurationMs = 0\n byOperation.clear()\n unmatched.clear()\n },\n }\n}\n", "/** A stable identifier for a point in a {@link Timeline}. */\nexport type CheckpointId = string\n\n/** An immutable node in a timeline's checkpoint DAG. */\nexport type Checkpoint<T> = Readonly<{\n id: CheckpointId\n branch: string\n parent: CheckpointId | null\n /** Logical time supplied by the timeline's injected clock. */\n at: number\n value: T\n}>\n\nexport type TimelineOptions = {\n /** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */\n now?: () => number\n /** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */\n maxCheckpoints?: number\n /** Customize deterministic checkpoint IDs. */\n id?: (sequence: number) => CheckpointId\n}\n\nexport type CommitOptions = {\n branch?: string\n /** Parent checkpoint. Defaults to the selected branch's current head. */\n parent?: CheckpointId | null\n}\n\nexport type ForkOptions = {\n /** Checkpoint to fork from. Defaults to the main branch's head. */\n from?: CheckpointId\n}\n\nconst BRANCH_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/\n\n/**\n * Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable\n * records, namespace images, or copy-on-write SQL engine snapshots.\n *\n * Values are retained by reference. Engines can therefore use persistent/COW snapshots while\n * simpler services can use immutable values. IDs and GC order are deterministic, and all IO\n * (the logical clock) is injected.\n */\nexport class Timeline<T> {\n readonly maxCheckpoints: number\n private readonly now: () => number\n private readonly makeId: (sequence: number) => CheckpointId\n private readonly nodes = new Map<CheckpointId, Checkpoint<T>>()\n private readonly heads = new Map<string, CheckpointId>()\n /** Unreferenced nodes in the exact order they became collectible. */\n private readonly evictable = new Set<CheckpointId>()\n /** Branch heads plus explicit retainers. Absent means zero. */\n private readonly references = new Map<CheckpointId, number>()\n private readonly explicitPins = new Map<CheckpointId, number>()\n private sequence = 0\n\n constructor(options: TimelineOptions = {}) {\n const max = options.maxCheckpoints ?? 1_000\n if (!Number.isSafeInteger(max) || max < 1)\n throw new RangeError(\"maxCheckpoints must be a positive integer\")\n this.maxCheckpoints = max\n this.now = options.now ?? (() => this.sequence)\n this.makeId = options.id ?? ((sequence) => `cp_${sequence.toString(36).padStart(8, \"0\")}`)\n }\n\n /** Capture a new immutable value and move `branch` to it. */\n commit(value: T, options: CommitOptions = {}): Checkpoint<T> {\n const branch = options.branch ?? \"main\"\n this.assertBranch(branch)\n const parent = options.parent === undefined ? (this.heads.get(branch) ?? null) : options.parent\n if (parent !== null && !this.nodes.has(parent)) throw new RangeError(`no checkpoint ${parent}`)\n const id = this.makeId(++this.sequence)\n if (this.nodes.has(id)) throw new RangeError(`duplicate checkpoint id ${id}`)\n const checkpoint = Object.freeze({ id, branch, parent, at: this.now(), value })\n this.nodes.set(id, checkpoint)\n this.moveHead(branch, id)\n this.collect(this.maxCheckpoints)\n return checkpoint\n }\n\n /** Create a branch pointer without copying its checkpoint value. */\n fork(branch: string, options: ForkOptions = {}): Checkpoint<T> | undefined {\n this.assertBranch(branch)\n if (this.heads.has(branch)) throw new RangeError(`branch already exists: ${branch}`)\n const from = options.from ?? this.heads.get(\"main\")\n if (from === undefined) return undefined\n const checkpoint = this.get(from)\n this.moveHead(branch, checkpoint.id)\n return checkpoint\n }\n\n /** Move a branch pointer to an existing checkpoint. */\n checkout(branch: string, id: CheckpointId): Checkpoint<T> {\n this.assertBranch(branch)\n const checkpoint = this.get(id)\n this.moveHead(branch, checkpoint.id)\n return checkpoint\n }\n\n get(id: CheckpointId): Checkpoint<T> {\n const checkpoint = this.nodes.get(id)\n if (!checkpoint) throw new RangeError(`no checkpoint ${id}`)\n return checkpoint\n }\n\n head(branch = \"main\"): Checkpoint<T> | undefined {\n const id = this.heads.get(branch)\n return id === undefined ? undefined : this.get(id)\n }\n\n hasBranch(branch: string): boolean {\n return this.heads.has(branch)\n }\n\n branches(): Readonly<Record<string, CheckpointId>> {\n return Object.freeze(\n Object.fromEntries([...this.heads].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))),\n )\n }\n\n checkpoints(): readonly Checkpoint<T>[] {\n return [...this.nodes.values()]\n }\n\n /** Number of retained checkpoints without allocating an array. */\n get size(): number {\n return this.nodes.size\n }\n\n /** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */\n retain(id: CheckpointId): Checkpoint<T> {\n const checkpoint = this.get(id)\n this.explicitPins.set(id, (this.explicitPins.get(id) ?? 0) + 1)\n this.addReference(id)\n return checkpoint\n }\n\n /** Release one explicit pin. Branch heads remain pinned until moved or deleted. */\n release(id: CheckpointId): boolean {\n if (!this.nodes.has(id)) return false\n const pins = this.explicitPins.get(id) ?? 0\n if (pins === 0) return false\n if (pins === 1) this.explicitPins.delete(id)\n else this.explicitPins.set(id, pins - 1)\n this.removeReference(id)\n this.collect(this.maxCheckpoints)\n return true\n }\n\n deleteBranch(branch: string): boolean {\n if (branch === \"main\") throw new RangeError(\"cannot delete main branch\")\n const previous = this.heads.get(branch)\n const deleted = this.heads.delete(branch)\n if (previous !== undefined) this.removeReference(previous)\n this.collect(this.maxCheckpoints)\n return deleted\n }\n\n /**\n * Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):\n * commits never scan pinned nodes or the retained history. Parents are metadata rather than a\n * storage dependency, so a retained node remains usable after pruning.\n */\n gc(max = this.maxCheckpoints): CheckpointId[] {\n if (!Number.isSafeInteger(max) || max < 1)\n throw new RangeError(\"max must be a positive integer\")\n const removed: CheckpointId[] = []\n this.collect(max, removed)\n return removed\n }\n\n private collect(max: number, removed?: CheckpointId[]): void {\n while (this.nodes.size > max && this.evictable.size > 0) {\n const id = this.evictable.values().next().value as CheckpointId\n this.evictable.delete(id)\n this.nodes.delete(id)\n removed?.push(id)\n }\n }\n\n private moveHead(branch: string, id: CheckpointId): void {\n const previous = this.heads.get(branch)\n if (previous === id) return\n if (previous !== undefined) this.removeReference(previous)\n this.heads.set(branch, id)\n this.addReference(id)\n }\n\n private addReference(id: CheckpointId): void {\n this.references.set(id, (this.references.get(id) ?? 0) + 1)\n this.evictable.delete(id)\n }\n\n private removeReference(id: CheckpointId): void {\n const next = (this.references.get(id) ?? 0) - 1\n if (next > 0) this.references.set(id, next)\n else {\n this.references.delete(id)\n if (this.nodes.has(id)) this.evictable.add(id)\n }\n }\n\n private assertBranch(branch: string): void {\n if (!BRANCH_PATTERN.test(branch)) throw new RangeError(`branch must match ${BRANCH_PATTERN}`)\n }\n}\n", "import { Database } from \"@crvouga/mockingbird-service-sqlite\"\nimport type { SqliteClient } from \"./client.js\"\n\n/** Construct the default in-memory SQLite client (`@crvouga/mockingbird-service-sqlite`). */\nexport const createDefaultSqlite = (): SqliteClient => new Database()\n\n/** Use the injected client, or fall back to {@link createDefaultSqlite}. */\nexport const resolveSqlite = (sqlite?: SqliteClient): SqliteClient =>\n sqlite ?? createDefaultSqlite()\n", "import type { SqliteClient } from \"./client.js\"\n\n/** One named, ordered schema change applied exactly once per client. */\nexport type Migration = {\n /** Stable id stored in `schema_migrations`. Must be unique across the list. */\n id: string\n sql: string\n}\n\nconst ensureMigrationsTable = (sqlite: SqliteClient) => {\n sqlite.exec(`\n CREATE TABLE IF NOT EXISTS schema_migrations (\n id TEXT PRIMARY KEY NOT NULL,\n applied_at INTEGER NOT NULL\n )\n `)\n}\n\n/**\n * Apply pending migrations in order inside a single transaction.\n *\n * Idempotent: already-applied ids are skipped. Re-running with the same list\n * is a no-op after the first successful boot.\n */\nexport const migrate = (sqlite: SqliteClient, migrations: readonly Migration[]): void => {\n ensureMigrationsTable(sqlite)\n const applied = new Set(\n sqlite\n .prepare(\"SELECT id FROM schema_migrations\")\n .all<{ id: string }>()\n .map((row) => row.id),\n )\n const pending = migrations.filter((migration) => !applied.has(migration.id))\n if (pending.length === 0) return\n\n const insert = sqlite.prepare(\"INSERT INTO schema_migrations (id, applied_at) VALUES (?, ?)\")\n const now = Math.floor(Date.now() / 1000)\n sqlite.transaction(() => {\n for (const migration of pending) {\n sqlite.exec(migration.sql)\n insert.run(migration.id, now)\n }\n })\n}\n\n/** Applied migration ids in application order (by `applied_at`, then `id`). */\nexport const listAppliedMigrations = (sqlite: SqliteClient): string[] => {\n ensureMigrationsTable(sqlite)\n return sqlite\n .prepare(\"SELECT id FROM schema_migrations ORDER BY applied_at ASC, id ASC\")\n .all<{ id: string }>()\n .map((row) => row.id)\n}\n", "import type { SqliteClient } from \"./client.js\"\nimport { type Migration, migrate } from \"./migrate.js\"\n\n/**\n * Core Mockingbird service schema: namespaced JSON records and counters.\n *\n * Applied on every service boot via {@link migrateCore}.\n */\nexport const CORE_MIGRATIONS: readonly Migration[] = [\n {\n id: \"20260322_core_records_sequences\",\n sql: `\n CREATE TABLE IF NOT EXISTS mockingbird_records (\n namespace TEXT NOT NULL,\n collection TEXT NOT NULL,\n id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n value TEXT NOT NULL,\n PRIMARY KEY (namespace, collection, id)\n );\n CREATE INDEX IF NOT EXISTS mockingbird_records_seq\n ON mockingbird_records (namespace, collection, seq);\n CREATE TABLE IF NOT EXISTS mockingbird_sequences (\n namespace TEXT NOT NULL,\n name TEXT NOT NULL,\n kind TEXT NOT NULL,\n value INTEGER NOT NULL,\n PRIMARY KEY (namespace, name, kind)\n );\n `,\n },\n]\n\n/** Apply {@link CORE_MIGRATIONS} (idempotent). */\nexport const migrateCore = (sqlite: SqliteClient): void => {\n migrate(sqlite, CORE_MIGRATIONS)\n}\n\n/** Delete every record and sequence belonging to `namespace`. */\nexport const clearNamespace = (sqlite: SqliteClient, namespace: string): void => {\n sqlite.transaction(() => {\n sqlite.prepare(\"DELETE FROM mockingbird_records WHERE namespace = ?\").run(namespace)\n sqlite.prepare(\"DELETE FROM mockingbird_sequences WHERE namespace = ?\").run(namespace)\n })\n}\n", "/**\n * Cross-browser baseline for every HTML surface this repo serves.\n *\n * `CSS_RESET` is the document sheet. `scopeReset(root)` is the same sheet\n * limited to a widget (`:where` so later component rules still win) and with\n * viewport heights rewritten to the widget's own box.\n *\n * `reset.css` is this string as a stylesheet. The package test fails when the\n * two drift.\n */\nexport const CSS_RESET = `*,\n*::before,\n*::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n}\n\n* {\n scrollbar-width: thin;\n scrollbar-color: color-mix(in srgb, CanvasText 35%, Canvas) Canvas;\n}\n\n*::-webkit-scrollbar {\n width: 12px;\n height: 12px;\n}\n\n*::-webkit-scrollbar-track,\n*::-webkit-scrollbar-corner {\n background: Canvas;\n}\n\n*::-webkit-scrollbar-thumb {\n background: color-mix(in srgb, CanvasText 35%, Canvas);\n border: 3px solid Canvas;\n border-radius: 999px;\n}\n\nhtml {\n hanging-punctuation: first allow-end last;\n -webkit-text-size-adjust: none;\n text-size-adjust: none;\n tab-size: 4;\n font-family:\n ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI Variable\", \"Segoe UI\",\n \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n font-size: 16px;\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n -webkit-tap-highlight-color: transparent;\n scroll-behavior: smooth;\n background: Canvas;\n color: CanvasText;\n}\n\nbody {\n min-height: 100svh;\n line-height: 1.5;\n background: Canvas;\n color: CanvasText;\n}\n\nh1 {\n font-size: 2em;\n}\n\nh2 {\n font-size: 1.5em;\n}\n\nh3 {\n font-size: 1.17em;\n}\n\nh4 {\n font-size: 1em;\n}\n\nh5 {\n font-size: 0.83em;\n}\n\nh6 {\n font-size: 0.67em;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-weight: 700;\n line-height: 1.2;\n text-wrap: balance;\n overflow-wrap: break-word;\n}\n\np,\nli,\nfigcaption,\ndd,\ndt,\nblockquote {\n overflow-wrap: break-word;\n}\n\np,\nli,\nfigcaption,\nblockquote {\n text-wrap: pretty;\n}\n\nul,\nol,\nmenu {\n list-style: none;\n}\n\na {\n color: inherit;\n text-decoration: underline;\n text-decoration-thickness: 1px;\n text-underline-offset: 0.15em;\n text-decoration-skip-ink: auto;\n}\n\nb,\nstrong {\n font-weight: 700;\n}\n\nsmall {\n font-size: 0.875em;\n}\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, \"SF Mono\", SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 1em;\n}\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\nabbr[title] {\n text-decoration: underline dotted;\n text-underline-offset: 0.15em;\n}\n\nmark {\n background: Mark;\n color: MarkText;\n}\n\nhr {\n height: 0;\n border: 0;\n border-top: 1px solid color-mix(in srgb, CanvasText 20%, transparent);\n color: inherit;\n}\n\nimg,\npicture,\nvideo,\ncanvas {\n display: block;\n max-width: 100%;\n}\n\nimg,\nvideo {\n height: auto;\n}\n\nsvg {\n overflow: hidden;\n}\n\niframe {\n border: 0;\n max-width: 100%;\n}\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\nfieldset {\n border: 0;\n min-inline-size: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nbutton,\ninput,\nselect,\ntextarea,\noptgroup {\n font: inherit;\n letter-spacing: inherit;\n color: inherit;\n margin: 0;\n vertical-align: middle;\n}\n\nbutton,\ninput[type=\"button\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"] {\n appearance: none;\n background: none;\n border: 0;\n padding: 0;\n cursor: pointer;\n text-align: center;\n}\n\ninput,\ntextarea,\nselect {\n background-color: Canvas;\n border: 1px solid color-mix(in srgb, CanvasText 28%, transparent);\n border-radius: 0;\n padding: 0.5em 0.65em;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"],\ninput[type=\"range\"],\ninput[type=\"file\"],\ninput[type=\"color\"],\ninput[type=\"button\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"image\"],\ninput[type=\"hidden\"] {\n background: none;\n border: 0;\n padding: 0;\n border-radius: 0;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n accent-color: CanvasText;\n}\n\ninput[type=\"search\"] {\n appearance: none;\n background-color: Canvas;\n border: 1px solid color-mix(in srgb, CanvasText 28%, transparent);\n}\n\ninput[type=\"search\"]::-webkit-search-decoration,\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-results-button,\ninput[type=\"search\"]::-webkit-search-results-decoration {\n -webkit-appearance: none;\n display: none;\n}\n\ninput[type=\"number\"] {\n appearance: textfield;\n background-color: Canvas;\n border: 1px solid color-mix(in srgb, CanvasText 28%, transparent);\n}\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\ntextarea {\n resize: vertical;\n}\n\n::placeholder {\n opacity: 1;\n color: color-mix(in srgb, CanvasText 45%, transparent);\n}\n\n:focus-visible {\n outline: 2px solid CanvasText;\n outline-offset: 2px;\n}\n\n:focus:not(:focus-visible) {\n outline: none;\n}\n\n:disabled,\n[disabled] {\n cursor: default;\n opacity: 0.6;\n}\n\nlabel,\nsummary,\nselect,\n[role=\"button\"] {\n cursor: pointer;\n}\n\nsummary {\n display: list-item;\n}\n\ndetails {\n display: block;\n}\n\ndialog {\n margin: auto;\n padding: 1rem;\n border: 1px solid color-mix(in srgb, CanvasText 20%, transparent);\n background: Canvas;\n color: CanvasText;\n max-width: calc(100vw - 2rem);\n max-height: calc(100svh - 2rem);\n}\n\ndialog:not([open]) {\n display: none;\n}\n\n::backdrop {\n background: color-mix(in srgb, CanvasText 40%, transparent);\n}\n\n[hidden] {\n display: none !important;\n}\n\n::selection {\n background: Highlight;\n color: HighlightText;\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n\n@media (pointer: coarse) {\n input,\n select,\n textarea {\n font-size: max(16px, 1em);\n }\n}`\n\n/** Scope the reset to `root` without raising specificity above a single element. */\nexport function scopeReset(root: string): string {\n return scopeStylesheet(CSS_RESET, root)\n .replaceAll(\"100dvh\", \"100%\")\n .replaceAll(\"100svh\", \"100%\")\n .replaceAll(\"100vh\", \"100%\")\n}\n\nfunction scopeStylesheet(css: string, root: string): string {\n let out = \"\"\n let cursor = 0\n while (cursor < css.length) {\n const brace = css.indexOf(\"{\", cursor)\n if (brace === -1) {\n out += css.slice(cursor)\n break\n }\n const prelude = css.slice(cursor, brace)\n const trimmed = prelude.trimStart()\n if (trimmed.startsWith(\"@media\") || trimmed.startsWith(\"@supports\")) {\n const end = skipBlock(css, brace)\n const body = css.slice(brace + 1, end - 1)\n out += `${css.slice(cursor, brace + 1)}${scopeStylesheet(body, root)}}`\n cursor = end\n continue\n }\n if (trimmed.startsWith(\"@\")) {\n const end = skipBlock(css, brace)\n out += css.slice(cursor, end)\n cursor = end\n continue\n }\n const close = prelude.lastIndexOf(\"}\")\n const head = close === -1 ? \"\" : prelude.slice(0, close + 1)\n const selector = close === -1 ? prelude : prelude.slice(close + 1)\n out += `${head}${scopeSelectorList(selector, root)}{`\n cursor = brace + 1\n }\n return out\n}\n\nfunction scopeSelectorList(selector: string, root: string): string {\n const where = `:where(${root})`\n return splitSelectors(selector)\n .map((part) => scopeOne(part.trim(), where))\n .filter((part) => part !== \"\")\n .join(\",\\n\")\n}\n\nfunction scopeOne(selector: string, where: string): string {\n if (selector === \"html\" || selector === \"body\" || selector === \":root\") return where\n if (selector.startsWith(\"*\")) {\n const rest = selector.slice(1)\n return `${where}${rest},\\n${where} ${selector}`\n }\n if (selector.startsWith(\":\")) return `${where}${selector},\\n${where} ${selector}`\n return `${where} ${selector}`\n}\n\n/** Split a selector list on commas that are not inside parentheses. */\nfunction splitSelectors(selector: string): string[] {\n const parts: string[] = []\n let current = \"\"\n let depth = 0\n for (const char of selector) {\n if (char === \"(\") depth++\n else if (char === \")\") depth = Math.max(0, depth - 1)\n if (char === \",\" && depth === 0) {\n parts.push(current)\n current = \"\"\n continue\n }\n current += char\n }\n parts.push(current)\n return parts\n}\n\nfunction skipBlock(css: string, openBrace: number): number {\n let depth = 0\n for (let index = openBrace; index < css.length; index++) {\n const char = css[index]\n if (char === \"{\") depth++\n else if (char === \"}\") {\n depth--\n if (depth === 0) return index + 1\n }\n }\n return css.length\n}\n", "import type { ClockState } from \"./clock.js\"\nimport type { FaultPresetList } from \"./faults.js\"\nimport type { StateCollectionView, StateField, StateFieldKind, StateView } from \"./state-view.js\"\n\n/**\n * Admin page behavior. `adminClientSource` inlines these functions into the document.\n * They run in the browser, so they cannot close over module bindings \u2014 configuration\n * arrives as the argument to `bootAdmin`.\n */\nexport type AdminBootConfig = {\n standardRoutes: readonly string[]\n adminPrefix: string\n adminKeyHeader: string\n brandsUrl: string\n service: string\n}\n\nexport type AdminBrandEnv = {\n document: Document\n $: (id: string) => HTMLElement | null\n params: URLSearchParams\n location: { href: string; origin: string }\n fetch: typeof fetch\n brandsUrl: string\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\n/** Paint the header chip from a brands catalog. Hostile URLs and markup are dropped. */\nexport function mountAdminBrand(\n doc: Document,\n host: HTMLElement,\n service: string,\n catalog: unknown,\n): void {\n const clip = (value: unknown, max: number): string | null => {\n if (typeof value !== \"string\") return null\n const trimmed = value.trim()\n if (trimmed === \"\") return null\n return trimmed.length > max ? trimmed.slice(0, max) : trimmed\n }\n const httpUrl = (value: unknown): string | null => {\n if (typeof value !== \"string\" || value.length > 2000) return null\n try {\n const url = new URL(value)\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") return null\n return url.href\n } catch {\n return null\n }\n }\n const hexColor = (value: unknown): string | null => {\n if (typeof value !== \"string\") return null\n const raw = value.trim()\n return /^#[0-9a-fA-F]{3,8}$/.test(raw) ? raw : null\n }\n const hostname = (value: string): string => {\n try {\n return new URL(value).hostname.replace(/^www\\./, \"\")\n } catch {\n return value\n }\n }\n host.replaceChildren()\n host.hidden = true\n if (!isRecord(catalog) || !Object.hasOwn(catalog, service)) return\n const row = catalog[service]\n if (!isRecord(row)) return\n const vendor = clip(row.vendor, 80)\n const website = httpUrl(row.website)\n const guide = httpUrl(row.guide)\n const docs = httpUrl(row.docs)\n const logo = httpUrl(row.logo)\n const color = hexColor(row.color)\n const description = clip(row.description, 280)\n if (vendor === null || (website === null && guide === null && docs === null)) return\n const add = <T extends Node>(node: T): T => {\n host.append(node)\n return node\n }\n if (logo !== null) {\n const img = doc.createElement(\"img\")\n img.alt = \"\"\n img.src = logo\n img.width = 16\n img.height = 16\n img.decoding = \"async\"\n img.referrerPolicy = \"no-referrer\"\n if (color !== null) img.style.borderColor = color\n add(img)\n }\n const name = doc.createElement(\"span\")\n name.className = \"vendor-name\"\n name.textContent = vendor\n if (description !== null) name.title = description\n add(name)\n const sep = (): HTMLSpanElement => {\n const node = doc.createElement(\"span\")\n node.className = \"vendor-sep\"\n node.setAttribute(\"aria-hidden\", \"true\")\n node.textContent = \"\u00B7\"\n return node\n }\n const link = (href: string, label: string, title: string): HTMLAnchorElement => {\n const node = doc.createElement(\"a\")\n node.className = \"vendor-link\"\n node.href = href\n node.target = \"_blank\"\n node.rel = \"noopener noreferrer\"\n node.referrerPolicy = \"no-referrer\"\n node.textContent = label\n node.title = title\n return node\n }\n if (website !== null) {\n add(sep())\n add(link(website, hostname(website), `${vendor} website`))\n }\n if (guide !== null) {\n add(sep())\n add(link(guide, \"Docs\", `Docs for ${vendor}`))\n }\n if (docs !== null) {\n add(sep())\n add(link(docs, \"API\", `${vendor} API reference`))\n }\n host.removeAttribute(\"hidden\")\n host.hidden = false\n}\n\n/** Fetch the brands catalog and paint `#vendor`. `?brands=` may name a local copy. */\nexport function startAdminBrand(env: AdminBrandEnv): void {\n const requested = env.params.get(\"brands\")\n let brandsUrl = env.brandsUrl\n if (requested) {\n try {\n const url = new URL(requested, env.location.href)\n const local =\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\" ||\n url.hostname === \"::1\" ||\n url.hostname === \"[::1]\" ||\n url.origin === env.location.origin\n if ((url.protocol === \"https:\" || url.protocol === \"http:\") && local) brandsUrl = url.href\n } catch {\n brandsUrl = env.brandsUrl\n }\n }\n const vendorHost = env.$(\"vendor\")\n const brandRoot = env.document.querySelector(\"[data-mockingbird-admin]\")\n const brandService = brandRoot?.getAttribute(\"data-service\") || \"\"\n if (vendorHost === null) return\n env\n .fetch(brandsUrl, {\n headers: { accept: \"application/json\" },\n signal: AbortSignal.timeout(5000),\n })\n .then(async (response) => {\n if (!response.ok) return null\n const catalog: unknown = await response.json()\n return catalog\n })\n .then((catalog) => {\n mountAdminBrand(env.document, vendorHost, brandService, catalog)\n })\n .catch(() => {})\n}\n\n/**\n * Names from `GET /__admin/faults/presets`.\n * The payload's `presets` field is a list. A record keyed by preset name is rejected\n * here, which is also a type error at the handler that builds a {@link FaultPresetList}.\n */\nexport function faultPresetList(value: unknown): FaultPresetList {\n if (!isRecord(value)) throw new Error(\"Fault presets response was not an object\")\n if (!Object.hasOwn(value, \"presets\") || value.presets === undefined || value.presets === null) {\n return { presets: [] }\n }\n if (!Array.isArray(value.presets)) throw new Error(\"Fault presets response was not a list\")\n return {\n presets: value.presets.flatMap((item) => {\n if (!isRecord(item) || typeof item.name !== \"string\") return []\n return [{ name: item.name }]\n }),\n }\n}\n\n/** Boot the admin document. Inlined into the page; do not close over module bindings. */\nexport function bootAdmin(config: AdminBootConfig): void {\n const fieldKinds = [\"string\", \"number\", \"boolean\", \"null\", \"object\", \"array\", \"unknown\"] as const\n const sources = [\"declared\", \"inferred\", \"mixed\"] as const\n const isFieldKind = (value: unknown): value is StateFieldKind =>\n typeof value === \"string\" && fieldKinds.some((kind) => kind === value)\n const isSource = (value: unknown): value is StateCollectionView[\"source\"] =>\n typeof value === \"string\" && sources.some((source) => source === value)\n const readJson = (text: string): unknown => {\n const value: unknown = JSON.parse(text)\n return value\n }\n const esc = (value: unknown): string =>\n String(value ?? \"\").replace(/[&<>\"']/g, (char) => {\n switch (char) {\n case \"&\":\n return \"&amp;\"\n case \"<\":\n return \"&lt;\"\n case \">\":\n return \"&gt;\"\n case '\"':\n return \"&quot;\"\n default:\n return \"&#39;\"\n }\n })\n const el = <T extends HTMLElement>(id: string, kind: new () => T): T => {\n const node = document.getElementById(id)\n if (!(node instanceof kind)) throw new Error(`admin shell is missing #${id}`)\n return node\n }\n const errorMessage = (data: unknown, fallback: string): string => {\n if (!isRecord(data)) return fallback\n const error = data.error\n if (!isRecord(error) || typeof error.message !== \"string\" || error.message === \"\") {\n return fallback\n }\n return error.message\n }\n const requireList = (value: unknown, label: string): unknown[] => {\n if (value === undefined || value === null) return []\n if (!Array.isArray(value)) throw new Error(`${label} was not a list`)\n return value\n }\n\n const state: {\n namespace: string\n key: string\n view: string\n collection: string\n shape: StateView | null\n route: string | null\n editing: string | null\n } = {\n namespace: \"default\",\n key: sessionStorage.getItem(\"mockingbird-admin-key\") || \"\",\n view: \"overview\",\n collection: \"\",\n shape: null,\n route: null,\n editing: null,\n }\n const standard = new Set(config.standardRoutes)\n const banner = el(\"banner\", HTMLElement)\n const keyInput = el(\"admin-key\", HTMLInputElement)\n keyInput.value = state.key\n const params = new URLSearchParams(location.search)\n const queryKey = params.get(\"key\")\n if (queryKey) {\n state.key = queryKey\n keyInput.value = state.key\n sessionStorage.setItem(\"mockingbird-admin-key\", state.key)\n params.delete(\"key\")\n const next = params.toString()\n history.replaceState(null, \"\", location.pathname + (next ? `?${next}` : \"\"))\n }\n const queryNamespace = params.get(\"namespace\")\n if (queryNamespace) state.namespace = queryNamespace\n\n const showError = (error: unknown): void => {\n banner.textContent = error instanceof Error ? error.message : String(error)\n banner.classList.add(\"show\")\n }\n const clearError = (): void => {\n banner.classList.remove(\"show\")\n }\n\n const api = async (method: string, path: string, body?: unknown): Promise<unknown> => {\n const headers: Record<string, string> = { accept: \"application/json\" }\n if (state.key !== \"\") headers[config.adminKeyHeader] = state.key\n if (state.namespace !== \"\") headers[\"x-mockingbird-namespace\"] = state.namespace\n if (body !== undefined) headers[\"content-type\"] = \"application/json\"\n const init: RequestInit = { method, headers }\n if (body !== undefined) init.body = JSON.stringify(body)\n const response = await fetch(config.adminPrefix + path, init)\n const text = await response.text()\n let data: unknown = null\n if (text !== \"\") {\n try {\n data = readJson(text)\n } catch {\n data = { raw: text }\n }\n }\n if (response.status === 401) {\n keyInput.focus()\n throw new Error(errorMessage(data, \"Admin key required\"))\n }\n if (!response.ok) {\n throw new Error(errorMessage(data, `${response.status} ${method} ${path}`))\n }\n return data\n }\n const originGet = async (path: string): Promise<unknown> => {\n const response = await fetch(path, { headers: { accept: \"application/json\" } })\n if (!response.ok) throw new Error(`${response.status} ${path}`)\n const value: unknown = await response.json()\n return value\n }\n type PanelApi = {\n get: (path: string) => Promise<unknown>\n send: (method: string, path: string, body?: unknown) => Promise<unknown>\n namespace: () => string\n }\n const panelApi: PanelApi = {\n get: (path) => api(\"GET\", path),\n send: (method, path, body) => api(method, path, body),\n namespace: () => state.namespace,\n }\n const isPanelScript = (value: unknown): value is (root: HTMLElement, api: PanelApi) => void =>\n typeof value === \"function\"\n\n const setTheme = (theme: string | null): void => {\n if (theme) document.documentElement.dataset.theme = theme\n else delete document.documentElement.dataset.theme\n }\n const storedTheme = localStorage.getItem(\"mockingbird-admin-theme\")\n if (storedTheme) setTheme(storedTheme)\n el(\"theme\", HTMLButtonElement).addEventListener(\"click\", () => {\n const current = document.documentElement.dataset.theme\n const dark = current ? current === \"dark\" : matchMedia(\"(prefers-color-scheme: dark)\").matches\n const next = dark ? \"light\" : \"dark\"\n localStorage.setItem(\"mockingbird-admin-theme\", next)\n setTheme(next)\n })\n\n const show = (view: string): void => {\n state.view = view\n for (const button of document.querySelectorAll(\"#nav button\")) {\n if (!(button instanceof HTMLButtonElement)) continue\n button.setAttribute(\"aria-current\", button.dataset.view === view ? \"true\" : \"false\")\n }\n for (const section of document.querySelectorAll(\"main .view\")) {\n if (!(section instanceof HTMLElement)) continue\n section.hidden = section.id !== `view-${view}`\n }\n }\n el(\"nav\", HTMLElement).addEventListener(\"click\", (event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n const button = target.closest(\"button[data-view]\")\n if (!(button instanceof HTMLButtonElement)) return\n const view = button.dataset.view\n if (view === undefined) return\n show(view)\n refresh().catch(showError)\n })\n\n const cards = (items: readonly { k: string; v: string }[]): string =>\n `<div class=\"grid\">${items\n .map(\n (item) =>\n `<article class=\"card\"><div class=\"k\">${item.k}</div><div class=\"v\">${item.v}</div></article>`,\n )\n .join(\"\")}</div>`\n const table = <Row extends object>(\n columns: readonly { label: string; cell: (row: Row) => string }[],\n rows: readonly Row[],\n ): string => {\n if (rows.length === 0) return '<p class=\"empty\">Nothing here yet.</p>'\n const head = `<tr>${columns.map((column) => `<th>${column.label}</th>`).join(\"\")}</tr>`\n const body = rows\n .map((row) => {\n const cells = columns\n .map((column) => `<td data-label=\"${column.label}\">${column.cell(row)}</td>`)\n .join(\"\")\n const attrs = \"attrs\" in row && typeof row.attrs === \"string\" ? row.attrs : \"\"\n return `<tr${attrs}>${cells}</tr>`\n })\n .join(\"\")\n return `<table><thead>${head}</thead><tbody>${body}</tbody></table>`\n }\n const preview = (value: unknown): string => {\n const text = JSON.stringify(value) ?? \"null\"\n return esc(text.length > 180 ? `${text.slice(0, 180)}\u2026` : text)\n }\n const when = (epoch: number): string => {\n const date = new Date(epoch)\n return Number.isNaN(date.getTime()) ? String(epoch) : date.toISOString()\n }\n const clockCard = (epoch: number): string => {\n const date = new Date(epoch)\n if (Number.isNaN(date.getTime())) return esc(String(epoch))\n const iso = date.toISOString()\n return `${esc(iso.slice(0, 10))}<span class=\"clock-time\">${esc(iso.slice(11, 19))} UTC</span>`\n }\n const decodeClock = (value: unknown): ClockState => {\n if (\n !isRecord(value) ||\n typeof value.now !== \"number\" ||\n typeof value.offsetMs !== \"number\" ||\n typeof value.frozen !== \"boolean\"\n ) {\n throw new Error(\"Clock response was not a clock\")\n }\n return { now: value.now, offsetMs: value.offsetMs, frozen: value.frozen }\n }\n const decodeField = (value: unknown): StateField | undefined => {\n if (!isRecord(value) || typeof value.name !== \"string\" || !isFieldKind(value.kind)) {\n return undefined\n }\n const field: StateField = {\n name: value.name,\n kind: value.kind,\n optional: value.optional === true,\n }\n if (typeof value.description === \"string\") field.description = value.description\n if (Array.isArray(value.fields)) {\n field.fields = value.fields.flatMap((item) => {\n const child = decodeField(item)\n return child === undefined ? [] : [child]\n })\n }\n return field\n }\n const decodeCollection = (value: unknown): StateCollectionView | undefined => {\n if (!isRecord(value) || typeof value.name !== \"string\") return undefined\n const fields = Array.isArray(value.fields)\n ? value.fields.flatMap((item) => {\n const field = decodeField(item)\n return field === undefined ? [] : [field]\n })\n : []\n const collection: StateCollectionView = {\n name: value.name,\n label: typeof value.label === \"string\" ? value.label : value.name,\n count: typeof value.count === \"number\" ? value.count : 0,\n source: isSource(value.source) ? value.source : \"inferred\",\n fields,\n }\n if (typeof value.description === \"string\") collection.description = value.description\n return collection\n }\n const decodeState = (value: unknown): StateView => {\n if (!isRecord(value) || !Array.isArray(value.collections)) {\n throw new Error(\"State response has no collection list\")\n }\n return {\n namespace: typeof value.namespace === \"string\" ? value.namespace : state.namespace,\n storageNamespace: typeof value.storageNamespace === \"string\" ? value.storageNamespace : \"\",\n collections: value.collections.flatMap((item) => {\n const collection = decodeCollection(item)\n return collection === undefined ? [] : [collection]\n }),\n }\n }\n type RecordRow = { id: string; seq: number; value: unknown; attrs: string }\n const decodeRecords = (value: unknown): RecordRow[] =>\n requireList(isRecord(value) ? value.records : undefined, \"Records\").flatMap((item) => {\n if (!isRecord(item) || typeof item.id !== \"string\") return []\n return [\n {\n id: item.id,\n seq: typeof item.seq === \"number\" ? item.seq : 0,\n value: item.value,\n attrs: ` class=\"clickable\" data-id=\"${esc(item.id)}\"`,\n },\n ]\n })\n type JournalRow = {\n at: string\n method: string\n path: string\n status: string\n durationMs: string\n operationId: string\n }\n const textOf = (value: unknown): string =>\n typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\"\n ? String(value)\n : \"\"\n const decodeJournal = (value: unknown): JournalRow[] =>\n requireList(isRecord(value) ? value.requests : undefined, \"Journal\").flatMap((item) => {\n if (!isRecord(item)) return []\n return [\n {\n at: textOf(item.at),\n method: textOf(item.method),\n path: textOf(item.path),\n status: textOf(item.status),\n durationMs: textOf(item.durationMs),\n operationId: textOf(item.operationId),\n },\n ]\n })\n type FaultRow = {\n id: string\n method: string | undefined\n pathPrefix: string | undefined\n operationId: string | undefined\n status: number | undefined\n effect: string | undefined\n drop: boolean | undefined\n latencyMs: number | undefined\n }\n const decodeFaults = (value: unknown): FaultRow[] =>\n requireList(isRecord(value) ? value.faults : undefined, \"Faults\").flatMap((item) => {\n if (!isRecord(item)) return []\n return [\n {\n id: textOf(item.id),\n method: typeof item.method === \"string\" ? item.method : undefined,\n pathPrefix: typeof item.pathPrefix === \"string\" ? item.pathPrefix : undefined,\n operationId: typeof item.operationId === \"string\" ? item.operationId : undefined,\n status: typeof item.status === \"number\" ? item.status : undefined,\n effect: typeof item.effect === \"string\" ? item.effect : undefined,\n drop: typeof item.drop === \"boolean\" ? item.drop : undefined,\n latencyMs: typeof item.latencyMs === \"number\" ? item.latencyMs : undefined,\n },\n ]\n })\n\n const loadNamespaces = async (): Promise<void> => {\n const data = await api(\"GET\", \"/namespaces\")\n const select = el(\"namespace\", HTMLSelectElement)\n const listed = requireList(isRecord(data) ? data.namespaces : undefined, \"Namespaces\")\n const fallback =\n isRecord(data) && typeof data.default === \"string\" && data.default !== \"\"\n ? data.default\n : \"default\"\n const names = (listed.length > 0 ? listed.map((name) => String(name)) : [fallback]).slice()\n if (!names.includes(state.namespace)) names.unshift(state.namespace)\n select.innerHTML = names\n .map((name) => `<option value=\"${esc(name)}\">${esc(name)}</option>`)\n .join(\"\")\n select.value = state.namespace\n }\n\n const renderOverview = async (): Promise<void> => {\n const [health, shape, clock, journal] = await Promise.all([\n originGet(\"/health\"),\n api(\"GET\", \"/state\"),\n api(\"GET\", \"/clock\"),\n api(\"GET\", \"/requests?limit=8\"),\n ])\n if (!isRecord(health)) throw new Error(\"Health response was not an object\")\n const decoded = decodeState(shape)\n state.shape = decoded\n const time = decodeClock(clock)\n el(\"overview-cards\", HTMLElement).innerHTML = cards([\n {\n k: \"Service\",\n v: esc(\n typeof health.service === \"string\" && health.service !== \"\"\n ? health.service\n : config.service,\n ),\n },\n {\n k: \"Status\",\n v: esc(typeof health.status === \"string\" && health.status !== \"\" ? health.status : \"ok\"),\n },\n { k: \"Namespace\", v: esc(state.namespace) },\n { k: \"Collections\", v: String(decoded.collections.length) },\n {\n k: \"Records\",\n v: String(decoded.collections.reduce((sum, item) => sum + item.count, 0)),\n },\n { k: \"Clock\", v: clockCard(time.now) },\n ])\n el(\"overview-requests\", HTMLElement).innerHTML = table(\n [\n { label: \"Method\", cell: (row: JournalRow) => esc(row.method) },\n { label: \"Path\", cell: (row: JournalRow) => esc(row.path) },\n {\n label: \"Status\",\n cell: (row: JournalRow) =>\n `<span class=\"status-${row.status.charAt(0)}\">${esc(row.status)}</span>`,\n },\n { label: \"Operation\", cell: (row: JournalRow) => esc(row.operationId) },\n ],\n decodeJournal(journal),\n )\n }\n\n const schemaChips = (collection: StateCollectionView): string => {\n if (collection.fields.length === 0) {\n return '<p class=\"empty\">No fields yet. Add a record or declare the collection on the service.</p>'\n }\n return `<div class=\"chips\">${collection.fields\n .map(\n (field) =>\n `<span class=\"chip\">${esc(field.name)} <i>${esc(field.kind)}${field.optional ? \"?\" : \"\"}</i></span>`,\n )\n .join(\"\")}</div>`\n }\n\n const renderState = async (): Promise<void> => {\n const shape = decodeState(await api(\"GET\", \"/state\"))\n state.shape = shape\n const host = el(\"collections\", HTMLElement)\n if (shape.collections.length === 0) {\n host.innerHTML = '<p class=\"empty\">This namespace has no collections yet.</p>'\n el(\"schema\", HTMLElement).innerHTML = \"\"\n el(\"records\", HTMLElement).innerHTML = \"\"\n return\n }\n if (!shape.collections.some((item) => item.name === state.collection)) {\n const first = shape.collections[0]\n if (first === undefined) return\n state.collection = first.name\n }\n host.innerHTML = shape.collections\n .map(\n (item) =>\n `<button type=\"button\" class=\"collection\" data-collection=\"${esc(item.name)}\" aria-current=\"${\n item.name === state.collection ? \"true\" : \"false\"\n }\"><strong>${esc(item.label)}</strong><small>${esc(item.count)} \u00B7 ${esc(item.source)}</small></button>`,\n )\n .join(\"\")\n const selected = shape.collections.find((item) => item.name === state.collection)\n if (selected === undefined) return\n const description = selected.description\n ? `<p class=\"lede\">${esc(selected.description)}</p>`\n : \"\"\n el(\"schema\", HTMLElement).innerHTML =\n `<h3>${esc(selected.label)}</h3>${description}${schemaChips(selected)}`\n const page = await api(\"GET\", `/state/${encodeURIComponent(state.collection)}?limit=50`)\n el(\"records\", HTMLElement).innerHTML = table(\n [\n { label: \"Id\", cell: (row: RecordRow) => `<code>${esc(row.id)}</code>` },\n { label: \"Seq\", cell: (row: RecordRow) => esc(row.seq) },\n { label: \"Value\", cell: (row: RecordRow) => preview(row.value) },\n ],\n decodeRecords(page),\n )\n }\n\n const renderClock = async (): Promise<void> => {\n const clock = decodeClock(await api(\"GET\", \"/clock\"))\n el(\"clock-readout\", HTMLElement).innerHTML =\n `<div class=\"k\">Now</div><div class=\"v\">${esc(when(clock.now))}</div><p>${esc(clock.now)} ms \u00B7 offset ${esc(\n clock.offsetMs,\n )} ms ${\n clock.frozen\n ? \"<span class='badge warn'>frozen</span>\"\n : \"<span class='badge ok'>live</span>\"\n }</p>`\n const freeze = el(\"freeze\", HTMLButtonElement)\n freeze.textContent = clock.frozen ? \"Unfreeze\" : \"Freeze\"\n freeze.dataset.frozen = clock.frozen ? \"1\" : \"0\"\n }\n\n const renderFaults = async (): Promise<void> => {\n const [faults, presets] = await Promise.all([\n api(\"GET\", \"/faults\"),\n api(\"GET\", \"/faults/presets\").catch((): unknown => ({ presets: [] })),\n ])\n const select = el(\"fault-preset\", HTMLSelectElement)\n const current = select.value\n const list = faultPresetList(presets).presets\n select.innerHTML = `<option value=\"\">Custom rule</option>${list\n .map((preset) => `<option value=\"${esc(preset.name)}\">${esc(preset.name)}</option>`)\n .join(\"\")}`\n select.value = current\n el(\"fault-list\", HTMLElement).innerHTML = table(\n [\n { label: \"Id\", cell: (row: FaultRow) => esc(row.id) },\n {\n label: \"Match\",\n cell: (row: FaultRow) =>\n esc(\n [row.method, row.pathPrefix, row.operationId]\n .filter((part): part is string => Boolean(part))\n .join(\" \") || \"all\",\n ),\n },\n {\n label: \"Effect\",\n cell: (row: FaultRow) =>\n esc(row.status ?? row.effect ?? (row.drop ? \"drop\" : row.latencyMs || \"\")),\n },\n ],\n decodeFaults(faults),\n )\n }\n\n const renderJournal = async (): Promise<void> => {\n const journal = await api(\"GET\", \"/requests?limit=100\")\n el(\"journal\", HTMLElement).innerHTML = table(\n [\n { label: \"When\", cell: (row: JournalRow) => esc(row.at) },\n { label: \"Method\", cell: (row: JournalRow) => esc(row.method) },\n { label: \"Path\", cell: (row: JournalRow) => esc(row.path) },\n { label: \"Status\", cell: (row: JournalRow) => esc(row.status) },\n { label: \"ms\", cell: (row: JournalRow) => esc(row.durationMs) },\n ],\n decodeJournal(journal),\n )\n }\n\n const renderRoutes = async (): Promise<void> => {\n const data = await api(\"GET\", \"/\")\n if (!isRecord(data)) throw new Error(\"Route list was not an object\")\n const routes = requireList(data.routes, \"Routes\").map((route) => String(route))\n el(\"route-list\", HTMLElement).innerHTML = routes\n .map((route) => {\n const extra = standard.has(route) ? \"\" : \" <span class='badge'>extension</span>\"\n const parts = route.split(\" \")\n const method = parts[0] ?? \"\"\n const path = parts.slice(1).join(\" \")\n return `<div class=\"route\"><span class=\"method\">${esc(method)}</span><span>${esc(path)}${extra}</span><button class=\"btn\" type=\"button\" data-route=\"${esc(route)}\">Use</button></div>`\n })\n .join(\"\")\n }\n\n const renderers: Record<string, () => Promise<void>> = {\n overview: renderOverview,\n state: renderState,\n clock: renderClock,\n faults: renderFaults,\n journal: renderJournal,\n routes: renderRoutes,\n }\n async function refresh(): Promise<void> {\n clearError()\n const render = renderers[state.view]\n if (render) await render()\n }\n\n el(\"namespace\", HTMLSelectElement).addEventListener(\"change\", () => {\n state.namespace = el(\"namespace\", HTMLSelectElement).value\n refresh().catch(showError)\n })\n keyInput.addEventListener(\"change\", () => {\n state.key = keyInput.value.trim()\n sessionStorage.setItem(\"mockingbird-admin-key\", state.key)\n refresh().catch(showError)\n })\n el(\"refresh\", HTMLButtonElement).addEventListener(\"click\", () => {\n refresh().catch(showError)\n })\n\n el(\"collections\", HTMLElement).addEventListener(\"click\", (event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n const button = target.closest(\"[data-collection]\")\n if (!(button instanceof HTMLElement)) return\n const collection = button.dataset.collection\n if (collection === undefined) return\n state.collection = collection\n renderState().catch(showError)\n })\n el(\"records\", HTMLElement).addEventListener(\"click\", (event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n const row = target.closest(\"[data-id]\")\n if (!(row instanceof HTMLElement)) return\n const id = row.dataset.id\n if (id === undefined) return\n openEditor(id).catch(showError)\n })\n\n const editor = el(\"editor\", HTMLDialogElement)\n const editorId = el(\"editor-id\", HTMLInputElement)\n const editorValue = el(\"editor-value\", HTMLTextAreaElement)\n const editorDelete = el(\"editor-delete\", HTMLButtonElement)\n async function openEditor(id: string | null): Promise<void> {\n state.editing = id\n el(\"editor-title\", HTMLElement).textContent = id ? \"Edit record\" : \"New record\"\n editorId.value = id ?? \"\"\n editorId.readOnly = id !== null\n editorDelete.hidden = id === null\n if (id) {\n const record = await api(\n \"GET\",\n `/state/${encodeURIComponent(state.collection)}/${encodeURIComponent(id)}`,\n )\n if (!isRecord(record)) throw new Error(\"Record response was not an object\")\n editorValue.value = JSON.stringify(record.value, null, 2) ?? \"\"\n } else {\n editorValue.value = \"{\\n \\n}\"\n }\n editor.showModal()\n }\n el(\"new-record\", HTMLButtonElement).addEventListener(\"click\", () => {\n openEditor(null).catch(showError)\n })\n el(\"editor-form\", HTMLFormElement).addEventListener(\"submit\", (event) => {\n const submitter = event.submitter\n if (!(submitter instanceof HTMLButtonElement) || submitter.value !== \"save\") return\n event.preventDefault()\n let value: unknown\n try {\n value = readJson(editorValue.value)\n } catch {\n showError(new Error(\"Value is not JSON\"))\n return\n }\n const id = editorId.value.trim()\n const path = `/state/${encodeURIComponent(state.collection)}`\n const request = state.editing\n ? api(\"PUT\", `${path}/${encodeURIComponent(id)}`, { value })\n : api(\"POST\", path, { id: id || undefined, value })\n request\n .then(() => {\n editor.close()\n return renderState()\n })\n .catch(showError)\n })\n editorDelete.addEventListener(\"click\", () => {\n const id = state.editing\n if (!id) return\n api(\"DELETE\", `/state/${encodeURIComponent(state.collection)}/${encodeURIComponent(id)}`)\n .then(() => {\n editor.close()\n return renderState()\n })\n .catch(showError)\n })\n\n for (const button of document.querySelectorAll(\"[data-advance]\")) {\n if (!(button instanceof HTMLButtonElement)) continue\n button.addEventListener(\"click\", () => {\n const raw = button.dataset.advance\n if (raw === undefined) return\n api(\"POST\", \"/clock\", { advance: Number(raw) })\n .then(() => renderClock())\n .catch(showError)\n })\n }\n el(\"freeze\", HTMLButtonElement).addEventListener(\"click\", () => {\n const frozen = el(\"freeze\", HTMLButtonElement).dataset.frozen === \"1\"\n api(\"POST\", \"/clock\", { freeze: !frozen })\n .then(() => renderClock())\n .catch(showError)\n })\n el(\"clock-reset\", HTMLButtonElement).addEventListener(\"click\", () => {\n api(\"POST\", \"/clock\", { reset: true })\n .then(() => renderClock())\n .catch(showError)\n })\n el(\"clock-set\", HTMLFormElement).addEventListener(\"submit\", (event) => {\n event.preventDefault()\n const raw = el(\"clock-instant\", HTMLInputElement).value.trim()\n const set = /^-?\\d+$/.test(raw) ? Number(raw) : raw\n api(\"POST\", \"/clock\", { set })\n .then(() => renderClock())\n .catch(showError)\n })\n\n el(\"fault-form\", HTMLFormElement).addEventListener(\"submit\", (event) => {\n event.preventDefault()\n const preset = el(\"fault-preset\", HTMLSelectElement).value\n if (preset !== \"\") {\n api(\"POST\", \"/faults\", { preset })\n .then(() => renderFaults())\n .catch(showError)\n return\n }\n const status = Number(el(\"fault-status\", HTMLInputElement).value)\n if (!Number.isFinite(status)) {\n showError(new Error(\"Status must be a number, or choose a preset\"))\n return\n }\n const path = el(\"fault-path\", HTMLInputElement).value\n const method = el(\"fault-method\", HTMLInputElement).value\n api(\"POST\", \"/faults\", {\n status,\n ...(path !== \"\" ? { pathPrefix: path } : {}),\n ...(method !== \"\" ? { method } : {}),\n })\n .then(() => renderFaults())\n .catch(showError)\n })\n el(\"fault-clear\", HTMLButtonElement).addEventListener(\"click\", () => {\n api(\"DELETE\", \"/faults\")\n .then(() => renderFaults())\n .catch(showError)\n })\n el(\"journal-clear\", HTMLButtonElement).addEventListener(\"click\", () => {\n api(\"DELETE\", \"/requests\")\n .then(() => renderJournal())\n .catch(showError)\n })\n\n el(\"route-list\", HTMLElement).addEventListener(\"click\", (event) => {\n const target = event.target\n if (!(target instanceof Element)) return\n const button = target.closest(\"[data-route]\")\n if (!(button instanceof HTMLElement)) return\n const route = button.dataset.route\n if (route === undefined) return\n state.route = route\n el(\"route-title\", HTMLElement).textContent = route\n const method = route.split(\" \")[0] ?? \"\"\n el(\"route-body\", HTMLTextAreaElement).disabled = method === \"GET\" || method === \"DELETE\"\n })\n el(\"route-form\", HTMLFormElement).addEventListener(\"submit\", (event) => {\n event.preventDefault()\n const send = async (): Promise<void> => {\n if (state.route === null) throw new Error(\"Choose a route first\")\n const parts = state.route.split(\" \")\n const method = parts[0]\n const path = parts.slice(1).join(\" \")\n if (method === undefined) throw new Error(\"Choose a route first\")\n const concrete = path.replace(\n /:([A-Za-z0-9_]+)/g,\n (_match, key: string) => prompt(`Value for ${key}`) || \"\",\n )\n let body: unknown\n const routeBody = el(\"route-body\", HTMLTextAreaElement)\n if (method !== \"GET\" && method !== \"DELETE\" && routeBody.value.trim() !== \"\") {\n try {\n body = readJson(routeBody.value)\n } catch {\n throw new Error(\"Body is not JSON\")\n }\n }\n const data = await api(method, concrete, body)\n el(\"route-result\", HTMLElement).textContent = JSON.stringify(data, null, 2)\n }\n send().catch(showError)\n })\n\n type Panel = { id: string; title: string; description: string; html: string; script?: string }\n const decodePanel = (value: unknown): Panel | undefined => {\n if (!isRecord(value) || typeof value.id !== \"string\" || typeof value.title !== \"string\") {\n return undefined\n }\n const panel: Panel = {\n id: value.id,\n title: value.title,\n description: typeof value.description === \"string\" ? value.description : \"\",\n html: typeof value.html === \"string\" ? value.html : \"\",\n }\n if (typeof value.script === \"string\") panel.script = value.script\n return panel\n }\n const mountPanels = (panels: readonly Panel[]): void => {\n const nav = el(\"nav\", HTMLElement)\n const views = el(\"views\", HTMLElement)\n for (const panel of panels) {\n const button = document.createElement(\"button\")\n button.type = \"button\"\n button.dataset.view = panel.id\n button.textContent = panel.title\n nav.append(button)\n const section = document.createElement(\"section\")\n section.className = \"view\"\n section.id = `view-${panel.id}`\n section.hidden = true\n const title = document.createElement(\"h2\")\n title.textContent = panel.title\n const lede = document.createElement(\"p\")\n lede.className = \"lede\"\n lede.textContent = panel.description\n const body = document.createElement(\"div\")\n body.className = \"panel-body\"\n body.id = `panel-${panel.id}`\n body.innerHTML = panel.html\n section.append(title, lede, body)\n views.append(section)\n if (panel.script === undefined) continue\n try {\n const compiled: unknown = new Function(\"root\", \"api\", panel.script)\n if (!isPanelScript(compiled)) throw new Error(\"panel script did not compile\")\n compiled(body, panelApi)\n } catch (error) {\n const note = document.createElement(\"p\")\n note.className = \"banner show\"\n note.textContent = error instanceof Error ? error.message : String(error)\n body.append(note)\n }\n }\n }\n\n startAdminBrand({\n document,\n $: (id) => document.getElementById(id),\n params,\n location: { href: location.href, origin: location.origin },\n fetch,\n brandsUrl: config.brandsUrl,\n })\n loadNamespaces()\n .then(() => api(\"GET\", \"/ui/manifest\"))\n .then((manifest) => {\n const panels = requireList(\n isRecord(manifest) ? manifest.panels : undefined,\n \"Panels\",\n ).flatMap((panel) => {\n const decoded = decodePanel(panel)\n return decoded === undefined ? [] : [decoded]\n })\n mountPanels(panels)\n return refresh()\n })\n .catch(showError)\n}\n\nconst clientPrelude = [isRecord, mountAdminBrand, startAdminBrand, faultPresetList, bootAdmin]\n .map((fn) => fn.toString())\n .join(\"\\n\")\n\n/** The `<script>` embedded in the admin document, typechecked as {@link bootAdmin}. */\nexport const adminClientSource = (config: AdminBootConfig): string => {\n const payload = JSON.stringify(config).replace(/</g, \"\\\\u003c\")\n return `<script>\\n${clientPrelude}\\nbootAdmin(${payload});\\n</script>`\n}\n", "import type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport type { Clock, ClockState } from \"./clock.js\"\nimport type { CredentialRegistry } from \"./credentials.js\"\nimport type { FaultRegistry, FaultRule } from \"./faults.js\"\nimport type { Journal } from \"./journal.js\"\nimport type { Metrics } from \"./metrics.js\"\nimport type { Rng } from \"./rng.js\"\nimport type { NamespaceSnapshot } from \"./snapshot.js\"\nimport type { StateView } from \"./state-view.js\"\n\n/**\n * What every mock can be called with. A service may accept more fields \u2014 accounts,\n * catalogs, webhook endpoints \u2014 and those stay optional so `createRuntime()` and\n * `createRuntime({ seed, adminKey })` work everywhere.\n */\nexport type MockCreateOptions = {\n sqlite?: SqliteClient\n clock?: Clock\n seed?: number | string\n adminKey?: string\n}\n\n/** A checkpoint head the admin client can show. Services may return a richer object. */\nexport type MockCheckpoint = {\n readonly id: string\n readonly branch: string\n readonly parent: string | null\n readonly at: number\n}\n\n/** The instance behind one namespace. Vendor methods sit beside these, not instead of them. */\nexport type MockInstanceSurface = {\n fetch(request: Request): Promise<Response>\n reset(): Promise<void>\n}\n\n/**\n * The interface every mock runtime implements.\n *\n * Assignability is one way: a service may add methods (`tick`, a typed webhook hub,\n * account directories) and narrower property types. Removing or renaming a member\n * fails the typecheck. The HTTP control plane (`/health`, `/__admin/*`) is the same\n * contract on the wire; {@link STANDARD_ADMIN_ROUTES} is that list.\n */\nexport type MockSurface = {\n readonly name: string\n fetch(request: Request): Promise<Response>\n readonly clock: Clock\n readonly faults: FaultRegistry\n readonly metrics: Metrics\n readonly journal: Journal\n readonly rng: Rng\n readonly credentials: CredentialRegistry\n /** Present on every runtime. `undefined` when the service has no outbound webhooks. */\n readonly webhooks: unknown\n applyPreset(name: string, namespace?: string, overrides?: Partial<FaultRule>): FaultRule[]\n instance(namespace?: string): MockInstanceSurface\n namespaces(): string[]\n reset(namespace?: string): Promise<void>\n snapshot(namespace?: string): NamespaceSnapshot\n restore(snapshot: NamespaceSnapshot, namespace?: string): void\n checkpoint(namespace?: string, branch?: string): MockCheckpoint\n branch(name: string, options?: { namespace?: string; at?: string }): MockCheckpoint\n checkout(checkpoint: string, options?: { namespace?: string; branch?: string }): void\n timeline(namespace?: string): {\n head(branch?: string): { readonly id: string } | undefined\n branches(): Readonly<Record<string, string>>\n }\n /** Collections in `namespace`, declared by the service and inferred from stored rows. */\n state(namespace?: string): StateView\n readonly sqlite: SqliteClient\n}\n\n/**\n * Keep a service's own runtime type while proving it is a {@link MockSurface}.\n * Extra members stay. A missing member is a type error at the definition.\n */\nexport const defineMock = <T extends MockSurface>(runtime: T): T => runtime\n\n/** Clock state is part of the surface so admin clients can render it without a cast. */\nexport type MockClockState = ClockState\n\n/**\n * Admin routes every mock answers. A service adds its own keys beside these.\n * A key in this list keeps the shared handler, so the state API and the admin UI\n * stay the same when a service also ships vendor-specific controls.\n */\nexport const STANDARD_ADMIN_ROUTES = [\n \"GET /\",\n \"POST /reset\",\n \"GET /namespaces\",\n \"GET /clock\",\n \"POST /clock\",\n \"GET /faults\",\n \"POST /faults\",\n \"DELETE /faults\",\n \"POST /snapshots\",\n \"POST /snapshots/:id/restore\",\n \"DELETE /snapshots/:id\",\n \"GET /timeline\",\n \"POST /checkpoints\",\n \"POST /branches/:name\",\n \"POST /branches/:name/checkout\",\n \"GET /requests\",\n \"DELETE /requests\",\n \"GET /metrics\",\n \"DELETE /metrics\",\n \"GET /credentials\",\n \"PUT /credentials\",\n \"DELETE /credentials\",\n \"GET /state\",\n \"GET /state/:collection\",\n \"GET /state/:collection/:id\",\n \"POST /state/:collection\",\n \"PUT /state/:collection/:id\",\n \"PATCH /state/:collection/:id\",\n \"DELETE /state/:collection/:id\",\n \"GET /ui\",\n \"GET /ui/\",\n \"GET /ui/manifest\",\n] as const\n\nexport type StandardAdminRoute = (typeof STANDARD_ADMIN_ROUTES)[number]\n\n/** A panel the default admin shell mounts after the shared views. */\nexport type AdminPanel = {\n /** DOM id suffix. Lowercase letters, digits, and hyphens. */\n id: string\n title: string\n description?: string\n /** Markup placed inside the panel body. The service author owns it. */\n html: string\n /**\n * Function body called as `(root, api) => void` once the shell has loaded.\n * `root` is the panel body. `api` is `{ get, send, namespace }` against `/__admin`.\n */\n script?: string\n}\n\n/**\n * How a service customizes the admin UI without leaving the shared shell.\n * `panels` add views. `render` replaces the document and can call `defaultHtml()`\n * to wrap the shared shell instead of discarding it.\n */\nexport type AdminUi = {\n panels?: readonly AdminPanel[]\n render?: (input: { service: string; defaultHtml: () => string }) => string\n}\n\nconst PANEL_ID = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/\n\n/** Reject a panel id the shell cannot mount. Called when the runtime is created. */\nexport const assertAdminUi = (ui: AdminUi | undefined): void => {\n if (!ui?.panels) return\n const seen = new Set<string>()\n for (const panel of ui.panels) {\n if (!PANEL_ID.test(panel.id)) {\n throw new RangeError(`admin panel id must match ${PANEL_ID}: ${JSON.stringify(panel.id)}`)\n }\n if (seen.has(panel.id)) throw new RangeError(`duplicate admin panel id ${panel.id}`)\n seen.add(panel.id)\n if (panel.title.trim() === \"\") throw new RangeError(`admin panel ${panel.id} needs a title`)\n }\n}\n", "import { CSS_RESET } from \"@crvouga/mockingbird-ui\"\nimport { adminClientSource } from \"./admin-client.js\"\nimport type { AdminRoutes } from \"./control.js\"\nimport { ADMIN_KEY_HEADER, ADMIN_PREFIX } from \"./control.js\"\nimport type { AdminUi } from \"./surface.js\"\nimport { STANDARD_ADMIN_ROUTES } from \"./surface.js\"\n\nconst escapeHtml = (value: string): string =>\n value.replace(/[&<>\"']/g, (char) => {\n switch (char) {\n case \"&\":\n return \"&amp;\"\n case \"<\":\n return \"&lt;\"\n case \">\":\n return \"&gt;\"\n case '\"':\n return \"&quot;\"\n default:\n return \"&#39;\"\n }\n })\n\n/**\n * Docs-site record of each service's logo, website, vendor API reference, and guide.\n * This address is the only brand data in the bundle. The payload is fetched when the\n * page opens, so a docs deploy updates every already-published admin.\n * `?brands=` may name a localhost or same-origin copy of that JSON.\n */\nexport const ADMIN_BRANDS_URL = \"https://mockingbird.chrisvouga.dev/brands.json\"\n\n/**\n * The default admin document. It talks only to `/__admin/*`, so every mock can serve it.\n * Bespoke panels arrive later from `GET /ui/manifest`, which stays behind the admin key.\n * The header chip is filled from {@link ADMIN_BRANDS_URL}; nothing about a vendor is inlined.\n */\nexport const renderAdminDocument = (service: string): string => {\n const name = escapeHtml(service)\n const script = adminClientSource({\n standardRoutes: STANDARD_ADMIN_ROUTES,\n adminPrefix: ADMIN_PREFIX,\n adminKeyHeader: ADMIN_KEY_HEADER,\n brandsUrl: ADMIN_BRANDS_URL,\n service,\n })\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<meta name=\"color-scheme\" content=\"light dark\">\n<link rel=\"icon\" href=\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='2' fill='%2327272a'/%3E%3C/svg%3E\">\n<title>${name} admin</title>\n<style>\n ${CSS_RESET}\n :root {\n color-scheme: light;\n --bg: #fafafa;\n --bg-elev: #ffffff;\n --bg-muted: #f4f4f5;\n --bg-inset: #f4f4f5;\n --line: #dedee3;\n --line-strong: #c4c4cc;\n --ink: #18181b;\n --muted: #62626b;\n --faint: #71717a;\n --accent: #27272a;\n --accent-ink: #ffffff;\n --accent-soft: #f4f4f5;\n --ok: #166534;\n --ok-soft: #f0fdf4;\n --warn: #a16207;\n --warn-soft: #fefce8;\n --err: #a82d32;\n --err-soft: #fef2f2;\n --shadow: none;\n --sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n --mono: ui-monospace, \"SF Mono\", SFMono-Regular, Menlo, Consolas, monospace;\n --radius: 10px;\n --header: 56px;\n --nav: 200px;\n }\n :root[data-theme=\"dark\"] {\n color-scheme: dark;\n --bg: #111113;\n --bg-elev: #19191c;\n --bg-muted: #242428;\n --bg-inset: #111113;\n --line: #36363c;\n --line-strong: #52525b;\n --ink: #f4f4f5;\n --muted: #a9a9b2;\n --faint: #71717a;\n --accent: #e4e4e7;\n --accent-ink: #18181b;\n --accent-soft: #242428;\n --ok: #86efac;\n --ok-soft: #14241b;\n --warn: #fde68a;\n --warn-soft: #2a2410;\n --err: #ffaaaa;\n --err-soft: #2c1516;\n --shadow: none;\n }\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n color-scheme: dark;\n --bg: #111113;\n --bg-elev: #19191c;\n --bg-muted: #242428;\n --bg-inset: #111113;\n --line: #36363c;\n --line-strong: #52525b;\n --ink: #f4f4f5;\n --muted: #a9a9b2;\n --faint: #71717a;\n --accent: #e4e4e7;\n --accent-ink: #18181b;\n --accent-soft: #242428;\n --ok: #86efac;\n --ok-soft: #14241b;\n --warn: #fde68a;\n --warn-soft: #2a2410;\n --err: #ffaaaa;\n --err-soft: #2c1516;\n --shadow: none;\n }\n }\n /* Fill the viewport, then grow with the content so the background covers the scroll. */\n html { height: 100%; }\n body {\n margin: 0;\n min-height: 100%;\n display: flex;\n flex-direction: column;\n font-family: var(--sans);\n background: var(--bg);\n color: var(--ink);\n line-height: 1.45;\n padding-left: env(safe-area-inset-left);\n padding-right: env(safe-area-inset-right);\n -webkit-text-size-adjust: 100%;\n }\n :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n .app { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; width: 100%; }\n header.top {\n position: sticky; top: 0; z-index: 5;\n display: flex; align-items: center; gap: 12px;\n min-height: var(--header); padding: 10px 16px;\n background: var(--bg-elev);\n border-bottom: 1px solid var(--line);\n min-width: 0; max-width: 100%;\n }\n .brand {\n display: flex; flex-flow: row wrap; align-items: center; gap: 14px;\n min-width: 0; max-width: 100%; margin-right: auto;\n }\n .brand-id { display: flex; flex-direction: column; min-width: 0; flex: none; }\n .brand-id strong { font-size: 15px; letter-spacing: -0.01em; }\n .brand-id span { color: var(--faint); font-size: 12px; }\n .vendor {\n display: flex; flex-wrap: wrap; align-items: center; gap: 6px;\n min-width: 0; max-width: 100%; font-size: 12px; color: var(--muted);\n }\n .vendor[hidden] { display: none; }\n /* Logos are drawn for a light tile, same as the docs site, so the plate stays white. */\n .vendor img {\n width: 16px; height: 16px; padding: 2px; box-sizing: content-box;\n border-radius: 4px; border: 1px solid var(--line); background: #fff; object-fit: contain;\n }\n .vendor-name { color: var(--ink); font-weight: 600; }\n .vendor-sep { color: var(--faint); }\n .vendor-link { color: inherit; text-decoration: none; }\n .vendor-link:hover { color: var(--ink); text-decoration: underline; }\n .controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }\n label.field { display: flex; flex-direction: column; gap: 2px; font-size: 11px; color: var(--faint); }\n label.field input, label.field select, .controls input[type=\"password\"] {\n background: var(--bg-inset); border: 1px solid var(--line); border-radius: 8px;\n padding: 7px 8px; min-height: 36px;\n }\n .icon-btn, .btn, .btn-primary, .btn-quiet, .btn-danger {\n border-radius: 9px; min-height: 36px; padding: 0 12px; border: 1px solid var(--line);\n background: var(--bg-elev);\n }\n .btn-primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }\n .btn-quiet { background: transparent; }\n .btn-danger { color: var(--err); }\n /* minmax(0, 1fr): a 1fr column will not shrink below its content, so a long\n record or the full nav row would widen the page past the viewport. */\n .layout {\n display: grid; grid-template-columns: var(--nav) minmax(0, 1fr);\n flex: 1 0 auto; min-width: 0;\n }\n nav.side {\n border-right: 1px solid var(--line); padding: 12px;\n display: flex; flex-direction: column; gap: 4px;\n background: var(--bg-elev);\n }\n nav.side button {\n text-align: left; border: 0; background: transparent; border-radius: 9px;\n padding: 9px 10px; min-height: 40px; color: var(--muted);\n }\n nav.side button[aria-current=\"true\"] { background: var(--accent-soft); color: var(--ink); font-weight: 600; }\n main { padding: 20px; max-width: 1100px; width: 100%; min-width: 0; }\n .view h2 { margin: 0 0 4px; font-size: 22px; letter-spacing: -0.02em; }\n .lede { margin: 0 0 16px; color: var(--muted); }\n .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr)); gap: 12px; }\n .card {\n background: var(--bg-elev); border: 1px solid var(--line); border-radius: var(--radius);\n padding: 14px 16px; box-shadow: var(--shadow);\n }\n .card .k { color: var(--faint); font-size: 12px; text-transform: uppercase; letter-spacing: 0.04em; }\n .card .v { display: flex; flex-direction: column; gap: 2px; font-size: 22px; margin-top: 4px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }\n .card .v .clock-time { font-size: 14px; color: var(--muted); }\n .split { display: grid; grid-template-columns: minmax(0, 240px) minmax(0, 1fr); gap: 16px; align-items: start; }\n .collection {\n width: 100%; text-align: left; border: 1px solid transparent; background: transparent;\n border-radius: 10px; padding: 8px 10px; min-height: 44px;\n }\n .collection[aria-current=\"true\"] { background: var(--bg-elev); border-color: var(--line); }\n .collection small { display: block; color: var(--faint); }\n .chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 14px; }\n .chip {\n font-family: var(--mono); font-size: 12px; background: var(--bg-muted);\n border-radius: 999px; padding: 4px 8px;\n }\n .chip i { color: var(--faint); font-style: normal; }\n table { width: 100%; border-collapse: collapse; font-size: 14px; }\n th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }\n th { color: var(--faint); font-weight: 600; font-size: 12px; }\n tr.clickable { cursor: pointer; }\n tr.clickable:hover { background: var(--bg-muted); }\n pre, code, .mono { font-family: var(--mono); overflow-wrap: anywhere; }\n pre {\n margin: 0; white-space: pre-wrap; word-break: break-word;\n background: var(--bg-inset); border-radius: 10px; padding: 12px; font-size: 12px;\n }\n .row-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }\n .banner {\n display: none; margin-bottom: 12px; padding: 10px 12px; border-radius: 10px;\n background: var(--err-soft); color: var(--err);\n }\n .banner.show { display: block; }\n .empty { color: var(--muted); padding: 24px 8px; }\n dialog {\n border: 1px solid var(--line); border-radius: var(--radius); padding: 0; background: var(--bg-elev);\n color: var(--ink); width: min(640px, calc(100% - 24px)); max-width: calc(100vw - 24px); box-shadow: none;\n }\n dialog::backdrop { background: rgb(20 19 17 / 0.45); }\n dialog form, .dialog-body { padding: 16px; display: flex; flex-direction: column; gap: 10px; }\n textarea {\n width: 100%; min-height: 180px; resize: vertical; border-radius: 10px;\n border: 1px solid var(--line); background: var(--bg-inset); padding: 10px;\n font-family: var(--mono); font-size: 12px;\n }\n .dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }\n .badge { font-size: 11px; border-radius: 999px; padding: 2px 7px; background: var(--bg-muted); color: var(--muted); }\n .badge.ok { background: var(--ok-soft); color: var(--ok); }\n .badge.warn { background: var(--warn-soft); color: var(--warn); }\n .status-2 { color: var(--ok); }\n .status-4, .status-5, .status-0 { color: var(--err); }\n .stack { display: flex; flex-direction: column; gap: 12px; }\n .route {\n display: grid; grid-template-columns: 88px 1fr auto; gap: 8px; align-items: center;\n padding: 8px 0; border-bottom: 1px solid var(--line);\n }\n .method { font-family: var(--mono); font-size: 12px; font-weight: 700; }\n @media (max-width: 800px) {\n header.top {\n align-items: stretch; flex-direction: column;\n padding-top: max(10px, env(safe-area-inset-top));\n }\n input, select, textarea { font-size: 16px; }\n .brand, .vendor, .controls { width: 100%; }\n label.field, label.field select, label.field input { flex: 1; min-width: 0; }\n .layout { grid-template-columns: minmax(0, 1fr); }\n nav.side {\n flex-direction: row; align-items: center; overflow-x: auto; min-width: 0;\n border-right: 0; border-bottom: 1px solid var(--line);\n padding: 8px;\n }\n nav.side button { white-space: nowrap; flex: none; }\n .split { grid-template-columns: minmax(0, 1fr); }\n main { padding: 14px; }\n table, thead, tbody, tr, th, td { display: block; }\n thead { display: none; }\n tr {\n border: 1px solid var(--line); border-radius: 12px; margin-bottom: 8px; padding: 6px;\n background: var(--bg-elev); min-width: 0;\n }\n td {\n border: 0; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px;\n min-width: 0; overflow-wrap: anywhere;\n }\n td::before { content: attr(data-label); color: var(--faint); font-size: 12px; flex: none; }\n .route { grid-template-columns: 72px 1fr; }\n .route button { grid-column: 1 / -1; }\n }\n</style>\n</head>\n<body>\n<div class=\"app\" data-service=\"${name}\" data-mockingbird-admin>\n <header class=\"top\">\n <div class=\"brand\">\n <div class=\"brand-id\">\n <strong>${name}</strong>\n <span>Admin</span>\n </div>\n <div class=\"vendor\" id=\"vendor\" hidden></div>\n </div>\n <div class=\"controls\">\n <label class=\"field\">Namespace\n <select id=\"namespace\" aria-label=\"Namespace\"></select>\n </label>\n <label class=\"field\">Admin key\n <input id=\"admin-key\" type=\"password\" autocomplete=\"off\" spellcheck=\"false\" aria-label=\"Admin key\">\n </label>\n <button class=\"icon-btn\" id=\"theme\" type=\"button\" aria-label=\"Toggle color theme\">Theme</button>\n <button class=\"btn\" id=\"refresh\" type=\"button\">Refresh</button>\n </div>\n </header>\n <div class=\"layout\">\n <nav class=\"side\" id=\"nav\" aria-label=\"Admin sections\">\n <button type=\"button\" data-view=\"overview\" aria-current=\"true\">Overview</button>\n <button type=\"button\" data-view=\"state\">State</button>\n <button type=\"button\" data-view=\"clock\">Clock</button>\n <button type=\"button\" data-view=\"faults\">Faults</button>\n <button type=\"button\" data-view=\"journal\">Journal</button>\n <button type=\"button\" data-view=\"routes\">Routes</button>\n </nav>\n <main id=\"views\">\n <p class=\"banner\" id=\"banner\" role=\"alert\"></p>\n <section class=\"view\" id=\"view-overview\">\n <h2>Overview</h2>\n <p class=\"lede\">Health, clock, and the collections this namespace is holding.</p>\n <div class=\"grid\" id=\"overview-cards\"></div>\n <h3>Recent requests</h3>\n <div id=\"overview-requests\"></div>\n </section>\n <section class=\"view\" id=\"view-state\" hidden>\n <h2>State</h2>\n <p class=\"lede\">Every collection in this namespace. Declared fields stay visible before any row exists; stored rows add whatever else they contain.</p>\n <div class=\"split\">\n <div id=\"collections\"></div>\n <div>\n <div id=\"schema\"></div>\n <div class=\"row-actions\">\n <button class=\"btn-primary\" id=\"new-record\" type=\"button\">New record</button>\n </div>\n <div id=\"records\"></div>\n </div>\n </div>\n </section>\n <section class=\"view\" id=\"view-clock\" hidden>\n <h2>Clock</h2>\n <p class=\"lede\">The clock every timestamp in this mock reads.</p>\n <div class=\"card\" id=\"clock-readout\"></div>\n <div class=\"row-actions\">\n <button class=\"btn\" type=\"button\" data-advance=\"60000\">+1m</button>\n <button class=\"btn\" type=\"button\" data-advance=\"900000\">+15m</button>\n <button class=\"btn\" type=\"button\" data-advance=\"3600000\">+1h</button>\n <button class=\"btn\" type=\"button\" data-advance=\"86400000\">+1d</button>\n <button class=\"btn\" type=\"button\" data-advance=\"-3600000\">\u22121h</button>\n <button class=\"btn\" id=\"freeze\" type=\"button\">Freeze</button>\n <button class=\"btn-quiet\" id=\"clock-reset\" type=\"button\">Reset</button>\n </div>\n <form id=\"clock-set\" class=\"row-actions\">\n <label class=\"field\">Set instant\n <input id=\"clock-instant\" type=\"text\" placeholder=\"2026-01-01T00:00:00Z or epoch ms\" size=\"32\">\n </label>\n <button class=\"btn-primary\" type=\"submit\">Set</button>\n </form>\n </section>\n <section class=\"view\" id=\"view-faults\" hidden>\n <h2>Faults</h2>\n <p class=\"lede\">Inject a response, a delay, or a named preset. Rules apply to this namespace.</p>\n <form id=\"fault-form\" class=\"card stack\">\n <label class=\"field\">Preset\n <select id=\"fault-preset\"><option value=\"\">Custom rule</option></select>\n </label>\n <label class=\"field\">Status\n <input id=\"fault-status\" inputmode=\"numeric\" placeholder=\"503\">\n </label>\n <label class=\"field\">Path prefix\n <input id=\"fault-path\" placeholder=\"/v1\">\n </label>\n <label class=\"field\">Method\n <input id=\"fault-method\" placeholder=\"GET\">\n </label>\n <div class=\"dialog-actions\">\n <button class=\"btn-primary\" type=\"submit\">Add fault</button>\n <button class=\"btn-danger\" id=\"fault-clear\" type=\"button\">Clear all</button>\n </div>\n </form>\n <div id=\"fault-list\"></div>\n </section>\n <section class=\"view\" id=\"view-journal\" hidden>\n <h2>Journal</h2>\n <p class=\"lede\">Requests this namespace has seen. Bodies are not stored.</p>\n <div class=\"row-actions\">\n <button class=\"btn-danger\" id=\"journal-clear\" type=\"button\">Clear journal</button>\n </div>\n <div id=\"journal\"></div>\n </section>\n <section class=\"view\" id=\"view-routes\" hidden>\n <h2>Routes</h2>\n <p class=\"lede\">Shared controls, plus any routes this mock adds. Extra routes are how a bespoke workflow shows up beside the default UI.</p>\n <div id=\"route-list\"></div>\n <form id=\"route-form\" class=\"card stack\">\n <strong id=\"route-title\">Select a route</strong>\n <label class=\"field\">JSON body\n <textarea id=\"route-body\" placeholder=\"{ }\"></textarea>\n </label>\n <div class=\"dialog-actions\">\n <button class=\"btn-primary\" type=\"submit\">Send</button>\n </div>\n <pre id=\"route-result\">Response will show here.</pre>\n </form>\n </section>\n </main>\n </div>\n</div>\n<dialog id=\"editor\">\n <form method=\"dialog\" id=\"editor-form\">\n <strong id=\"editor-title\">Record</strong>\n <label class=\"field\">Id\n <input id=\"editor-id\" required>\n </label>\n <label class=\"field\">JSON value\n <textarea id=\"editor-value\"></textarea>\n </label>\n <div class=\"dialog-actions\">\n <button class=\"btn-danger\" id=\"editor-delete\" type=\"button\" value=\"delete\">Delete</button>\n <button class=\"btn-quiet\" type=\"submit\" value=\"cancel\">Cancel</button>\n <button class=\"btn-primary\" type=\"submit\" value=\"save\">Save</button>\n </div>\n </form>\n</dialog>\n${script}\n</body>\n</html>`\n}\n\nconst htmlResponse = (body: string): Response =>\n new Response(body, {\n status: 200,\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": \"no-store\",\n },\n })\n\nconst json = (body: unknown): Response =>\n new Response(JSON.stringify(body), {\n status: 200,\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n })\n\n/** `GET /__admin/ui` plus the manifest a bespoke panel list is read from. */\nexport const adminUiRoutes = (service: string, ui: AdminUi | undefined): AdminRoutes => {\n const shell = () => renderAdminDocument(service)\n const document = () => (ui?.render ? ui.render({ service, defaultHtml: shell }) : shell())\n return {\n \"GET /ui\": () => htmlResponse(document()),\n \"GET /ui/\": () => htmlResponse(document()),\n \"GET /ui/manifest\": () =>\n json({\n service,\n panels: (ui?.panels ?? []).map((panel) => ({\n id: panel.id,\n title: panel.title,\n ...(panel.description !== undefined ? { description: panel.description } : {}),\n html: panel.html,\n ...(panel.script !== undefined ? { script: panel.script } : {}),\n })),\n }),\n }\n}\n", "/**\n * Mockingbird's OpenAPI extensions. They are deliberately generic: nothing here knows about any\n * particular provider. Provider specifics live in each provider's `openapi.yaml`.\n */\n\n/** `x-mockingbird` on an operation. */\nexport type OperationExtension = {\n /** `false` marks an operation the mock explicitly does not implement. Default `true`. */\n supported?: boolean\n /** Human explanation, required when `supported: false` or `parity.enabled: false`. */\n reason?: string\n parity?: {\n /** Whether the differential runner generates this operation. Defaults to `supported`. */\n enabled?: boolean\n /** `false` for operations that must never hit a real account (destructive, billing\u2026). Default `true`. */\n safe?: boolean\n reason?: string\n }\n}\n\nexport type OperationMetadata = {\n supported: boolean\n reason: string | undefined\n parity: { enabled: boolean; safe: boolean; reason: string | undefined }\n}\n\n/** `x-mockingbird-resource`: this string value is the identity of a resource. */\nexport type ResourceIdentityExtension = { type: string; identity: true }\n\n/** `x-mockingbird-resource-ref`: this value must reference an existing resource of `type`. */\nexport type ResourceRefExtension = {\n type: string\n /** A well-formed id that does not exist, used to exercise not-found behaviour. */\n missing?: string\n}\n\nexport const VOLATILE_KINDS = [\"id\", \"timestamp\", \"token\", \"url\", \"account\", \"opaque\"] as const\nexport type VolatileKind = (typeof VOLATILE_KINDS)[number]\n\n/** `x-mockingbird-volatile`: nondeterministic on the real side; compared by shape only. */\nexport type VolatileExtension = { kind: VolatileKind }\n\nexport const SCOPE_VALUES = [\"run-id\", \"walk-start-unix\", \"walk-start-iso\"] as const\nexport type ScopeValue = (typeof SCOPE_VALUES)[number]\n\n/** `x-mockingbird-scope`: always generate this run-scoped value instead of a random one. */\nexport type ScopeExtension = { value: ScopeValue }\n\n/** `x-mockingbird-unsupported`: the mock does not implement this parameter/property. */\nexport type UnsupportedExtension = true | { reason?: string }\n\nexport type SchemaMetadata = {\n resource: ResourceIdentityExtension | undefined\n resourceRef: ResourceRefExtension | undefined\n volatile: VolatileExtension | undefined\n scope: ScopeExtension | undefined\n unsupported: { reason: string | undefined } | undefined\n}\n\nexport const EXTENSION_KEYS = {\n operation: \"x-mockingbird\",\n resource: \"x-mockingbird-resource\",\n resourceRef: \"x-mockingbird-resource-ref\",\n volatile: \"x-mockingbird-volatile\",\n scope: \"x-mockingbird-scope\",\n unsupported: \"x-mockingbird-unsupported\",\n parityHeader: \"x-mockingbird-parity-header\",\n} as const\n", "import type {\n HeaderObject,\n OpenAPIDocument,\n OperationObject,\n ParameterObject,\n ResponseObject,\n SchemaObject,\n} from \"@crvouga/mockingbird-openapi\"\nimport { deref, resolveSchema } from \"@crvouga/mockingbird-openapi\"\nimport {\n EXTENSION_KEYS,\n type OperationExtension,\n type OperationMetadata,\n SCOPE_VALUES,\n type SchemaMetadata,\n VOLATILE_KINDS,\n} from \"./types.js\"\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst extensionOf = (holder: object, key: string): unknown =>\n (holder as Record<string, unknown>)[key]\n\n/** Read `x-mockingbird` from an operation, applying defaults. */\nexport const operationMetadata = (operation: OperationObject): OperationMetadata => {\n const raw = extensionOf(operation, EXTENSION_KEYS.operation)\n const ext: OperationExtension = isRecord(raw) ? (raw as OperationExtension) : {}\n const supported = ext.supported ?? true\n const parity = ext.parity ?? {}\n return {\n supported,\n reason: typeof ext.reason === \"string\" ? ext.reason : undefined,\n parity: {\n enabled: supported && (parity.enabled ?? true),\n safe: parity.safe ?? true,\n reason: typeof parity.reason === \"string\" ? parity.reason : undefined,\n },\n }\n}\n\nconst readResource = (raw: unknown): SchemaMetadata[\"resource\"] => {\n if (!isRecord(raw) || typeof raw.type !== \"string\" || raw.identity !== true) return undefined\n return { type: raw.type, identity: true }\n}\n\nconst readResourceRef = (raw: unknown): SchemaMetadata[\"resourceRef\"] => {\n if (!isRecord(raw) || typeof raw.type !== \"string\") return undefined\n return { type: raw.type, ...(typeof raw.missing === \"string\" ? { missing: raw.missing } : {}) }\n}\n\nconst readVolatile = (raw: unknown): SchemaMetadata[\"volatile\"] => {\n if (!isRecord(raw) || typeof raw.kind !== \"string\") return undefined\n const kind = VOLATILE_KINDS.find((k) => k === raw.kind)\n return kind === undefined ? undefined : { kind }\n}\n\nconst readScope = (raw: unknown): SchemaMetadata[\"scope\"] => {\n if (!isRecord(raw) || typeof raw.value !== \"string\") return undefined\n const value = SCOPE_VALUES.find((v) => v === raw.value)\n return value === undefined ? undefined : { value }\n}\n\nconst readUnsupported = (raw: unknown): SchemaMetadata[\"unsupported\"] => {\n if (raw === true) return { reason: undefined }\n if (isRecord(raw)) return { reason: typeof raw.reason === \"string\" ? raw.reason : undefined }\n return undefined\n}\n\n/**\n * Read Mockingbird's schema-level extensions from a (resolved) schema or parameter.\n * Extensions on a `$ref` wrapper win over the target's, matching {@link resolveSchema}.\n */\nexport const schemaMetadata = (holder: SchemaObject | ParameterObject): SchemaMetadata => ({\n resource: readResource(extensionOf(holder, EXTENSION_KEYS.resource)),\n resourceRef: readResourceRef(extensionOf(holder, EXTENSION_KEYS.resourceRef)),\n volatile: readVolatile(extensionOf(holder, EXTENSION_KEYS.volatile)),\n scope: readScope(extensionOf(holder, EXTENSION_KEYS.scope)),\n unsupported: readUnsupported(extensionOf(holder, EXTENSION_KEYS.unsupported)),\n})\n\n/** Metadata of a parameter: extensions on the parameter itself win over its schema's. */\nexport const parameterMetadata = (\n document: OpenAPIDocument,\n parameter: ParameterObject,\n): SchemaMetadata => {\n const own = schemaMetadata(parameter)\n const fromSchema = parameter.schema\n ? schemaMetadata(resolveSchema(document, parameter.schema))\n : undefined\n return {\n resource: own.resource ?? fromSchema?.resource,\n resourceRef: own.resourceRef ?? fromSchema?.resourceRef,\n volatile: own.volatile ?? fromSchema?.volatile,\n scope: own.scope ?? fromSchema?.scope,\n unsupported: own.unsupported ?? fromSchema?.unsupported,\n }\n}\n\n/** Lower-cased names of response headers flagged with `x-mockingbird-parity-header: true`. */\nexport const parityHeaders = (document: OpenAPIDocument, response: ResponseObject): string[] => {\n const names: string[] = []\n for (const [name, raw] of Object.entries(response.headers ?? {})) {\n const header = deref<HeaderObject>(document, raw)\n if (extensionOf(header, EXTENSION_KEYS.parityHeader) === true) names.push(name.toLowerCase())\n }\n return names.sort()\n}\n", "import type { FetchAPI } from \"@crvouga/mockingbird-core\"\nimport {\n type DecodedBody,\n decodeFormPairs,\n type FormObject,\n readBody,\n} from \"@crvouga/mockingbird-http-codec\"\nimport { listOperations, type OpenAPIDocument, type Operation } from \"@crvouga/mockingbird-openapi\"\nimport { operationMetadata } from \"@crvouga/mockingbird-openapi-metadata\"\nimport {\n clearNamespace,\n migrateCore,\n resolveSqlite,\n type SqliteClient,\n} from \"@crvouga/mockingbird-sqlite\"\nimport { type Context, Hono } from \"hono\"\nimport { annotateResponse } from \"./journal.js\"\nimport { recordedIssues } from \"./validation.js\"\n\n/** A rejection carries the issues `bodyIssues` found, for the runtime's log entry. */\nconst withIssues = (request: Request, response: Response): Response => {\n const issues = response.status >= 400 ? recordedIssues(request) : undefined\n return issues && issues.length > 0 ? annotateResponse(response, { issues }) : response\n}\n\n/** Options every provider constructor accepts. */\nexport type APIOptions = {\n /** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */\n sqlite?: SqliteClient\n /** Clock used for `created`-style fields. Default `Date.now`. */\n now?: () => number\n /**\n * Storage namespace for this instance's records. Instances sharing one SQLite\n * client stay isolated when their namespaces differ. Defaults to the service name.\n */\n namespace?: string\n}\n\nexport type OperationContext = {\n request: Request\n url: URL\n /** Path parameters. */\n params: Record<string, string>\n /** Query string decoded with bracket notation (`created[gte]=1` -> `{ created: { gte: \"1\" } }`). */\n query: FormObject\n body: DecodedBody\n /** Shared SQLite client for this service (already migrated). */\n sqlite: SqliteClient\n /** Service namespace used for records / sequences. */\n namespace: string\n operation: Operation\n /** The vendor contract the service was built from. */\n document: OpenAPIDocument\n now: () => number\n}\n\nexport type OperationHandler = (context: OperationContext) => Promise<Response> | Response\n\nexport type OperationHandlers = Record<string, OperationHandler>\n\n/** Identity helper that keeps handler maps type-checked against a fixed set of operation ids. */\nexport const defineOperations = <Id extends string>(\n handlers: Record<Id, OperationHandler>,\n): Record<Id, OperationHandler> => handlers\n\nexport class OperationRegistryError extends Error {\n constructor(readonly problems: string[]) {\n super(`operation registry is inconsistent:\\n${problems.map((p) => ` - ${p}`).join(\"\\n\")}`)\n this.name = \"OperationRegistryError\"\n }\n}\n\n/**\n * Cross-check handlers against the document: every supported operation needs exactly one\n * handler, no handler may target an unknown or unsupported operation, no duplicate ids.\n */\nexport const verifyOperations = (\n document: OpenAPIDocument,\n handlers: OperationHandlers,\n): string[] => {\n const problems: string[] = []\n const operations = listOperations(document)\n const seen = new Set<string>()\n for (const operation of operations) {\n if (seen.has(operation.operationId))\n problems.push(`duplicate operationId ${operation.operationId}`)\n seen.add(operation.operationId)\n const supported = operationMetadata(operation.operation).supported\n const handler = handlers[operation.operationId]\n if (supported && !handler)\n problems.push(`supported operation ${operation.operationId} has no handler`)\n if (!supported && handler)\n problems.push(`operation ${operation.operationId} is marked unsupported but has a handler`)\n }\n for (const id of Object.keys(handlers)) {\n if (!seen.has(id)) problems.push(`handler ${id} has no OpenAPI operation`)\n }\n return problems\n}\n\nexport type ServiceOptions = {\n document: OpenAPIDocument\n handlers: OperationHandlers\n sqlite: SqliteClient\n /** Namespace isolating this service's records and sequences. */\n namespace: string\n now?: (() => number) | undefined\n /** Response for paths/methods outside the contract. */\n notFound: (request: Request) => Response | Promise<Response>\n /** Response for operations declared but marked `supported: false`. Default: `notFound`. */\n unsupported?: (request: Request, operation: Operation) => Response | Promise<Response>\n /** Convert handler exceptions into a provider-shaped response. */\n onError: (error: unknown, request: Request) => Response | Promise<Response>\n /** Runs before every operation; return a Response to short-circuit (e.g. authentication). */\n before?: (context: OperationContext) => Promise<Response | undefined> | Response | undefined\n}\n\nexport type Service = FetchAPI & {\n app: Hono\n sqlite: SqliteClient\n namespace: string\n /** Delete every record and sequence in the service namespace. */\n reset(): Promise<void>\n}\n\nconst honoPath = (template: string) => template.replace(/\\{([^}]+)\\}/g, \":$1\")\n\n/** Static segments before parameters so `/v1/customers/search` beats `/v1/customers/:id`. */\nconst routeOrder = (a: Operation, b: Operation) => {\n const sa = a.path.split(\"/\")\n const sb = b.path.split(\"/\")\n for (let i = 0; i < Math.max(sa.length, sb.length); i++) {\n const x = sa[i] ?? \"\"\n const y = sb[i] ?? \"\"\n const px = x.startsWith(\"{\")\n const py = y.startsWith(\"{\")\n if (px !== py) return px ? 1 : -1\n if (x !== y) return x < y ? -1 : 1\n }\n return 0\n}\n\nconst queryOf = (url: URL): FormObject => decodeFormPairs(url.searchParams.entries())\n\n/**\n * Resolve optional `sqlite`, run core migrations, and return the ready client.\n * Call this from every provider constructor before building state.\n */\nexport const bootSqlite = (sqlite?: SqliteClient): SqliteClient => {\n const client = resolveSqlite(sqlite)\n migrateCore(client)\n return client\n}\n\n/** Build a Fetch-native service whose routes are exactly the document's operations. */\nexport const createService = (options: ServiceOptions): Service => {\n const problems = verifyOperations(options.document, options.handlers)\n if (problems.length > 0) throw new OperationRegistryError(problems)\n migrateCore(options.sqlite)\n const now = options.now ?? (() => Date.now())\n const app = new Hono()\n app.notFound((c) => options.notFound(c.req.raw))\n app.onError((error, c) => options.onError(error, c.req.raw))\n\n const operations = [...listOperations(options.document)].sort(routeOrder)\n for (const operation of operations) {\n const metadata = operationMetadata(operation.operation)\n const handler = options.handlers[operation.operationId]\n const route = async (c: Context) => {\n const request = c.req.raw\n if (!metadata.supported || !handler) {\n return options.unsupported\n ? options.unsupported(request, operation)\n : options.notFound(request)\n }\n const url = new URL(request.url)\n const context: OperationContext = {\n request,\n url,\n params: c.req.param(),\n query: queryOf(url),\n body: await readBody(request),\n sqlite: options.sqlite,\n namespace: options.namespace,\n operation,\n document: options.document,\n now,\n }\n const short = await options.before?.(context)\n return withIssues(request, short ?? (await handler(context)))\n }\n app.on(operation.method.toUpperCase(), honoPath(operation.path), route)\n }\n\n return {\n app,\n sqlite: options.sqlite,\n namespace: options.namespace,\n fetch: async (request) => app.fetch(request),\n reset: async () => {\n clearNamespace(options.sqlite, options.namespace)\n },\n }\n}\n", "import { mediaTypeOf } from \"@crvouga/mockingbird-http-codec\"\nimport {\n deref,\n resolveSchema,\n type SchemaObject,\n validateValue,\n} from \"@crvouga/mockingbird-openapi\"\nimport type { OperationContext } from \"./service.js\"\n\n/**\n * One problem with a request body, at a dotted path (`patient.address.city`, `items.0.sku`).\n * `kind` is `media_type` when the body is present but its media type is not one the operation\n * accepts (a `415` on most vendors), `syntax` when it could not be decoded, `required` when\n * the operation needs a body and none arrived, and `schema` for a contract violation.\n */\nexport type BodyIssue = {\n path: string\n message: string\n kind?: \"media_type\" | \"syntax\" | \"required\" | \"schema\"\n}\n\n/** What the runtime records about a request the mock rejected: never the body itself. */\nexport type UnsupportedMediaType = {\n /** The request's media type (`text/plain`), or `null` when it sent no `content-type`. */\n mediaType: string | null\n /** The media types the operation's contract accepts, as written (`application/*+json`). */\n accepted: string[]\n}\n\ntype ResolvedRequestBody = {\n required?: boolean\n content?: Record<string, { schema?: SchemaObject }>\n}\n\nconst requestBodyOf = (context: OperationContext): ResolvedRequestBody | undefined => {\n const requestBody = context.operation.operation.requestBody\n return requestBody ? (deref(context.document, requestBody) as ResolvedRequestBody) : undefined\n}\n\n/** `application/*+json` accepts `application/vnd.api+json`; a star on both sides accepts anything. */\nconst mediaTypeMatches = (accepted: string, actual: string): boolean => {\n const pattern = mediaTypeOf(accepted) ?? accepted.toLowerCase()\n if (pattern === actual || pattern === \"*/*\") return true\n const [type, subtype] = pattern.split(\"/\")\n const [actualType, actualSubtype] = actual.split(\"/\")\n if (type !== actualType && type !== \"*\") return false\n if (subtype === undefined || subtype === \"*\") return true\n if (subtype.startsWith(\"*+\")) return actualSubtype?.endsWith(subtype.slice(1)) === true\n return false\n}\n\n/**\n * Which key of the operation's `requestBody.content` the request's `content-type` selects,\n * or undefined when none matches (or the operation declares no body).\n */\nconst acceptedKeyFor = (\n content: Record<string, unknown> | undefined,\n mediaType: string | undefined,\n): string | undefined => {\n if (!content || mediaType === undefined) return undefined\n const keys = Object.keys(content)\n return (\n keys.find((key) => mediaTypeOf(key) === mediaType) ??\n keys.find((key) => mediaTypeMatches(key, mediaType))\n )\n}\n\n/**\n * The reason a request body cannot be read by this operation: its `content-type` is missing\n * or names a media type the contract does not list. Undefined when the operation declares no\n * body, the media type is accepted, or the body is empty (unless `includeEmpty`: ASP.NET\n * Core picks the input formatter from the header before looking at the body, so even an\n * empty body with no `content-type` is 415 there). A JSON body sent as `text/plain` or with\n * no header is the common case: ASP.NET Core, Spring and Rails answer it `415`, and it must\n * never read as \"request body is required\".\n */\nexport const unsupportedMediaType = (\n context: OperationContext,\n options: { includeEmpty?: boolean } = {},\n): UnsupportedMediaType | undefined => {\n if (context.body.kind === \"empty\" && options.includeEmpty !== true) return undefined\n const content = requestBodyOf(context)?.content\n if (!content || Object.keys(content).length === 0) return undefined\n const mediaType = mediaTypeOf(context.request.headers.get(\"content-type\"))\n if (acceptedKeyFor(content, mediaType) !== undefined) return undefined\n return { mediaType: mediaType ?? null, accepted: Object.keys(content) }\n}\n\n/** Issues recorded per request, for the runtime's log entry of a rejected request. */\nconst recorded = new WeakMap<Request, BodyIssue[]>()\n\n/** The issues `bodyIssues` last found for a request, if any. */\nexport const recordedIssues = (request: Request): BodyIssue[] | undefined => recorded.get(request)\n\n/**\n * Validate the decoded body against the operation's `requestBody` schema in the vendor\n * contract, for the media type the request sent (or `contentType` when it sent none that the\n * contract lists). Returns `[]` when valid, or when the operation declares no such body.\n * Services turn the issues into the vendor's own validation error shape; a `media_type`\n * issue is a body the operation cannot read at all (see `unsupportedMediaType`).\n */\nexport const bodyIssues = (\n context: OperationContext,\n contentType = \"application/json\",\n): BodyIssue[] => {\n const issues = findBodyIssues(context, contentType)\n if (issues.length > 0) recorded.set(context.request, issues)\n return issues\n}\n\nconst findBodyIssues = (context: OperationContext, contentType: string): BodyIssue[] => {\n const resolved = requestBodyOf(context)\n if (!resolved) return []\n const unsupported = unsupportedMediaType(context)\n if (unsupported) {\n return [\n {\n path: \"\",\n kind: \"media_type\",\n message:\n unsupported.mediaType === null\n ? \"request body has no content-type\"\n : `request body media type ${unsupported.mediaType} is not supported`,\n },\n ]\n }\n const key =\n acceptedKeyFor(resolved.content, mediaTypeOf(context.request.headers.get(\"content-type\"))) ??\n contentType\n const schema = resolved.content?.[key]?.schema\n if (!schema) return []\n if (context.body.kind === \"invalid\") {\n return [\n {\n path: \"\",\n kind: \"syntax\",\n message: `request body is not valid ${context.body.mediaType}`,\n },\n ]\n }\n const value =\n context.body.kind === \"json\" || context.body.kind === \"form\" || context.body.kind === \"text\"\n ? context.body.value\n : undefined\n if (value === undefined) {\n return resolved.required && context.body.kind === \"empty\"\n ? [{ path: \"\", kind: \"required\", message: \"request body is required\" }]\n : []\n }\n return validateValue(context.document, resolveSchema(context.document, schema), value).map(\n (issue) => ({ path: issue.path.join(\".\"), kind: \"schema\", message: issue.message }),\n )\n}\n\n/** Issues grouped Laravel-style: `{ \"patient.email\": [\"\u2026\"] }`. */\nexport const issuesByField = (issues: BodyIssue[]): Record<string, string[]> => {\n const out: Record<string, string[]> = {}\n for (const issue of issues) {\n const missing = /^missing required property (.+)$/.exec(issue.message)\n const field = missing\n ? [issue.path, missing[1]].filter(Boolean).join(\".\")\n : issue.path || \"body\"\n const message = missing\n ? `The ${field} field is required.`\n : `The ${field} field ${issue.message}.`\n out[field] = [...(out[field] ?? []), message]\n }\n return out\n}\n", "import { Timeline } from \"@crvouga/mockingbird-core\"\nimport type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\n\n/**\n * A point-in-time copy of everything a service namespace holds.\n *\n * All service state lives in the two core tables keyed by namespace, so a snapshot\n * is generic: any service gets per-test rollback without knowing its own schema.\n * Restoring is much cheaper than rebuilding a namespace from a corpus.\n */\nexport type NamespaceSnapshot = {\n namespace: string\n records: { collection: string; id: string; seq: number; value: string }[]\n sequences: { name: string; kind: string; value: number }[]\n}\n\n/**\n * @deprecated Low-level Timeline payload capture retained for API compatibility. Provider code\n * must use the runtime Timeline or `withNamespaceRollback`.\n */\nexport const snapshotNamespace = (sqlite: SqliteClient, namespace: string): NamespaceSnapshot => ({\n namespace,\n records: sqlite\n .prepare(\n \"SELECT collection, id, seq, value FROM mockingbird_records WHERE namespace = ? ORDER BY collection, seq\",\n )\n .all<{ collection: string; id: string; seq: number; value: string }>(namespace),\n sequences: sqlite\n .prepare(\n \"SELECT name, kind, value FROM mockingbird_sequences WHERE namespace = ? ORDER BY name, kind\",\n )\n .all<{ name: string; kind: string; value: number }>(namespace),\n})\n\n/**\n * Replace a namespace's contents with `snapshot`. The namespace is emptied first,\n * so restoring is an assignment, not a merge \u2014 records created since the snapshot\n * are gone afterwards.\n *\n * @deprecated Low-level Timeline payload restore retained for API compatibility. Provider code\n * must use the runtime Timeline or `withNamespaceRollback`.\n */\nexport const restoreNamespace = (\n sqlite: SqliteClient,\n namespace: string,\n snapshot: NamespaceSnapshot,\n): void => {\n sqlite.transaction(() => {\n sqlite.prepare(\"DELETE FROM mockingbird_records WHERE namespace = ?\").run(namespace)\n sqlite.prepare(\"DELETE FROM mockingbird_sequences WHERE namespace = ?\").run(namespace)\n const record = sqlite.prepare(\n \"INSERT INTO mockingbird_records (namespace, collection, id, seq, value) VALUES (?, ?, ?, ?, ?)\",\n )\n for (const row of snapshot.records) {\n record.run(namespace, row.collection, row.id, row.seq, row.value)\n }\n const sequence = sqlite.prepare(\n \"INSERT INTO mockingbird_sequences (namespace, name, kind, value) VALUES (?, ?, ?, ?)\",\n )\n for (const row of snapshot.sequences) {\n sequence.run(namespace, row.name, row.kind, row.value)\n }\n })\n}\n\n/**\n * Execute asynchronous service work atomically using the canonical Timeline rollback primitive.\n * This is the prescribed escape hatch when the SQLite adapter cannot hold a transaction across\n * `await`; service code should not coordinate raw namespace snapshots itself.\n */\nexport const withNamespaceRollback = async <T>(\n sqlite: SqliteClient,\n namespace: string,\n run: () => Promise<T>,\n): Promise<T> => {\n const rollback = new Timeline<NamespaceSnapshot>({ maxCheckpoints: 1 })\n const before = rollback.commit(snapshotNamespace(sqlite, namespace))\n try {\n return await run()\n } catch (error) {\n restoreNamespace(sqlite, namespace, before.value)\n throw error\n }\n}\n", "import type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport { Collection } from \"./collection.js\"\nimport type { AdminRoutes } from \"./control.js\"\n\nexport const STATE_FIELD_KINDS = [\n \"string\",\n \"number\",\n \"boolean\",\n \"null\",\n \"object\",\n \"array\",\n \"unknown\",\n] as const\n\nexport type StateFieldKind = (typeof STATE_FIELD_KINDS)[number]\n\n/** JSON-safe annotations a bespoke admin UI may read. The default UI shows them as text. */\nexport type StateMeta = Readonly<Record<string, string | number | boolean | null>>\n\nexport type StateField = {\n name: string\n kind: StateFieldKind\n optional: boolean\n description?: string\n /** One level of nested object fields. */\n fields?: StateField[]\n meta?: StateMeta\n}\n\n/**\n * What a service knows about a collection before any row exists.\n * Stored rows still appear, including fields this declaration does not mention.\n */\nexport type StateDeclaration = {\n name: string\n label?: string\n description?: string\n fields?: readonly StateField[]\n meta?: StateMeta\n}\n\nexport type StateCollectionView = {\n name: string\n label: string\n description?: string\n count: number\n /** `mixed` when a declaration and stored rows both contribute fields. */\n source: \"declared\" | \"inferred\" | \"mixed\"\n fields: StateField[]\n meta?: StateMeta\n}\n\n/** The shape of one namespace, for an admin UI that has never seen the service before. */\nexport type StateView = {\n namespace: string\n storageNamespace: string\n collections: StateCollectionView[]\n}\n\nexport type StateRecord = {\n id: string\n seq: number\n value: unknown\n}\n\nexport type StatePage = {\n collection: string\n count: number\n records: StateRecord[]\n next: number | null\n}\n\nexport type StateFailure = { ok: false; status: number; message: string }\nexport type StateResult<T> = { ok: true; value: T } | StateFailure\n\nconst COLLECTION_NAME = /^[A-Za-z0-9_.@:-]{1,200}$/\nconst RECORD_ID = /^[^\\s/]{1,256}$/\nconst SAMPLE = 25\nconst WALK_LIMIT = 10_000\nconst SKIP_CTORS = new Set([\"Hono\", \"HonoRequest\", \"Router\"])\n\nconst fail = (status: number, message: string): StateFailure => ({ ok: false, status, message })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst kindOf = (value: unknown): StateFieldKind => {\n if (value === null) return \"null\"\n if (Array.isArray(value)) return \"array\"\n switch (typeof value) {\n case \"string\":\n return \"string\"\n case \"number\":\n return Number.isFinite(value) ? \"number\" : \"unknown\"\n case \"boolean\":\n return \"boolean\"\n case \"object\":\n return \"object\"\n default:\n return \"unknown\"\n }\n}\n\nconst humanize = (name: string): string => {\n const words = name.replace(/[@:_-]+/g, \" \").trim()\n if (words === \"\") return name\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n\n/** Drop values that cannot ride in a JSON admin response. */\nexport const jsonValue = (value: unknown): StateResult<unknown> => {\n if (value === undefined) return fail(400, \"value is required\")\n try {\n return { ok: true, value: JSON.parse(JSON.stringify(value)) as unknown }\n } catch {\n return fail(400, \"value must be JSON\")\n }\n}\n\nconst ctorName = (value: object): string => {\n const ctor = (value as { constructor?: { name?: string } }).constructor\n return typeof ctor?.name === \"string\" ? ctor.name : \"\"\n}\n\nconst isSqlite = (value: object): boolean =>\n \"prepare\" in value &&\n typeof (value as { prepare?: unknown }).prepare === \"function\" &&\n \"transaction\" in value\n\n/** Every Collection hanging off `root`, including ones stored in maps. */\nexport const discoverCollections = (root: unknown): Collection<unknown>[] => {\n const found: Collection<unknown>[] = []\n const seen = new Set<object>()\n const visit = (value: unknown, depth: number): void => {\n if (found.length + seen.size > WALK_LIMIT) return\n if (value === null || typeof value !== \"object\") return\n if (seen.has(value)) return\n seen.add(value)\n if (value instanceof Collection) {\n found.push(value as Collection<unknown>)\n return\n }\n if (value instanceof Map) {\n for (const child of value.values()) visit(child, depth + 1)\n return\n }\n if (value instanceof Set) {\n for (const child of value.values()) visit(child, depth + 1)\n return\n }\n if (depth > 6 || isSqlite(value) || SKIP_CTORS.has(ctorName(value))) return\n if (Array.isArray(value)) {\n const cap = Math.min(value.length, 32)\n for (let i = 0; i < cap; i++) visit(value[i], depth + 1)\n return\n }\n let children: unknown[]\n try {\n children = Object.values(value)\n } catch {\n return\n }\n for (const child of children) visit(child, depth + 1)\n }\n visit(root, 0)\n return found\n}\n\nconst storedNames = (sqlite: SqliteClient, namespace: string): string[] => {\n const records = sqlite\n .prepare(\"SELECT DISTINCT collection AS name FROM mockingbird_records WHERE namespace = ?\")\n .all<{ name: string }>(namespace)\n const sequences = sqlite\n .prepare(\n \"SELECT DISTINCT name FROM mockingbird_sequences WHERE namespace = ? AND kind = 'collection'\",\n )\n .all<{ name: string }>(namespace)\n return [...records, ...sequences].map((row) => row.name)\n}\n\ntype FieldAccum = {\n name: string\n kinds: Set<StateFieldKind>\n present: number\n nested: Map<string, FieldAccum>\n}\n\nconst blankAccum = (name: string): FieldAccum => ({\n name,\n kinds: new Set(),\n present: 0,\n nested: new Map(),\n})\n\nconst absorb = (accum: FieldAccum, value: unknown): void => {\n const kind = kindOf(value)\n accum.kinds.add(kind)\n accum.present++\n if (!isRecord(value)) return\n for (const [key, child] of Object.entries(value)) {\n const nested = accum.nested.get(key) ?? blankAccum(key)\n absorb(nested, child)\n accum.nested.set(key, nested)\n }\n}\n\nconst finishField = (accum: FieldAccum, samples: number): StateField => {\n const kinds = [...accum.kinds]\n const kind = kinds.length === 1 ? (kinds[0] as StateFieldKind) : \"unknown\"\n const field: StateField = {\n name: accum.name,\n kind,\n optional: accum.present < samples || kinds.includes(\"null\"),\n }\n if (accum.nested.size > 0) {\n field.fields = [...accum.nested.values()]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((child) => finishField(child, accum.present))\n }\n return field\n}\n\nconst inferFields = (records: StateRecord[]): StateField[] => {\n if (records.length === 0) return []\n const sample = records.slice(0, SAMPLE)\n const objects = sample.filter((record) => isRecord(record.value))\n if (objects.length === 0) {\n const kinds = new Set(sample.map((record) => kindOf(record.value)))\n const list = [...kinds]\n return [\n {\n name: \"(value)\",\n kind: list.length === 1 ? (list[0] as StateFieldKind) : \"unknown\",\n optional: false,\n },\n ]\n }\n const root = new Map<string, FieldAccum>()\n for (const record of objects) {\n for (const [key, value] of Object.entries(record.value as Record<string, unknown>)) {\n const accum = root.get(key) ?? blankAccum(key)\n absorb(accum, value)\n root.set(key, accum)\n }\n }\n return [...root.values()]\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((accum) => finishField(accum, objects.length))\n}\n\nconst mergeFields = (\n declared: readonly StateField[] | undefined,\n inferred: StateField[],\n): StateField[] => {\n const byName = new Map<string, StateField>()\n for (const field of inferred) byName.set(field.name, field)\n const ordered: StateField[] = []\n const seen = new Set<string>()\n for (const field of declared ?? []) {\n const found = byName.get(field.name)\n seen.add(field.name)\n if (!found) {\n ordered.push({ ...field, optional: field.optional })\n continue\n }\n ordered.push({\n ...found,\n kind: field.kind === \"unknown\" ? found.kind : field.kind,\n optional: field.optional || found.optional,\n ...(field.description !== undefined ? { description: field.description } : {}),\n ...(field.meta !== undefined ? { meta: field.meta } : {}),\n ...(field.fields !== undefined\n ? { fields: mergeFields(field.fields, found.fields ?? []) }\n : {}),\n })\n }\n for (const field of inferred) {\n if (!seen.has(field.name)) ordered.push(field)\n }\n return ordered\n}\n\nconst collectionOf = (sqlite: SqliteClient, namespace: string, name: string) =>\n new Collection<unknown>(sqlite, namespace, name)\n\nconst readRecord = (collection: Collection<unknown>, id: string): StateRecord | undefined => {\n const rows = collection.list({ where: (_value, _seq) => true, order: \"oldest\" })\n const row = rows.find((entry) => entry.id === id)\n return row ? { id: row.id, seq: row.seq, value: row.value } : undefined\n}\n\nexport type StateScope = {\n sqlite: SqliteClient\n /** Public namespace name a request selects. */\n namespace: string\n /** Namespace key used in `mockingbird_records`. */\n storageNamespace: string\n /** Service instance, walked for Collection fields. */\n root: unknown\n declarations?: readonly StateDeclaration[]\n}\n\n/** Describe every collection in a namespace. Empty declared collections are included. */\nexport const inspectState = (scope: StateScope): StateView => {\n const declared = new Map<string, StateDeclaration>()\n for (const declaration of scope.declarations ?? []) {\n if (COLLECTION_NAME.test(declaration.name)) declared.set(declaration.name, declaration)\n }\n const names = new Set<string>(declared.keys())\n for (const name of storedNames(scope.sqlite, scope.storageNamespace)) names.add(name)\n for (const collection of discoverCollections(scope.root)) {\n if (collection.namespace === scope.storageNamespace) names.add(collection.collectionName)\n }\n const collections: StateCollectionView[] = []\n for (const name of names) {\n if (!COLLECTION_NAME.test(name)) continue\n const declaration = declared.get(name)\n const collection = collectionOf(scope.sqlite, scope.storageNamespace, name)\n const records = collection\n .list({ order: \"newest\" })\n .slice(0, SAMPLE)\n .map((row) => ({ id: row.id, seq: row.seq, value: row.value }))\n const inferred = inferFields(records)\n const fields = mergeFields(declaration?.fields, inferred)\n const source =\n declaration && records.length > 0 ? \"mixed\" : declaration ? \"declared\" : \"inferred\"\n collections.push({\n name,\n label: declaration?.label ?? humanize(name),\n ...(declaration?.description !== undefined ? { description: declaration.description } : {}),\n count: collection.count(),\n source,\n fields,\n ...(declaration?.meta !== undefined ? { meta: declaration.meta } : {}),\n })\n }\n const order = new Map<string, number>()\n for (const [index, item] of (scope.declarations ?? []).entries()) order.set(item.name, index)\n collections.sort((a, b) => {\n const left = order.get(a.name)\n const right = order.get(b.name)\n if (left !== undefined && right !== undefined) return left - right\n if (left !== undefined) return -1\n if (right !== undefined) return 1\n return a.name.localeCompare(b.name)\n })\n return {\n namespace: scope.namespace,\n storageNamespace: scope.storageNamespace,\n collections,\n }\n}\n\nexport type StateQuery = {\n limit?: number\n after?: number\n order?: \"newest\" | \"oldest\"\n}\n\nconst pageOf = (\n sqlite: SqliteClient,\n storageNamespace: string,\n name: string,\n query: StateQuery,\n): StateResult<StatePage> => {\n if (!COLLECTION_NAME.test(name)) return fail(400, \"collection name is not allowed\")\n const limit = query.limit ?? 50\n if (!Number.isInteger(limit) || limit < 1 || limit > 200) {\n return fail(400, \"limit must be an integer from 1 to 200\")\n }\n const order = query.order ?? \"newest\"\n if (order !== \"newest\" && order !== \"oldest\")\n return fail(400, 'order must be \"newest\" or \"oldest\"')\n const collection = collectionOf(sqlite, storageNamespace, name)\n const rows = collection.list({ order }).filter((row) => {\n if (query.after === undefined) return true\n return order === \"newest\" ? row.seq < query.after : row.seq > query.after\n })\n const slice = rows.slice(0, limit)\n const last = slice.at(-1)\n return {\n ok: true,\n value: {\n collection: name,\n count: collection.count(),\n records: slice.map((row) => ({ id: row.id, seq: row.seq, value: row.value })),\n next: rows.length > limit && last ? last.seq : null,\n },\n }\n}\n\nexport const readStatePage = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n query: StateQuery = {},\n): StateResult<StatePage> => pageOf(scope.sqlite, scope.storageNamespace, name, query)\n\nexport const readStateRecord = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n id: string,\n): StateResult<StateRecord> => {\n if (!COLLECTION_NAME.test(name)) return fail(400, \"collection name is not allowed\")\n if (!RECORD_ID.test(id)) return fail(400, \"record id is not allowed\")\n const record = readRecord(collectionOf(scope.sqlite, scope.storageNamespace, name), id)\n return record ? { ok: true, value: record } : fail(404, `no record ${id} in ${name}`)\n}\n\nconst requireId = (id: string): StateResult<string> =>\n RECORD_ID.test(id) ? { ok: true, value: id } : fail(400, \"id must be a single path segment\")\n\nexport const createStateRecord = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n input: { id?: string; value: unknown },\n): StateResult<StateRecord> => {\n if (!COLLECTION_NAME.test(name)) return fail(400, \"collection name is not allowed\")\n const parsed = jsonValue(input.value)\n if (!parsed.ok) return parsed\n const collection = collectionOf(scope.sqlite, scope.storageNamespace, name)\n const id = input.id ?? `${name}_${collection.nextSequence()}`\n const checked = requireId(id)\n if (!checked.ok) return checked\n if (collection.has(checked.value)) return fail(409, `record ${checked.value} already exists`)\n const stored = collection.insert(checked.value, parsed.value)\n return { ok: true, value: { id: checked.value, seq: stored.seq, value: stored.value } }\n}\n\nexport const replaceStateRecord = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n id: string,\n value: unknown,\n): StateResult<StateRecord> => {\n if (!COLLECTION_NAME.test(name)) return fail(400, \"collection name is not allowed\")\n const checked = requireId(id)\n if (!checked.ok) return checked\n const parsed = jsonValue(value)\n if (!parsed.ok) return parsed\n const collection = collectionOf(scope.sqlite, scope.storageNamespace, name)\n if (!collection.has(checked.value)) return fail(404, `no record ${checked.value} in ${name}`)\n const stored = collection.update(checked.value, parsed.value)\n if (!stored) return fail(404, `no record ${checked.value} in ${name}`)\n return { ok: true, value: { id: checked.value, seq: stored.seq, value: stored.value } }\n}\n\nexport const patchStateRecord = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n id: string,\n value: unknown,\n): StateResult<StateRecord> => {\n const current = readStateRecord(scope, name, id)\n if (!current.ok) return current\n const parsed = jsonValue(value)\n if (!parsed.ok) return parsed\n const next =\n isRecord(current.value.value) && isRecord(parsed.value)\n ? { ...current.value.value, ...parsed.value }\n : parsed.value\n return replaceStateRecord(scope, name, id, next)\n}\n\nexport const deleteStateRecord = (\n scope: Pick<StateScope, \"sqlite\" | \"storageNamespace\">,\n name: string,\n id: string,\n): StateResult<{ id: string }> => {\n if (!COLLECTION_NAME.test(name)) return fail(400, \"collection name is not allowed\")\n const checked = requireId(id)\n if (!checked.ok) return checked\n const collection = collectionOf(scope.sqlite, scope.storageNamespace, name)\n return collection.delete(checked.value)\n ? { ok: true, value: { id: checked.value } }\n : fail(404, `no record ${checked.value} in ${name}`)\n}\n\nconst json = (status: number, body: unknown): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\" },\n })\n\nconst adminError = (status: number, message: string): Response =>\n json(status, { error: { type: \"mockingbird_admin\", message } })\n\nconst fromResult = <T>(result: StateResult<T>, status: number): Response =>\n result.ok ? json(status, result.value) : adminError(result.status, result.message)\n\nconst integerParam = (value: string | null): number | undefined | \"bad\" => {\n if (value === null) return undefined\n if (!/^-?\\d+$/.test(value)) return \"bad\"\n return Number(value)\n}\n\nexport type StateRoutes = {\n /** Open the public namespace and return the scope the state routes read. */\n open(namespace: string): StateScope\n /** Called after a successful write so Timeline records the new rows. */\n afterWrite?(namespace: string): void\n}\n\n/** The shared `/__admin/state*` routes. Registered after service routes so this key always wins. */\nexport const stateAdminRoutes = (routes: StateRoutes): AdminRoutes => {\n const open = (namespace: string): StateResult<StateScope> => {\n try {\n return { ok: true, value: routes.open(namespace) }\n } catch (error) {\n return fail(400, error instanceof Error ? error.message : String(error))\n }\n }\n const wrote = (namespace: string) => {\n routes.afterWrite?.(namespace)\n }\n return {\n \"GET /state\": ({ namespace }) => {\n const scope = open(namespace)\n return fromResult(scope.ok ? { ok: true, value: inspectState(scope.value) } : scope, 200)\n },\n \"GET /state/:collection\": ({ namespace, params, url }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 200)\n const limit = integerParam(url.searchParams.get(\"limit\"))\n const after = integerParam(url.searchParams.get(\"after\"))\n if (limit === \"bad\") return adminError(400, \"limit: expected an integer\")\n if (after === \"bad\") return adminError(400, \"after: expected a sequence number\")\n const order = url.searchParams.get(\"order\")\n return fromResult(\n readStatePage(scope.value, params.collection ?? \"\", {\n ...(limit !== undefined ? { limit } : {}),\n ...(after !== undefined ? { after } : {}),\n ...(order === \"newest\" || order === \"oldest\" ? { order } : {}),\n }),\n 200,\n )\n },\n \"GET /state/:collection/:id\": ({ namespace, params }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 200)\n return fromResult(readStateRecord(scope.value, params.collection ?? \"\", params.id ?? \"\"), 200)\n },\n \"POST /state/:collection\": ({ namespace, params, body }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 201)\n if (!isRecord(body) || !(\"value\" in body)) {\n return adminError(400, 'expected {\"id?\": \"<id>\", \"value\": <json>}')\n }\n const id = body.id\n if (id !== undefined && typeof id !== \"string\") return adminError(400, \"id must be a string\")\n const created = createStateRecord(scope.value, params.collection ?? \"\", {\n ...(typeof id === \"string\" ? { id } : {}),\n value: body.value,\n })\n if (created.ok) wrote(namespace)\n return fromResult(created, 201)\n },\n \"PUT /state/:collection/:id\": ({ namespace, params, body }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 200)\n if (!isRecord(body) || !(\"value\" in body))\n return adminError(400, 'expected {\"value\": <json>}')\n const replaced = replaceStateRecord(\n scope.value,\n params.collection ?? \"\",\n params.id ?? \"\",\n body.value,\n )\n if (replaced.ok) wrote(namespace)\n return fromResult(replaced, 200)\n },\n \"PATCH /state/:collection/:id\": ({ namespace, params, body }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 200)\n if (!isRecord(body) || !(\"value\" in body))\n return adminError(400, 'expected {\"value\": <json>}')\n const patched = patchStateRecord(\n scope.value,\n params.collection ?? \"\",\n params.id ?? \"\",\n body.value,\n )\n if (patched.ok) wrote(namespace)\n return fromResult(patched, 200)\n },\n \"DELETE /state/:collection/:id\": ({ namespace, params }) => {\n const scope = open(namespace)\n if (!scope.ok) return fromResult(scope, 200)\n const removed = deleteStateRecord(scope.value, params.collection ?? \"\", params.id ?? \"\")\n if (removed.ok) wrote(namespace)\n return fromResult(removed, 200)\n },\n }\n}\n", "/**\n * Set by `scripts/bundle-service.ts` when a service is bundled, and rewritten to the\n * released version when it is published. Undefined when running from source.\n */\ndeclare const __MOCKINGBIRD_PACKAGE_VERSION__: string | undefined\n\n/** Placeholder a bundle carries until `release:publish` writes the real version over it. */\nexport const UNRELEASED_VERSION = \"0.0.0-development\"\n\n/** The published version of the service package this code is bundled into. */\nexport const PACKAGE_VERSION: string =\n typeof __MOCKINGBIRD_PACKAGE_VERSION__ === \"string\"\n ? __MOCKINGBIRD_PACKAGE_VERSION__\n : UNRELEASED_VERSION\n", "/**\n * HMAC and encoding primitives for vendor webhook signatures, over WebCrypto so they run\n * wherever the mocks do (Node, Bun, workers).\n */\n\nexport type HmacAlgorithm = \"SHA-1\" | \"SHA-256\" | \"SHA-512\"\nexport type ByteEncoding = \"hex\" | \"base64\"\n\nconst encoder = new TextEncoder()\n\nexport const toBase64 = (bytes: ArrayBuffer | Uint8Array): string => {\n let binary = \"\"\n for (const byte of bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary)\n}\n\nexport const fromBase64 = (value: string): Uint8Array =>\n Uint8Array.from(atob(value), (char) => char.charCodeAt(0))\n\nexport const toHex = (bytes: ArrayBuffer | Uint8Array): string =>\n [...(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes))]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\")\n\nconst keyBytes = (key: string | Uint8Array): Uint8Array =>\n typeof key === \"string\" ? encoder.encode(key) : key\n\n/** HMAC of `message` under `key` (a UTF-8 string or raw bytes), encoded as hex or base64. */\nexport const hmac = async (\n algorithm: HmacAlgorithm,\n key: string | Uint8Array,\n message: string | Uint8Array,\n encoding: ByteEncoding = \"hex\",\n): Promise<string> => {\n const imported = await crypto.subtle.importKey(\n \"raw\",\n keyBytes(key) as BufferSource,\n { name: \"HMAC\", hash: algorithm },\n false,\n [\"sign\"],\n )\n const signed = await crypto.subtle.sign(\n \"HMAC\",\n imported,\n (typeof message === \"string\" ? encoder.encode(message) : message) as BufferSource,\n )\n return encoding === \"hex\" ? toHex(signed) : toBase64(signed)\n}\n\n/** SHA digest of `input`, hex-encoded. */\nexport const sha = async (\n algorithm: \"SHA-1\" | \"SHA-256\" | \"SHA-512\",\n input: string | Uint8Array,\n): Promise<string> =>\n toHex(\n await crypto.subtle.digest(\n algorithm,\n (typeof input === \"string\" ? encoder.encode(input) : input) as BufferSource,\n ),\n )\n\n/**\n * The raw key of a Svix-style secret: `whsec_<base64>` (Svix, Resend, Junction) or\n * `fwhsec_<base64>` (Flex). A bare base64 secret is accepted too.\n */\nexport const svixSecretBytes = (secret: string): Uint8Array => {\n const raw = secret.replace(/^f?whsec_/, \"\")\n try {\n return fromBase64(raw)\n } catch {\n throw new TypeError(\"webhook secret must be whsec_<base64> (as Svix issues it)\")\n }\n}\n\n/** `v1,<base64 HMAC-SHA256>` over `\"<id>.<timestamp>.<body>\"`, as Svix signs. */\nexport const signSvix = async (\n secret: string,\n messageId: string,\n timestampSeconds: number,\n body: string,\n): Promise<string> =>\n `v1,${await hmac(\"SHA-256\", svixSecretBytes(secret), `${messageId}.${timestampSeconds}.${body}`, \"base64\")}`\n\n/** `t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<body>\")>`, as Stripe (and Persona) sign. */\nexport const signTimestamped = async (\n secret: string,\n timestampSeconds: number,\n body: string,\n): Promise<string> =>\n `t=${timestampSeconds},v1=${await hmac(\"SHA-256\", secret, `${timestampSeconds}.${body}`, \"hex\")}`\n\n/**\n * Twilio's `X-Twilio-Signature`: base64 HMAC-SHA1 of the full URL followed by every form\n * parameter as `key + value`, keys sorted. Sign against the public URL the app is\n * configured with, not the address the request is actually posted to.\n */\nexport const signTwilio = async (\n authToken: string,\n url: string,\n params: Record<string, string>,\n): Promise<string> => {\n const payload =\n url +\n Object.keys(params)\n .sort()\n .map((key) => `${key}${params[key]}`)\n .join(\"\")\n return hmac(\"SHA-1\", authToken, payload, \"base64\")\n}\n\n/** Constant-time string comparison, so a verifier in a test double does not leak timing. */\nexport const timingSafeEqual = (a: string, b: string): boolean => {\n if (a.length !== b.length) return false\n let diff = 0\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i)\n return diff === 0\n}\n", "import type { AdminRoutes } from \"./control.js\"\nimport { signSvix, signTimestamped, signTwilio } from \"./signing.js\"\n\n/**\n * Outbound webhooks, shared by every service that has them.\n *\n * A service publishes a message (the exact bytes the vendor would send); the hub fans it out\n * to every matching endpoint, signs each delivery with the vendor's scheme, retries on the\n * vendor's schedule, and keeps a record a suite can read, replay or flush through\n * `/__admin/webhooks*`. Signature timestamps use the wall clock unless a service injects\n * `now`: receivers check them against their own time, and an advanced mock clock would\n * otherwise fail every delivery. A service whose caller injected the clock (Stripe) passes it,\n * so a virtual-time receiver verifies at the mock's time.\n */\n\n/** What a signer sees for one delivery attempt. */\nexport type SignInput = {\n messageId: string\n /** Exact bytes about to be sent. */\n body: string\n /** Unix seconds of this attempt: wall clock, or the hub's injected `now`. */\n timestampSeconds: number\n /** Where the delivery is posted. */\n url: string\n /** The endpoint's secret, if it has one. */\n secret: string | undefined\n /** The endpoint's `signUrl` (the public URL the receiver verifies against), else `url`. */\n signUrl: string\n /** Form parameters, when the body is form-encoded (Twilio signs these, not the body). */\n form: Record<string, string> | undefined\n /** Stable event type and metadata captured with the message; avoids signer side-channel state. */\n type: string\n tags: Readonly<Record<string, string>>\n}\n\n/** Headers to add to one delivery. */\nexport type WebhookSigner = (\n input: SignInput,\n) => Record<string, string> | Promise<Record<string, string>>\n\n/** Named signers for the vendor schemes the catalog needs. */\nexport const signers = {\n /** No signature. */\n none: (): WebhookSigner => () => ({}),\n /** Svix (`svix-id`, `svix-timestamp`, `svix-signature: v1,<b64>`): Junction, Flex, Resend. */\n svix:\n (options: { prefix?: \"svix\" | \"webhook\" } = {}): WebhookSigner =>\n async ({ messageId, body, timestampSeconds, secret }) => {\n if (!secret) return {}\n const prefix = options.prefix ?? \"svix\"\n return {\n [`${prefix}-id`]: messageId,\n [`${prefix}-timestamp`]: String(timestampSeconds),\n [`${prefix}-signature`]: await signSvix(secret, messageId, timestampSeconds, body),\n }\n },\n /** `<header>: t=<unix>,v1=<hex HMAC-SHA256(secret, \"t.body\")>`: Stripe, Persona, Fullscript. */\n timestamped:\n (header = \"Stripe-Signature\"): WebhookSigner =>\n async ({ body, timestampSeconds, secret }) =>\n secret ? { [header]: await signTimestamped(secret, timestampSeconds, body) } : {},\n /** `X-Twilio-Signature` over the public URL plus the sorted form parameters. */\n twilio:\n (): WebhookSigner =>\n async ({ signUrl, form, secret }) =>\n secret ? { \"X-Twilio-Signature\": await signTwilio(secret, signUrl, form ?? {}) } : {},\n /** The secret itself in a header (optionally templated): RxVortex, Pharmetika, AHA `Token <s>`. */\n header:\n (header: string, format: (secret: string) => string = (s) => s): WebhookSigner =>\n ({ secret }) =>\n secret ? { [header]: format(secret) } : {},\n /** Anything else: the service computes the headers itself. */\n custom: (sign: WebhookSigner): WebhookSigner => sign,\n}\n\nexport type WebhookEndpoint = {\n /** Stable id; generated when omitted. */\n id?: string\n url: string\n secret?: string\n /** Event types to deliver; omit or include `\"*\"` for every type. */\n events?: string[]\n /** Deliver only messages whose tags include all of these (e.g. `{ account: \"mso\" }`). */\n tags?: Record<string, string>\n /** The public URL the receiver verifies signatures against (Twilio), when it differs. */\n signUrl?: string\n headers?: Record<string, string>\n}\n\nexport type WebhookMessage = {\n id: string\n namespace: string\n type: string\n body: string\n contentType: string\n tags: Record<string, string>\n headers?: Record<string, string>\n /** Wall-clock ISO-8601 time of publication. */\n publishedAt: string\n}\n\nexport type WebhookAttempt = {\n attempt: number\n at: string\n status: number | null\n error: string | null\n durationMs: number\n /** Exact receiver response body, when one was returned. */\n responseBody?: string | null\n}\n\nexport type WebhookDelivery = {\n id: string\n messageId: string\n namespace: string\n type: string\n endpointId: string\n url: string\n state: \"pending\" | \"delivered\" | \"failed\" | \"dropped\"\n attempts: WebhookAttempt[]\n}\n\n/** A delivery-level fault: what happens to the next `count` messages in a namespace. */\nexport type WebhookFault = {\n mode: \"duplicate\" | \"reorder\" | \"drop\"\n /** Messages affected; default 1. */\n count?: number\n}\n\nexport type PublishInput = {\n namespace: string\n type: string\n /** Exact body; objects are JSON-encoded. */\n body: string | Record<string, unknown> | unknown[]\n /** Default `application/json`, or form-encoded when `form` is given. */\n contentType?: string\n /** Form parameters, when the vendor posts `application/x-www-form-urlencoded`. */\n form?: Record<string, string>\n tags?: Record<string, string>\n /** Message-specific delivery headers, captured as part of durable message state. */\n headers?: Record<string, string>\n /** Message id; generated when omitted. */\n id?: string\n}\n\nexport type WebhookHubOptions = {\n signer: WebhookSigner\n /**\n * Delay before each attempt, in ms; the first entry delays the first attempt. Default:\n * immediately, then 5 s, 5 min, 30 min, 2 h.\n */\n retryDelaysMs?: readonly number[]\n /** Abort an attempt after this long. Default 15 s. */\n timeoutMs?: number\n /** Which receiver statuses count as delivered. Default 2xx. */\n delivered?: (status: number) => boolean\n /** Endpoints every namespace delivers to (from `--webhook-url`). */\n endpoints?: WebhookEndpoint[]\n fetch?: (request: Request) => Promise<Response>\n /** Called in-process for every published message, delivered or not. */\n onMessage?: (message: WebhookMessage) => void\n /** Messages kept per namespace for `GET /__admin/webhooks/events`. Default 500. */\n keep?: number\n /** Injectable clock (default wall clock) for signatures and attempt records. */\n now?: () => number\n /** Injectable deterministic identifier source. Receives `\"msg_\"` or `\"dlv_\"`. */\n id?: (prefix: string) => string\n /** Injectable scheduler used by timeouts and retries. */\n schedule?: (callback: () => void, delayMs: number) => unknown\n cancel?: (handle: unknown) => void\n}\n\nexport type WebhookHub = {\n publish(input: PublishInput): WebhookMessage\n /** Replace a namespace's own endpoints (`PUT /__admin/webhook-endpoints`). */\n setEndpoints(namespace: string, endpoints: WebhookEndpoint[]): WebhookEndpoint[]\n /** The endpoints a namespace delivers to: its own, plus the global ones. */\n endpoints(namespace: string): WebhookEndpoint[]\n messages(namespace?: string): WebhookMessage[]\n deliveries(namespace?: string): WebhookDelivery[]\n replay(deliveryId: string): Promise<WebhookDelivery | undefined>\n /** Run every pending retry (and release held reordered messages) now, and every retry those attempts schedule, until nothing is pending. */\n flush(): Promise<void>\n /** Resolve once nothing is in flight. */\n idle(): Promise<void>\n fault(namespace: string, fault: WebhookFault): void\n clear(namespace?: string): void\n}\n\nconst DEFAULT_DELAYS = [0, 5_000, 300_000, 1_800_000, 7_200_000] as const\n\nconst unref = (timer: unknown) => {\n ;(timer as { unref?: () => void }).unref?.()\n}\n\nconst randomId = (prefix: string) =>\n `${prefix}${crypto.randomUUID().replace(/-/g, \"\").slice(0, 24)}`\n\nconst matchesEndpoint = (endpoint: WebhookEndpoint, message: WebhookMessage): boolean => {\n const events = endpoint.events ?? [\"*\"]\n if (!events.includes(\"*\") && !events.includes(message.type)) return false\n for (const [key, value] of Object.entries(endpoint.tags ?? {})) {\n if (message.tags[key] !== value) return false\n }\n return true\n}\n\nexport const createWebhookHub = (options: WebhookHubOptions): WebhookHub => {\n const delays = options.retryDelaysMs ?? DEFAULT_DELAYS\n const timeoutMs = options.timeoutMs ?? 15_000\n const delivered = options.delivered ?? ((status: number) => status >= 200 && status < 300)\n const send = options.fetch ?? ((request: Request) => fetch(request))\n const keep = options.keep ?? 500\n const now = options.now ?? Date.now\n const id = options.id ?? randomId\n const scheduleTimer =\n options.schedule ?? ((callback: () => void, delayMs: number) => setTimeout(callback, delayMs))\n const cancel =\n options.cancel ?? ((handle: unknown) => clearTimeout(handle as ReturnType<typeof setTimeout>))\n const global = (options.endpoints ?? []).map((e, i) => ({ ...e, id: e.id ?? `we_global_${i}` }))\n const own = new Map<string, WebhookEndpoint[]>()\n const messages: WebhookMessage[] = []\n const deliveries = new Map<string, WebhookDelivery>()\n const pending = new Map<string, unknown | undefined>()\n const payloads = new Map<string, { message: WebhookMessage; endpoint: WebhookEndpoint }>()\n const faults = new Map<string, { mode: WebhookFault[\"mode\"]; remaining: number }[]>()\n const held = new Map<string, WebhookMessage[]>()\n const inFlight = new Set<Promise<void>>()\n // Immediate (delay 0) attempts chain onto this so two deliveries scheduled in the same tick\n // (e.g. a reorder fault's swap) hit the receiver in schedule order, not fetch-race order.\n let immediate: Promise<unknown> = Promise.resolve()\n\n const track = (work: Promise<void>) => {\n inFlight.add(work)\n void work.finally(() => inFlight.delete(work))\n }\n\n const attempt = async (delivery: WebhookDelivery): Promise<boolean> => {\n const entry = payloads.get(delivery.id)\n if (!entry) return false\n const { message, endpoint } = entry\n const timestampSeconds = Math.floor(now() / 1000)\n const started = now()\n const record: WebhookAttempt = {\n attempt: delivery.attempts.length + 1,\n at: new Date(started).toISOString(),\n status: null,\n error: null,\n durationMs: 0,\n responseBody: null,\n }\n const controller = new AbortController()\n const timer = scheduleTimer(() => controller.abort(), timeoutMs)\n try {\n const signed = await options.signer({\n messageId: message.id,\n body: message.body,\n timestampSeconds,\n url: endpoint.url,\n secret: endpoint.secret,\n signUrl: endpoint.signUrl ?? endpoint.url,\n form: message.contentType.startsWith(\"application/x-www-form-urlencoded\")\n ? Object.fromEntries(new URLSearchParams(message.body))\n : undefined,\n type: message.type,\n tags: message.tags,\n })\n const response = await send(\n new Request(endpoint.url, {\n method: \"POST\",\n headers: {\n \"content-type\": message.contentType,\n ...endpoint.headers,\n ...message.headers,\n ...signed,\n },\n body: message.body,\n signal: controller.signal,\n }),\n )\n record.status = response.status\n record.responseBody = await response.text()\n } catch (error) {\n record.error = controller.signal.aborted\n ? `timed out after ${timeoutMs}ms`\n : error instanceof Error\n ? error.message\n : String(error)\n } finally {\n cancel(timer)\n record.durationMs = now() - started\n delivery.attempts.push(record)\n }\n return record.status !== null && delivered(record.status)\n }\n\n const schedule = (delivery: WebhookDelivery) => {\n const index = delivery.attempts.length\n if (index >= delays.length) {\n delivery.state = \"failed\"\n pending.delete(delivery.id)\n return\n }\n const settle = async () => {\n // `clear` can drop a delivery queued behind an earlier immediate attempt. Its attempt would\n // record nothing and reschedule at the same index forever, starving the event loop.\n if (!payloads.has(delivery.id)) return\n await attempt(delivery).then((ok) => {\n if (ok) delivery.state = \"delivered\"\n else schedule(delivery)\n })\n }\n const delay = delays[index] ?? 0\n if (delay <= 0) {\n const task = immediate.then(settle)\n immediate = task.catch(() => {})\n track(task)\n return\n }\n const timer = scheduleTimer(() => {\n pending.delete(delivery.id)\n track(settle())\n }, delay)\n unref(timer)\n pending.set(delivery.id, timer)\n }\n\n const endpointsFor = (namespace: string) => [...(own.get(namespace) ?? []), ...global]\n\n const fanOut = (message: WebhookMessage, state: WebhookDelivery[\"state\"] = \"pending\") => {\n for (const endpoint of endpointsFor(message.namespace)) {\n if (!matchesEndpoint(endpoint, message)) continue\n const delivery: WebhookDelivery = {\n id: id(\"dlv_\"),\n messageId: message.id,\n namespace: message.namespace,\n type: message.type,\n endpointId: endpoint.id ?? \"we_unknown\",\n url: endpoint.url,\n state,\n attempts: [],\n }\n deliveries.set(delivery.id, delivery)\n payloads.set(delivery.id, { message, endpoint })\n if (state === \"pending\") schedule(delivery)\n }\n }\n\n const takeFault = (namespace: string): WebhookFault[\"mode\"] | undefined => {\n const queue = faults.get(namespace)\n const head = queue?.[0]\n if (!queue || !head) return undefined\n head.remaining--\n if (head.remaining <= 0) queue.shift()\n return head.mode\n }\n\n const releaseHeld = (namespace: string) => {\n const waiting = held.get(namespace)\n if (!waiting) return\n held.delete(namespace)\n for (const message of waiting) fanOut(message)\n }\n\n const hub: WebhookHub = {\n publish(input) {\n const contentType =\n input.contentType ?? (input.form ? \"application/x-www-form-urlencoded\" : \"application/json\")\n const body =\n typeof input.body === \"string\"\n ? input.body\n : input.form\n ? new URLSearchParams(input.form).toString()\n : JSON.stringify(input.body)\n const message: WebhookMessage = {\n id: input.id ?? id(\"msg_\"),\n namespace: input.namespace,\n type: input.type,\n body,\n contentType,\n tags: input.tags ?? {},\n headers: input.headers ?? {},\n publishedAt: new Date(now()).toISOString(),\n }\n messages.push(message)\n const ofNamespace = messages.filter((m) => m.namespace === message.namespace)\n const oldest = ofNamespace[0]\n if (ofNamespace.length > keep && oldest) messages.splice(messages.indexOf(oldest), 1)\n options.onMessage?.(message)\n const fault = takeFault(message.namespace)\n if (fault === \"drop\") {\n fanOut(message, \"dropped\")\n return message\n }\n if (fault === \"reorder\") {\n // Held until the next message goes out, so the receiver sees them swapped.\n held.set(message.namespace, [...(held.get(message.namespace) ?? []), message])\n return message\n }\n fanOut(message)\n if (fault === \"duplicate\") fanOut(message)\n releaseHeld(message.namespace)\n return message\n },\n setEndpoints(namespace, endpoints) {\n const withIds = endpoints.map((e, i) => ({ ...e, id: e.id ?? `we_${namespace}_${i}` }))\n own.set(namespace, withIds)\n return withIds\n },\n endpoints: endpointsFor,\n messages: (namespace) =>\n namespace === undefined ? [...messages] : messages.filter((m) => m.namespace === namespace),\n deliveries: (namespace) =>\n [...deliveries.values()].filter((d) => namespace === undefined || d.namespace === namespace),\n async replay(id) {\n const delivery = deliveries.get(id)\n if (!delivery) return undefined\n const ok = await attempt(delivery)\n if (ok) delivery.state = \"delivered\"\n return delivery\n },\n async flush() {\n // Drains until nothing is held or scheduled: a retry that an attempt failing during this\n // flush schedules runs too, so a caller asserting after `flush` never catches a delivery\n // between attempts. Bounded, as every pass moves each delivery an attempt closer to\n // `delivered` or `failed`.\n for (;;) {\n for (const namespace of [...held.keys()]) releaseHeld(namespace)\n const waiting = [...pending.entries()]\n for (const [id, timer] of waiting) {\n if (timer === undefined) continue\n cancel(timer)\n pending.delete(id)\n const delivery = deliveries.get(id)\n if (!delivery) continue\n track(\n attempt(delivery).then((ok) => {\n if (ok) delivery.state = \"delivered\"\n else schedule(delivery)\n }),\n )\n }\n await hub.idle()\n const scheduled = [...pending.values()].some((timer) => timer !== undefined)\n if (held.size === 0 && !scheduled) return\n }\n },\n async idle() {\n while (inFlight.size > 0) await Promise.allSettled([...inFlight])\n },\n fault(namespace, fault) {\n const queue = faults.get(namespace) ?? []\n queue.push({ mode: fault.mode, remaining: Math.max(1, fault.count ?? 1) })\n faults.set(namespace, queue)\n },\n clear(namespace) {\n for (const [id, delivery] of deliveries) {\n if (namespace !== undefined && delivery.namespace !== namespace) continue\n const timer = pending.get(id)\n if (timer !== undefined) cancel(timer)\n pending.delete(id)\n deliveries.delete(id)\n payloads.delete(id)\n }\n for (let i = messages.length - 1; i >= 0; i--) {\n if (namespace === undefined || messages[i]?.namespace === namespace) messages.splice(i, 1)\n }\n if (namespace === undefined) {\n held.clear()\n faults.clear()\n own.clear()\n } else {\n held.delete(namespace)\n faults.delete(namespace)\n own.delete(namespace)\n }\n },\n }\n return hub\n}\n\nconst json = (status: number, body: unknown): Response =>\n new Response(JSON.stringify(body), { status, headers: { \"content-type\": \"application/json\" } })\n\nconst adminError = (status: number, message: string): Response =>\n json(status, { error: { type: \"mockingbird_admin\", message } })\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst parseEndpoint = (value: unknown): WebhookEndpoint | string => {\n if (!isRecord(value) || typeof value.url !== \"string\") return \"each endpoint needs a url\"\n try {\n new URL(value.url)\n } catch {\n return `not a URL: ${value.url}`\n }\n const endpoint: WebhookEndpoint = { url: value.url }\n if (typeof value.id === \"string\") endpoint.id = value.id\n if (typeof value.secret === \"string\") endpoint.secret = value.secret\n if (typeof value.signUrl === \"string\") endpoint.signUrl = value.signUrl\n const events = value.events ?? value.enabledEvents\n if (Array.isArray(events)) endpoint.events = events.map(String)\n if (isRecord(value.tags)) {\n endpoint.tags = Object.fromEntries(Object.entries(value.tags).map(([k, v]) => [k, String(v)]))\n }\n if (typeof value.account === \"string\")\n endpoint.tags = { ...endpoint.tags, account: value.account }\n if (isRecord(value.headers)) {\n endpoint.headers = Object.fromEntries(\n Object.entries(value.headers).map(([k, v]) => [k, String(v)]),\n )\n }\n return endpoint\n}\n\n/**\n * The standard webhook admin routes, for a runtime that owns `hub`:\n *\n * - `GET /webhooks` deliveries, `GET /webhooks/events` published messages (with bodies:\n * they are the mock's own output), `POST /webhooks/:id/replay`, `POST /webhooks/flush`\n * - `GET|PUT|DELETE /webhook-endpoints` per namespace\n * - `POST /webhooks/faults {mode: duplicate|reorder|drop, count?}`\n */\nexport const webhookAdminRoutes = (hub: WebhookHub): AdminRoutes => ({\n \"GET /webhooks\": ({ url, namespace }) =>\n json(200, {\n deliveries: hub\n .deliveries(url.searchParams.get(\"all\") === \"1\" ? undefined : namespace)\n .filter((d) => {\n const type = url.searchParams.get(\"type\")\n return type === null || d.type === type\n }),\n }),\n \"GET /webhooks/events\": ({ url, namespace }) => {\n const type = url.searchParams.get(\"type\")\n return json(200, {\n events: hub\n .messages(url.searchParams.get(\"all\") === \"1\" ? undefined : namespace)\n .filter((m) => type === null || m.type === type)\n .map((m) => ({ ...m, payload: parsePayload(m) })),\n })\n },\n \"POST /webhooks/:id/replay\": async ({ params }) => {\n const replayed = await hub.replay(params.id as string)\n return replayed ? json(200, replayed) : adminError(404, `no delivery ${params.id}`)\n },\n \"POST /webhooks/flush\": async () => {\n await hub.flush()\n return json(200, { status: \"ok\" })\n },\n \"POST /webhooks/faults\": ({ body, namespace }) => {\n if (!isRecord(body) || ![\"duplicate\", \"reorder\", \"drop\"].includes(String(body.mode))) {\n return adminError(400, \"mode must be duplicate, reorder or drop\")\n }\n const fault: WebhookFault = { mode: body.mode as WebhookFault[\"mode\"] }\n if (typeof body.count === \"number\") fault.count = body.count\n hub.fault(namespace, fault)\n return json(201, { namespace, ...fault })\n },\n \"GET /webhook-endpoints\": ({ namespace }) =>\n json(200, {\n endpoints: hub.endpoints(namespace).map(({ secret, ...rest }) => ({\n ...rest,\n secret: secret ? \"(set)\" : null,\n })),\n }),\n \"PUT /webhook-endpoints\": ({ body, namespace }) => {\n const list = Array.isArray(body) ? body : isRecord(body) ? body.endpoints : undefined\n if (!Array.isArray(list)) return adminError(400, \"expected [{url, secret?, events?}]\")\n const parsed: WebhookEndpoint[] = []\n for (const each of list) {\n const endpoint = parseEndpoint(each)\n if (typeof endpoint === \"string\") return adminError(400, endpoint)\n parsed.push(endpoint)\n }\n const set = hub.setEndpoints(namespace, parsed)\n return json(200, { endpoints: set.map((e) => ({ ...e, secret: e.secret ? \"(set)\" : null })) })\n },\n \"DELETE /webhook-endpoints\": ({ namespace }) => {\n hub.setEndpoints(namespace, [])\n return json(200, { status: \"ok\" })\n },\n})\n\nconst parsePayload = (message: WebhookMessage): unknown => {\n if (message.contentType.startsWith(\"application/json\")) {\n try {\n return JSON.parse(message.body)\n } catch {\n return message.body\n }\n }\n if (message.contentType.startsWith(\"application/x-www-form-urlencoded\")) {\n return Object.fromEntries(new URLSearchParams(message.body))\n }\n return message.body\n}\n", "import { type Checkpoint, type FetchAPI, Timeline } from \"@crvouga/mockingbird-core\"\nimport { listOperations, type OpenAPIDocument } from \"@crvouga/mockingbird-openapi\"\nimport { clearNamespace, type SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport { adminUiRoutes } from \"./admin-ui.js\"\nimport { type Clock, createClock } from \"./clock.js\"\nimport { type AdminRoutes, createControlPlane, NAMESPACE_HEADER } from \"./control.js\"\nimport { type CredentialRegistry, createCredentialRegistry, maskCredential } from \"./credentials.js\"\nimport {\n createFaultRegistry,\n type FaultHit,\n type FaultPreset,\n type FaultPresetList,\n type FaultRegistry,\n type FaultRule,\n} from \"./faults.js\"\nimport { createJournal, DEFAULT_JOURNAL_SIZE, type Journal, responseNotes } from \"./journal.js\"\nimport { createMetrics, type Metrics, type RejectedRequest, type RequestLog } from \"./metrics.js\"\nimport { createRng, type Rng, seedFrom } from \"./rng.js\"\nimport { bootSqlite } from \"./service.js\"\nimport { type NamespaceSnapshot, restoreNamespace, snapshotNamespace } from \"./snapshot.js\"\nimport {\n inspectState,\n type StateDeclaration,\n type StateView,\n stateAdminRoutes,\n} from \"./state-view.js\"\nimport { type AdminUi, assertAdminUi, defineMock, type MockSurface } from \"./surface.js\"\nimport { PACKAGE_VERSION } from \"./version.js\"\nimport { type WebhookHub, webhookAdminRoutes } from \"./webhooks.js\"\n\n/**\n * Stamped on every response the runtime returns \u2014 vendor, fault, admin and health alike \u2014\n * as `<service>@<version>; ns=<namespace>`, so a consumer can tell the mock from the vendor.\n */\nexport const MOCKINGBIRD_HEADER = \"x-mockingbird\"\n/** Selects a named copy-on-write history branch. `main` is the compatibility default. */\nexport const BRANCH_HEADER = \"x-mockingbird-branch\"\n/** Reads a historical checkpoint. With a branch header, initializes that branch from it. */\nexport const AT_HEADER = \"x-mockingbird-at\"\n/** Identifies the resulting checkpoint on successful mutations. */\nexport const CHECKPOINT_HEADER = \"x-mockingbird-checkpoint\"\n\n/** What the runtime needs from a service: a Fetch handler it can reset. */\nexport type ServiceInstance = FetchAPI & { reset(): Promise<void> }\n\n/** Everything an instance shares with the runtime that owns it. */\nexport type InstanceContext = {\n /** Storage namespace for this instance's records. */\n namespace: string\n /** The public namespace name a request selects it by. */\n publicNamespace: string\n sqlite: SqliteClient\n clock: Clock\n rng: Rng\n}\n\nexport type RuntimeOptions<T extends ServiceInstance> = {\n /** Service name, e.g. `\"junction\"`. Also the default namespace's storage key. */\n name: string\n /** Build the instance backing one namespace. Called once per namespace, on first use. */\n create: (context: InstanceContext) => T\n /** The vendor contract, used to name each request's operation in logs, metrics and faults. */\n document?: OpenAPIDocument\n /** Shared by every namespace. Defaults to a fresh `@crvouga/mockingbird-service-sqlite`. */\n sqlite?: SqliteClient\n /** Defaults to a live clock over `Date.now`. */\n clock?: Clock\n /** Seeds every random choice the runtime makes (fault rates). Default `0`. */\n seed?: number | string\n /** Extra `GET /health` fields, such as the loaded corpus version. */\n describe?: () => Record<string, unknown>\n /** Service-specific admin routes, given the runtime so they can reach any namespace. */\n admin?: (runtime: ServiceRuntime<T>) => AdminRoutes\n /** Require this value in `x-mockingbird-admin-key` on `/__admin/*`. Omit to leave admin open. */\n adminKey?: string\n /** Structured request log sink, called once per request. */\n onLog?: (entry: RequestLog) => void\n /** Requests each namespace's journal keeps (`GET /__admin/requests`). Default 1000; 0 turns it off. */\n journalSize?: number\n /** Reported in the `x-mockingbird` header. Default: the bundled package's version. */\n version?: string\n /**\n * The vendor credential a request carries (API key, token, account SID, AWS access key\n * id), for SDKs that cannot send `x-mockingbird-namespace`: a suite maps credentials to\n * namespaces with `PUT /__admin/credentials`. See `bearerToken`, `basicAuth`,\n * `sigV4AccessKeyId`.\n */\n credential?: (request: Request) => string | undefined\n /** Named faults, switched on with `POST /__admin/faults {\"preset\": \"<name>\"}`. */\n presets?: Record<string, FaultPreset>\n /** Outbound webhooks; adds the `/__admin/webhooks*` routes and clears on reset. */\n webhooks?: WebhookHub\n /** Retained time-travel checkpoints per namespace. Default 1,000. */\n maxCheckpoints?: number\n /** Injectable process IO used for observability and delays; logical service time uses `clock`. */\n io?: Partial<RuntimeIO>\n /**\n * Collections the admin UI should show even before any row exists.\n * Stored collections are always included, whether or not they are declared.\n * A function may describe collections that depend on the live instance.\n */\n state?: readonly StateDeclaration[] | ((api: T, namespace: string) => readonly StateDeclaration[])\n /**\n * Panels added to the default admin UI, or a function that replaces the document.\n * `render` receives `defaultHtml()` so a bespoke UI can wrap the shared shell.\n */\n adminUi?: AdminUi\n}\n\nexport type RuntimeIO = {\n wallNow(): number\n monotonicNow(): number\n sleep(ms: number): Promise<void>\n}\n\nexport type ServiceTimelineState = Readonly<{\n snapshot: NamespaceSnapshot\n clock: Readonly<ReturnType<Clock[\"state\"]>>\n rngState: number\n}>\n\nexport type ServiceCheckpoint = Checkpoint<ServiceTimelineState>\n\nexport type ServiceRuntime<T extends ServiceInstance> = FetchAPI & {\n readonly name: string\n readonly sqlite: SqliteClient\n readonly clock: Clock\n readonly faults: FaultRegistry\n readonly metrics: Metrics\n readonly journal: Journal\n readonly rng: Rng\n readonly credentials: CredentialRegistry\n /** The webhook hub, when the service has outbound webhooks. */\n readonly webhooks: WebhookHub | undefined\n /** Expand a named preset into fault rules (and webhook faults) for `namespace`. */\n applyPreset(name: string, namespace?: string, overrides?: Partial<FaultRule>): FaultRule[]\n /** The instance behind `namespace` (the default one when omitted), created on first use. */\n instance(namespace?: string): T\n /** Public names of every namespace created so far. */\n namespaces(): string[]\n /** Reset one namespace, or every namespace with `\"*\"`. */\n reset(namespace?: string): Promise<void>\n snapshot(namespace?: string): NamespaceSnapshot\n restore(snapshot: NamespaceSnapshot, namespace?: string): void\n /** Capture the current branch. Mutating HTTP calls do this automatically. */\n checkpoint(namespace?: string, branch?: string): ServiceCheckpoint\n /** Create an isolated branch, optionally from a historical checkpoint. */\n branch(name: string, options?: { namespace?: string; at?: string }): ServiceCheckpoint\n /** Restore a branch, clock, and PRNG to a checkpoint. */\n checkout(checkpoint: string, options?: { namespace?: string; branch?: string }): void\n /** Inspect the retained history for a namespace. */\n timeline(namespace?: string): Timeline<ServiceTimelineState>\n /** Collections in one namespace: declared shape plus what the rows actually hold. */\n state(namespace?: string): StateView\n}\n\ntype _MockSurfaceProof = ServiceRuntime<ServiceInstance> extends MockSurface ? true : never\nconst mockSurfaceProof: _MockSurfaceProof = true\nvoid mockSurfaceProof\n\n/** The namespace used when a request names none. */\nexport const DEFAULT_NAMESPACE = \"default\"\n\nconst NAMESPACE_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/\n\n/** `/ns/<namespace>/\u2026`: the namespace carrier for SDKs that only take a base URL. */\nconst PATH_PREFIX = /^\\/ns\\/([^/]+)(\\/.*)?$/\nconst BRANCH_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/\nconst MUTATING_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"])\n\nconst effects = new WeakMap<Request, FaultHit[\"effect\"][]>()\n\n/**\n * Merge two sorted snapshot row arrays, retaining byte-identical old objects. Unlike the previous\n * Map/string-key implementation this is allocation-free apart from the result array and O(n).\n */\nconst reuseSorted = <T>(\n fresh: T[],\n previous: T[] | undefined,\n compare: (left: T, right: T) => number,\n equal: (left: T, right: T) => boolean,\n): T[] => {\n if (!previous || previous.length === 0) return fresh.map((row) => Object.freeze(row))\n const result = new Array<T>(fresh.length)\n let unchanged = fresh.length === previous.length\n let oldIndex = 0\n for (let index = 0; index < fresh.length; index++) {\n const row = fresh[index] as T\n while (oldIndex < previous.length && compare(previous[oldIndex] as T, row) < 0) {\n oldIndex++\n }\n const old = previous[oldIndex]\n result[index] =\n old !== undefined && compare(old, row) === 0 && equal(old, row) ? old : Object.freeze(row)\n if (result[index] !== previous[index]) unchanged = false\n }\n return unchanged ? previous : result\n}\n\n/**\n * The fault effects (`{\"effect\": \"created_but_500\"}` rules) that fired for this request, in\n * rule order. Handlers read this to switch on a named vendor misbehaviour.\n */\nexport const faultEffects = (\n request: Request,\n): { name: string; params: Record<string, unknown> }[] =>\n (effects.get(request) ?? []).filter((e): e is NonNullable<typeof e> => e !== undefined)\n\n/** Whether the named effect fired for this request; its params when it did. */\nexport const faultEffect = (request: Request, name: string): Record<string, unknown> | undefined =>\n faultEffects(request).find((e) => e.name === name)?.params\n\n/**\n * Thrown by an in-process `runtime.fetch` when a `drop` fault fires: the same thing a real\n * `fetch` does when the connection dies mid-request. A served mock destroys the socket.\n */\nexport class DroppedConnectionError extends TypeError {\n readonly code = \"MOCKINGBIRD_DROP\"\n constructor() {\n super(\"fetch failed: connection dropped by Mockingbird fault\")\n this.name = \"TypeError\"\n }\n}\n\ntype Matcher = { operationId: string; method: string; pattern: RegExp; params: number }\n\n/** Resolve a request to its operationId: static segments beat parameters, as in routing. */\nconst operationMatcher = (document: OpenAPIDocument) => {\n const matchers: Matcher[] = listOperations(document)\n .map((operation) => ({\n operationId: operation.operationId,\n method: operation.method.toUpperCase(),\n pattern: new RegExp(\n `^${operation.path\n .split(\"/\")\n .map((segment) =>\n segment.startsWith(\"{\") ? \"[^/]+\" : segment.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"),\n )\n .join(\"/\")}/?$`,\n ),\n params: (operation.path.match(/\\{/g) ?? []).length,\n }))\n .sort((a, b) => a.params - b.params)\n return (request: Request, path: string): string | undefined =>\n matchers.find((m) => m.method === request.method && m.pattern.test(path))?.operationId\n}\n\n/**\n * Wrap a service in the shared Mockingbird contract: an unauthenticated `/health`,\n * the `/__admin/*` control plane, per-request namespaces, a controllable clock,\n * fault injection, and request metrics.\n *\n * Namespaces isolate parallel workers inside one process: each gets its own\n * instance over the same SQLite database, so rows are partitioned by namespace\n * and a worker's reset or restore never touches another worker's data.\n */\nexport const createRuntime = <T extends ServiceInstance>(\n options: RuntimeOptions<T>,\n): ServiceRuntime<T> => {\n assertAdminUi(options.adminUi)\n const sqlite = bootSqlite(options.sqlite)\n const clock = options.clock ?? createClock()\n const rng = createRng(options.seed ?? 0)\n const wallNow = options.io?.wallNow ?? Date.now\n const monotonicNow = options.io?.monotonicNow ?? (() => performance.now())\n const sleep =\n options.io?.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)))\n const faults = createFaultRegistry(createRng(options.seed ?? 0), sleep)\n const metrics = createMetrics()\n const journal = createJournal(options.journalSize ?? DEFAULT_JOURNAL_SIZE)\n const version = options.version ?? PACKAGE_VERSION\n const instances = new Map<string, T>()\n const publicNamespaces = new Set<string>()\n const branchRngs = new Map<string, Rng>()\n const timelines = new Map<string, Timeline<ServiceTimelineState>>()\n const branchStorage = new Map<string, string>()\n const captured = new Map<string, NamespaceSnapshot>()\n const credentials = createCredentialRegistry()\n const operationIdFor = options.document ? operationMatcher(options.document) : () => undefined\n\n const storageNamespace = (name: string) =>\n name === DEFAULT_NAMESPACE ? options.name : `${options.name}:${name}`\n\n const instanceFor = (key: string, publicNamespace = key, isolatedRng?: Rng): T => {\n const existing = instances.get(key)\n if (existing) return existing\n if (!NAMESPACE_PATTERN.test(key) || !NAMESPACE_PATTERN.test(publicNamespace)) {\n throw new RangeError(\n `namespace must match ${NAMESPACE_PATTERN}: ${JSON.stringify(publicNamespace)}`,\n )\n }\n const created = options.create({\n namespace: storageNamespace(key),\n publicNamespace,\n sqlite,\n clock,\n rng: isolatedRng ?? rng,\n })\n instances.set(key, created)\n publicNamespaces.add(publicNamespace)\n if (isolatedRng) branchRngs.set(key, isolatedRng)\n return created\n }\n\n const instance = (name: string = DEFAULT_NAMESPACE): T => instanceFor(name)\n\n const capture = (storage: string): ServiceTimelineState => {\n const fresh = snapshotNamespace(sqlite, storageNamespace(storage))\n const previous = captured.get(storage)\n const snapshot: NamespaceSnapshot = {\n namespace: fresh.namespace,\n records: reuseSorted(\n fresh.records,\n previous?.records,\n (left, right) =>\n left.collection < right.collection\n ? -1\n : left.collection > right.collection\n ? 1\n : left.seq - right.seq,\n (left, right) => left.id === right.id && left.value === right.value,\n ),\n sequences: reuseSorted(\n fresh.sequences,\n previous?.sequences,\n (left, right) =>\n left.name < right.name\n ? -1\n : left.name > right.name\n ? 1\n : left.kind < right.kind\n ? -1\n : left.kind > right.kind\n ? 1\n : 0,\n (left, right) => left.value === right.value,\n ),\n }\n Object.freeze(snapshot.records)\n Object.freeze(snapshot.sequences)\n Object.freeze(snapshot)\n captured.set(storage, snapshot)\n return Object.freeze({\n snapshot,\n clock: Object.freeze(clock.state()),\n rngState: (branchRngs.get(storage) ?? rng).state(),\n })\n }\n\n const timeline = (name: string = DEFAULT_NAMESPACE): Timeline<ServiceTimelineState> => {\n let found = timelines.get(name)\n if (found) return found\n instance(name)\n found = new Timeline<ServiceTimelineState>({\n now: clock.now,\n ...(options.maxCheckpoints !== undefined ? { maxCheckpoints: options.maxCheckpoints } : {}),\n })\n found.commit(capture(name))\n timelines.set(name, found)\n return found\n }\n\n const physicalBranch = (namespace: string, branch: string): string => {\n if (branch === \"main\") return namespace\n const mapKey = `${namespace}\\0${branch}`\n const existing = branchStorage.get(mapKey)\n if (existing) return existing\n // The hash keeps the internal instance key inside the 64-character namespace contract.\n const key = `branch_${seedFrom(`${options.name}\\0${namespace}\\0${branch}`).toString(36)}`\n branchStorage.set(mapKey, key)\n return key\n }\n\n const ensureBranch = (namespace: string, branch: string, at?: string): string => {\n if (!BRANCH_PATTERN.test(branch)) throw new RangeError(`branch must match ${BRANCH_PATTERN}`)\n const history = timeline(namespace)\n if (branch === \"main\") {\n if (at !== undefined) {\n const point = history.checkout(\"main\", at)\n restoreNamespace(sqlite, storageNamespace(namespace), point.value.snapshot)\n captured.set(namespace, point.value.snapshot)\n rng.setState(point.value.rngState)\n clock.set(point.value.clock.now)\n if (point.value.clock.frozen) clock.freeze()\n else clock.unfreeze()\n }\n return namespace\n }\n const storage = physicalBranch(namespace, branch)\n if (!history.hasBranch(branch)) {\n // Capture unobserved background work before branching from the current main head.\n if (at === undefined) history.commit(capture(namespace))\n const point = history.fork(branch, at === undefined ? {} : { from: at })\n const branchRng = createRng(options.seed ?? 0)\n if (point) branchRng.setState(point.value.rngState)\n instanceFor(storage, namespace, branchRng)\n if (point) restoreNamespace(sqlite, storageNamespace(storage), point.value.snapshot)\n if (point) captured.set(storage, point.value.snapshot)\n } else if (at !== undefined && history.head(branch)?.id !== at) {\n const point = history.checkout(branch, at)\n if (!instances.has(storage)) {\n const branchRng = createRng(options.seed ?? 0)\n branchRng.setState(point.value.rngState)\n instanceFor(storage, namespace, branchRng)\n }\n branchRngs.get(storage)?.setState(point.value.rngState)\n restoreNamespace(sqlite, storageNamespace(storage), point.value.snapshot)\n captured.set(storage, point.value.snapshot)\n } else {\n if (!instances.has(storage)) {\n const point = history.head(branch)\n const branchRng = createRng(options.seed ?? 0)\n if (point) branchRng.setState(point.value.rngState)\n instanceFor(storage, namespace, branchRng)\n }\n }\n return storage\n }\n\n const checkpoint = (namespace = DEFAULT_NAMESPACE, branch = \"main\"): ServiceCheckpoint => {\n const storage = ensureBranch(namespace, branch)\n return timeline(namespace).commit(capture(storage), { branch })\n }\n\n const branch = (\n name: string,\n branchOptions: { namespace?: string; at?: string } = {},\n ): ServiceCheckpoint => {\n const namespace = branchOptions.namespace ?? DEFAULT_NAMESPACE\n ensureBranch(namespace, name, branchOptions.at)\n const head = timeline(namespace).head(name)\n if (!head) throw new RangeError(`branch ${name} has no checkpoint`)\n return head\n }\n\n const checkout = (\n checkpointId: string,\n checkoutOptions: { namespace?: string; branch?: string } = {},\n ): void => {\n const namespace = checkoutOptions.namespace ?? DEFAULT_NAMESPACE\n const branchName = checkoutOptions.branch ?? \"main\"\n const history = timeline(namespace)\n const point = history.checkout(branchName, checkpointId)\n const storage = ensureBranch(namespace, branchName)\n restoreNamespace(sqlite, storageNamespace(storage), point.value.snapshot)\n captured.set(storage, point.value.snapshot)\n clock.set(point.value.clock.now)\n if (point.value.clock.frozen) clock.freeze()\n else clock.unfreeze()\n ;(branchRngs.get(storage) ?? rng).setState(point.value.rngState)\n }\n\n const reset = async (name: string = DEFAULT_NAMESPACE): Promise<void> => {\n if (name === \"*\") {\n options.webhooks?.clear()\n for (const each of instances.values()) await each.reset()\n timelines.clear()\n branchStorage.clear()\n branchRngs.clear()\n captured.clear()\n return\n }\n options.webhooks?.clear(name)\n const target = instances.get(name)\n if (target) await target.reset()\n else clearNamespace(sqlite, storageNamespace(name))\n for (const [mapping, storage] of branchStorage) {\n if (!mapping.startsWith(`${name}\\0`)) continue\n const branchInstance = instances.get(storage)\n if (branchInstance) await branchInstance.reset()\n else clearNamespace(sqlite, storageNamespace(storage))\n branchStorage.delete(mapping)\n branchRngs.delete(storage)\n captured.delete(storage)\n }\n timelines.delete(name)\n captured.delete(name)\n }\n\n const snapshot = (name: string = DEFAULT_NAMESPACE): NamespaceSnapshot => {\n return checkpoint(name, \"main\").value.snapshot\n }\n\n const restore = (from: NamespaceSnapshot, name: string = DEFAULT_NAMESPACE): void => {\n instance(name)\n restoreNamespace(sqlite, storageNamespace(name), from)\n captured.set(name, from)\n // Import legacy snapshots into the canonical history instead of creating a second rollback\n // mechanism. The compatibility method stays synchronous and keeps its original return type.\n const history = timelines.get(name)\n if (history) history.commit(capture(name), { branch: \"main\" })\n else timeline(name)\n }\n\n const declarationsFor = (namespace: string): readonly StateDeclaration[] => {\n const declared = options.state\n if (!declared) return []\n return typeof declared === \"function\" ? declared(instance(namespace), namespace) : declared\n }\n\n const stateScope = (namespace: string) => ({\n sqlite,\n namespace,\n storageNamespace: storageNamespace(namespace),\n root: instance(namespace),\n declarations: declarationsFor(namespace),\n })\n\n const runtime: ServiceRuntime<T> = {\n name: options.name,\n sqlite,\n clock,\n faults,\n metrics,\n journal,\n rng,\n credentials,\n webhooks: options.webhooks,\n applyPreset: (name, namespace = DEFAULT_NAMESPACE, overrides = {}) => {\n const preset = options.presets?.[name]\n if (!preset) throw new RangeError(`no fault preset ${JSON.stringify(name)}`)\n const added = (preset.rules ?? []).map((rule, index) =>\n faults.add({\n namespace,\n ...rule,\n ...overrides,\n preset: name,\n id: `${overrides.id ?? name}${(preset.rules ?? []).length > 1 ? `_${index + 1}` : \"\"}`,\n } as FaultRule),\n )\n if (preset.webhook && options.webhooks) {\n options.webhooks.fault(namespace, {\n ...preset.webhook,\n ...(overrides.count !== undefined ? { count: overrides.count } : {}),\n })\n }\n return added\n },\n instance,\n namespaces: () => [...publicNamespaces].sort(),\n reset,\n snapshot,\n restore,\n checkpoint,\n branch,\n checkout,\n timeline,\n state: (namespace = DEFAULT_NAMESPACE) => inspectState(stateScope(namespace)),\n fetch: async (incoming) => {\n let request = incoming\n // `/ns/<name>/\u2026` selects a namespace (and is stripped) for SDKs that cannot add headers.\n const prefixed = PATH_PREFIX.exec(new URL(request.url).pathname)\n if (prefixed) {\n const url = new URL(request.url)\n url.pathname = prefixed[2] ?? \"/\"\n const headers = new Headers(request.headers)\n if (!headers.has(NAMESPACE_HEADER)) {\n headers.set(NAMESPACE_HEADER, decodeURIComponent(prefixed[1] as string))\n }\n const hasBody = request.method !== \"GET\" && request.method !== \"HEAD\"\n request = new Request(url, {\n method: request.method,\n headers,\n ...(hasBody ? { body: await request.arrayBuffer() } : {}),\n signal: request.signal,\n })\n }\n let namespace = control.namespaceOf(request)\n if (!request.headers.has(NAMESPACE_HEADER) && options.credential) {\n const credential = options.credential(request)\n const mapped = credential !== undefined ? credentials.get(credential) : undefined\n if (mapped !== undefined) namespace = mapped\n }\n const selectedBranch = request.headers.get(BRANCH_HEADER) ?? \"main\"\n const at = request.headers.get(AT_HEADER) ?? undefined\n const stamp = (response: Response): Response => {\n // An invalid namespace is not echoed back.\n const value = NAMESPACE_PATTERN.test(namespace)\n ? `${options.name}@${version}; ns=${namespace}`\n : `${options.name}@${version}`\n try {\n response.headers.set(MOCKINGBIRD_HEADER, value)\n return response\n } catch {\n // Immutable headers (a response passed through from `fetch`): copy it.\n const copy = new Response(response.body, response)\n copy.headers.set(MOCKINGBIRD_HEADER, value)\n return copy\n }\n }\n const handled = await control.handle(request)\n if (handled) return stamp(handled)\n const started = monotonicNow()\n const url = new URL(request.url)\n const operationId = operationIdFor(request, url.pathname)\n // What a rejection records about the body. The runtime never reads the request stream \u2014\n // consuming it would break a streaming request (e.g. a bidirectional model stream) \u2014 so the\n // byte count comes from `content-length` when the client sent it, and is null otherwise.\n const contentLength = request.headers.get(\"content-length\")\n const received: RejectedRequest = {\n contentType: request.headers.get(\"content-type\"),\n bodyBytes:\n contentLength !== null && /^\\d+$/.test(contentLength) ? Number(contentLength) : null,\n transferEncoding: request.headers.get(\"transfer-encoding\"),\n }\n const log = (status: number, faultId?: string, response?: Response) => {\n const noted = response ? responseNotes(response) : undefined\n const rejected = status >= 400 && faultId === undefined\n const entry: RequestLog = {\n service: options.name,\n namespace,\n operationId,\n method: request.method,\n path: url.pathname,\n status,\n durationMs: Math.round((monotonicNow() - started) * 100) / 100,\n unmatched: options.document !== undefined && operationId === undefined,\n ...(faultId !== undefined ? { faultId } : {}),\n ...(noted?.ids && Object.keys(noted.ids).length > 0 ? { ids: noted.ids } : {}),\n ...(noted?.adopted ? { adopted: true } : {}),\n ...(rejected ? { request: { ...received } } : {}),\n ...(rejected && noted?.issues && noted.issues.length > 0\n ? { issues: noted.issues.map((issue) => ({ ...issue })) }\n : {}),\n }\n metrics.record(entry)\n journal.record({ ...entry, at: new Date(clock.now()).toISOString() })\n options.onLog?.(entry)\n }\n if (!NAMESPACE_PATTERN.test(namespace)) {\n log(400)\n return stamp(\n new Response(\n JSON.stringify({\n error: {\n type: \"mockingbird_admin\",\n message: `${NAMESPACE_HEADER} must match ${NAMESPACE_PATTERN}`,\n },\n }),\n { status: 400, headers: { \"content-type\": \"application/json\" } },\n ),\n )\n }\n if (!BRANCH_PATTERN.test(selectedBranch)) {\n log(400)\n return stamp(adminFail(400, `${BRANCH_HEADER} must match ${BRANCH_PATTERN}`))\n }\n let storage: string\n try {\n if (\n at !== undefined &&\n selectedBranch === \"main\" &&\n !MUTATING_METHODS.has(request.method)\n ) {\n const point = timeline(namespace).get(at)\n storage = physicalBranch(namespace, `at_${at}`)\n let viewRng = branchRngs.get(storage)\n if (!viewRng) {\n viewRng = createRng(options.seed ?? 0)\n instanceFor(storage, namespace, viewRng)\n }\n viewRng.setState(point.value.rngState)\n restoreNamespace(sqlite, storageNamespace(storage), point.value.snapshot)\n captured.set(storage, point.value.snapshot)\n } else {\n storage = ensureBranch(namespace, selectedBranch, at)\n }\n } catch (error) {\n log(409)\n return stamp(adminFail(409, error instanceof Error ? error.message : String(error)))\n }\n const hits = await faults.take({\n operationId,\n method: request.method,\n path: url.pathname,\n namespace,\n })\n const final = hits.find((hit) => hit.drop || hit.response)\n if (final?.drop) {\n log(0, final.id)\n throw new DroppedConnectionError()\n }\n if (final?.response) {\n log(final.response.status, final.id)\n return stamp(final.response)\n }\n const fired = hits.filter((hit) => hit.effect !== undefined)\n if (fired.length > 0)\n effects.set(\n request,\n fired.map((hit) => hit.effect),\n )\n let response = await instanceFor(storage, namespace).fetch(request)\n if (MUTATING_METHODS.has(request.method) && response.status >= 200 && response.status < 400) {\n const point = timeline(namespace).commit(capture(storage), { branch: selectedBranch })\n response = mutableResponse(response)\n response.headers.set(CHECKPOINT_HEADER, point.id)\n }\n if (selectedBranch !== \"main\") {\n response = mutableResponse(response)\n response.headers.set(BRANCH_HEADER, selectedBranch)\n }\n if (at !== undefined) {\n response = mutableResponse(response)\n response.headers.set(AT_HEADER, at)\n }\n log(response.status, fired[0]?.id, response)\n return stamp(response)\n },\n }\n\n const control = createControlPlane({\n name: options.name,\n startedAt: wallNow(),\n wallNow,\n clock,\n faults,\n metrics,\n journal,\n defaultNamespace: DEFAULT_NAMESPACE,\n namespaces: runtime.namespaces,\n reset,\n timeTravel: {\n checkpoint: (name, branchName) => {\n const point = checkpoint(name, branchName)\n return {\n id: point.id,\n branch: point.branch,\n parent: point.parent,\n at: point.at,\n records: point.value.snapshot.records.length,\n }\n },\n branch: (branchName, branchOptions) => {\n const point = branch(branchName, branchOptions)\n return { id: point.id, branch: point.branch, parent: point.parent, at: point.at }\n },\n checkout: (checkpointId, checkoutOptions) => checkout(checkpointId, checkoutOptions),\n retain: (name, checkpointId) => {\n timeline(name).retain(checkpointId)\n },\n release: (name, checkpointId) => timeline(name).release(checkpointId),\n inspect: (name) => {\n const history = timeline(name)\n return {\n branches: history.branches(),\n checkpoints: history.checkpoints().map(({ id, branch: branchName, parent, at }) => ({\n id,\n branch: branchName,\n parent,\n at,\n })),\n }\n },\n },\n describe: options.describe ?? (() => ({})),\n ...(options.presets\n ? {\n applyPreset: (name: string, namespace: string, overrides: Partial<FaultRule>) =>\n runtime.applyPreset(name, namespace, overrides),\n }\n : {}),\n routes: {\n ...credentialRoutes(credentials),\n ...(options.webhooks ? webhookAdminRoutes(options.webhooks) : {}),\n ...(options.admin?.(runtime) ?? {}),\n // Shell routes win a colliding key. Fault presets are one of them: the admin page\n // maps `presets`, and a service route must not replace that list with a record.\n ...(options.presets ? presetRoutes(options.presets, runtime) : {}),\n ...stateAdminRoutes({\n open: stateScope,\n afterWrite: (namespace) => {\n checkpoint(namespace, \"main\")\n },\n }),\n ...adminUiRoutes(options.name, options.adminUi),\n },\n adminKey: options.adminKey,\n })\n\n return defineMock(runtime)\n}\n\nconst mutableResponse = (response: Response): Response => {\n try {\n response.headers.set(\"x-mockingbird-mutable-probe\", \"1\")\n response.headers.delete(\"x-mockingbird-mutable-probe\")\n return response\n } catch {\n return new Response(response.body, response)\n }\n}\n\nconst adminJson = (status: number, body: unknown): Response =>\n new Response(JSON.stringify(body), { status, headers: { \"content-type\": \"application/json\" } })\n\nconst adminFail = (status: number, message: string): Response =>\n adminJson(status, { error: { type: \"mockingbird_admin\", message } })\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\n/**\n * `PUT /__admin/credentials` accepts `{ credentials: { \"<credential>\": \"<namespace>\" } }`,\n * `[{ credential, namespace }]`, or `{ credentials: [\"<credential>\"] }` with `?namespace=`\n * (maps each to the calling namespace). `GET` lists them masked; `DELETE` removes one\n * (`?credential=`) or all.\n */\nconst credentialRoutes = (registry: CredentialRegistry): AdminRoutes => ({\n \"GET /credentials\": () =>\n adminJson(200, {\n credentials: registry.entries().map(({ credential, namespace }) => ({\n credential: maskCredential(credential),\n namespace,\n })),\n }),\n \"PUT /credentials\": ({ body, namespace }) => {\n const pairs: [string, string][] = []\n const list = Array.isArray(body) ? body : isObject(body) ? body.credentials : undefined\n if (Array.isArray(list)) {\n for (const each of list) {\n if (typeof each === \"string\") pairs.push([each, namespace])\n else if (isObject(each) && typeof each.credential === \"string\") {\n pairs.push([\n each.credential,\n typeof each.namespace === \"string\" ? each.namespace : namespace,\n ])\n } else return adminFail(400, \"each entry is a credential string or {credential, namespace}\")\n }\n } else if (isObject(list)) {\n for (const [credential, target] of Object.entries(list)) {\n if (typeof target !== \"string\")\n return adminFail(400, `namespace for ${credential} must be a string`)\n pairs.push([credential, target])\n }\n } else if (isObject(body) && typeof body.credential === \"string\") {\n pairs.push([body.credential, typeof body.namespace === \"string\" ? body.namespace : namespace])\n } else {\n return adminFail(400, 'expected {\"credentials\": {\"<credential>\": \"<namespace>\"}}')\n }\n for (const [credential, target] of pairs) {\n if (!NAMESPACE_PATTERN.test(target))\n return adminFail(400, `bad namespace ${JSON.stringify(target)}`)\n registry.set(credential, target)\n }\n return adminJson(200, { mapped: pairs.length })\n },\n \"DELETE /credentials\": ({ url }) => {\n const credential = url.searchParams.get(\"credential\")\n if (credential === null) registry.clear()\n else registry.remove(credential)\n return adminJson(200, { status: \"ok\" })\n },\n})\n\nconst presetRoutes = <T extends ServiceInstance>(\n presets: Record<string, FaultPreset>,\n runtime: ServiceRuntime<T>,\n): AdminRoutes => ({\n \"GET /faults/presets\": () => {\n const body: FaultPresetList = {\n presets: Object.entries(presets).map(([name, preset]) => ({ name, ...preset })),\n }\n return adminJson(200, body)\n },\n \"POST /faults/presets/:name\": ({ params, body, namespace }) => {\n const name = params.name as string\n if (!presets[name])\n return adminFail(404, `no fault preset ${name}; GET /__admin/faults/presets`)\n const overrides = isObject(body) ? (body as Partial<FaultRule>) : {}\n return adminJson(201, { preset: name, rules: runtime.applyPreset(name, namespace, overrides) })\n },\n})\n", "// Generated by @crvouga/mockingbird-openapi-codegen from openapi.yaml. Do not edit.\n\nimport type { OpenAPIDocument } from \"@crvouga/mockingbird-openapi\"\n\nexport const document: OpenAPIDocument = JSON.parse(`{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Google Places, Geocoding and Maps JavaScript API (Mockingbird subset)\",\"description\":\"The Google Maps Platform surface our member app calls: Places Autocomplete, Place Details\\\\nand Find Place From Text (the legacy JSON web services), the Geocoding API, and the Maps\\\\nJavaScript API loader (\\`/maps/api/js?libraries=places\\`). Every web-service answer is HTTP 200\\\\nwith Google's \\`status\\` field; the mock resolves addresses from a QA corpus.\\\\n\",\"version\":\"1\",\"x-mockingbird-upstream\":{\"note\":\"Hand-authored from Google's documented response shapes and the fields our consumer reads (address-autocomplete-native-rest.tsx, address-autocomplete-web.tsx, use-geocoded-address.ts). Google publishes no OpenAPI document for these endpoints.\"}},\"servers\":[{\"url\":\"https://maps.googleapis.com\"}],\"paths\":{\"/maps/api/place/autocomplete/json\":{\"get\":{\"operationId\":\"PlaceAutocomplete\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":true,\"safe\":true}},\"parameters\":[{\"$ref\":\"#/components/parameters/Key\"},{\"name\":\"input\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\",\"minLength\":1,\"maxLength\":60,\"examples\":[\"1625 N Central\",\"Phoenix\",\"85004\",\"4821 Maple Street Denver\",\"200 N Spring St, Los Angeles\",\"136 Murray\"]}},{\"name\":\"types\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"enum\":[\"address\",\"geocode\"]}},{\"name\":\"components\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"enum\":[\"country:us\",\"country:ca\",\"country:us|country:ca\"]}},{\"$ref\":\"#/components/parameters/SessionToken\"}],\"responses\":{\"200\":{\"description\":\"Predictions, or a non-OK status (HTTP 200 either way)\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/AutocompleteResponse\"}}}},\"500\":{\"description\":\"Google front-end failure (server_error preset)\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/maps/api/place/details/json\":{\"get\":{\"operationId\":\"PlaceDetails\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":true,\"safe\":true}},\"parameters\":[{\"$ref\":\"#/components/parameters/Key\"},{\"name\":\"place_id\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\",\"minLength\":1,\"maxLength\":200,\"examples\":[\"ChIJ5BKAwJuCB5951g03ZzrkHx9\",\"ChIJE1ellR5XyWiy2lHIlJ5cls3\",\"ChIJaWYsCINV1XBQQ97jO3pznpg\",\"EieyJsIjoiNDgyMSBNYXBsZSBTdHJlZXQiLCJjIjoiRGVudmVyIiwicyI6IkNPIiwieiI6IjgwMjAyIiwibiI6IkRlbnZlciBDb3VudHkiLCJhIjozOS43NDc4OCwibyI6LTEwNC45OTQyNX0\",\"ChIJdoesNotExist000000000\"]}},{\"name\":\"fields\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"enum\":[\"address_component\",\"address_components\",\"geometry\",\"formatted_address,geometry\",\"place_id,name,types\",\"address_component,geometry,formatted_address\"]}},{\"$ref\":\"#/components/parameters/SessionToken\"}],\"responses\":{\"200\":{\"description\":\"The place, or a non-OK status\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/DetailsResponse\"}}}},\"500\":{\"description\":\"Google front-end failure (server_error preset)\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/maps/api/geocode/json\":{\"get\":{\"operationId\":\"Geocode\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":true,\"safe\":true}},\"parameters\":[{\"$ref\":\"#/components/parameters/Key\"},{\"name\":\"address\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"minLength\":1,\"maxLength\":80,\"examples\":[\"1625 N Central Ave, Phoenix, AZ 85004\",\"88 Greenwich St, New York, NY 10006\",\"4821 Maple Street, Denver, CO 80202\",\"85004\",\"Phoenix, AZ\",\"1625 N Central Ave\"]}},{\"name\":\"place_id\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"examples\":[\"ChIJ5BKAwJuCB5951g03ZzrkHx9\"]}},{\"name\":\"components\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"enum\":[\"postal_code:85004\",\"postal_code:10006\",\"postal_code:00000\"]}}],\"responses\":{\"200\":{\"description\":\"Geocoding results, or a non-OK status\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/GeocodeResponse\"}}}},\"500\":{\"description\":\"Google front-end failure (server_error preset)\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/maps/api/place/findplacefromtext/json\":{\"get\":{\"operationId\":\"FindPlaceFromText\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":true,\"safe\":true}},\"parameters\":[{\"$ref\":\"#/components/parameters/Key\"},{\"name\":\"input\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\",\"minLength\":1,\"maxLength\":80,\"examples\":[\"1625 N Central Ave, Phoenix, AZ 85004\",\"1625 N Central\",\"Gilbert\"]}},{\"name\":\"inputtype\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\",\"enum\":[\"textquery\",\"phonenumber\"]}},{\"name\":\"fields\",\"in\":\"query\",\"schema\":{\"type\":\"string\",\"enum\":[\"geometry\",\"formatted_address,geometry\",\"place_id,name\",\"place_id\"]}}],\"responses\":{\"200\":{\"description\":\"Candidates, or a non-OK status\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/FindPlaceResponse\"}}}},\"500\":{\"description\":\"Google front-end failure (server_error preset)\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\"}}}}}}},\"/maps/api/js\":{\"get\":{\"operationId\":\"MapsJavaScriptApi\",\"description\":\"The Maps JavaScript API loader. The mock serves a shim defining google.maps.places (AutocompleteService, PlacesService, AutocompleteSessionToken, PlacesServiceStatus) and google.maps.Geocoder, backed by the REST operations above.\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":false,\"reason\":\"A JavaScript program, not data: it is exercised by evaluating it in a fake window and driving our web client through it (google-maps.acceptance.test.ts).\"}},\"parameters\":[{\"name\":\"key\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}},{\"name\":\"libraries\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}},{\"name\":\"callback\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}},{\"name\":\"v\",\"in\":\"query\",\"schema\":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"description\":\"The Maps JavaScript shim\",\"content\":{\"text/javascript\":{\"schema\":{\"type\":\"string\"}}}},\"503\":{\"description\":\"Script unavailable (script_unavailable preset)\",\"content\":{\"text/plain\":{\"schema\":{\"type\":\"string\"}}}}}}},\"/v1:validateAddress\":{\"servers\":[{\"url\":\"https://addressvalidation.googleapis.com\"}],\"post\":{\"operationId\":\"ValidateAddress\",\"description\":\"Address Validation API v1 validateAddress, with USPS CASS data (\\`enableUspsCass\\`). A Google Cloud API: errors are HTTP 4xx/5xx with a \\`google.rpc.Status\\` envelope, and the key may also be sent as the \\`X-Goog-Api-Key\\` header. Responses are proto3 JSON (false booleans and empty lists omitted). Reference: https://developers.google.com/maps/documentation/address-validation/reference/rest/v1/TopLevel/validateAddress\",\"x-mockingbird\":{\"supported\":true,\"parity\":{\"enabled\":true,\"safe\":true}},\"parameters\":[{\"$ref\":\"#/components/parameters/Key\"}],\"requestBody\":{\"required\":true,\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ValidateAddressRequest\"}}}},\"responses\":{\"200\":{\"description\":\"The validation result\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/ValidateAddressResponse\"}}}},\"400\":{\"description\":\"INVALID_ARGUMENT (malformed request, unsupported region, invalid API key)\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/GoogleApiError\"}}}},\"403\":{\"description\":\"PERMISSION_DENIED (missing key; address_validation_denied preset)\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/GoogleApiError\"}}}},\"503\":{\"description\":\"UNAVAILABLE (address_validation_unavailable preset)\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/GoogleApiError\"}}}}}}}},\"components\":{\"parameters\":{\"Key\":{\"name\":\"key\",\"in\":\"query\",\"required\":true,\"description\":\"The Google Maps Platform API key (\\`PLACES_KEY\\`); also the namespace credential.\",\"schema\":{\"type\":\"string\",\"minLength\":1,\"maxLength\":40,\"examples\":[\"parity-key\"]}},\"SessionToken\":{\"name\":\"sessiontoken\",\"in\":\"query\",\"description\":\"Autocomplete session token (billing grouping); accepted and journaled as metadata.\",\"schema\":{\"type\":\"string\",\"format\":\"uuid\"}}},\"schemas\":{\"Status\":{\"type\":\"string\",\"enum\":[\"OK\",\"ZERO_RESULTS\",\"INVALID_REQUEST\",\"OVER_QUERY_LIMIT\",\"REQUEST_DENIED\",\"UNKNOWN_ERROR\",\"NOT_FOUND\"]},\"LatLng\":{\"type\":\"object\",\"required\":[\"lat\",\"lng\"],\"properties\":{\"lat\":{\"type\":\"number\"},\"lng\":{\"type\":\"number\"}}},\"Viewport\":{\"type\":\"object\",\"required\":[\"northeast\",\"southwest\"],\"properties\":{\"northeast\":{\"$ref\":\"#/components/schemas/LatLng\"},\"southwest\":{\"$ref\":\"#/components/schemas/LatLng\"}}},\"Geometry\":{\"type\":\"object\",\"required\":[\"location\",\"viewport\"],\"properties\":{\"location\":{\"$ref\":\"#/components/schemas/LatLng\"},\"location_type\":{\"type\":\"string\",\"enum\":[\"ROOFTOP\",\"RANGE_INTERPOLATED\",\"GEOMETRIC_CENTER\",\"APPROXIMATE\"]},\"viewport\":{\"$ref\":\"#/components/schemas/Viewport\"}}},\"AddressComponent\":{\"type\":\"object\",\"required\":[\"long_name\",\"short_name\",\"types\"],\"properties\":{\"long_name\":{\"type\":\"string\"},\"short_name\":{\"type\":\"string\"},\"types\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"MatchedSubstring\":{\"type\":\"object\",\"required\":[\"length\",\"offset\"],\"properties\":{\"length\":{\"type\":\"integer\"},\"offset\":{\"type\":\"integer\"}}},\"Prediction\":{\"type\":\"object\",\"required\":[\"description\",\"place_id\",\"reference\",\"structured_formatting\",\"terms\",\"types\",\"matched_substrings\"],\"properties\":{\"description\":{\"type\":\"string\"},\"matched_substrings\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/MatchedSubstring\"}},\"place_id\":{\"type\":\"string\",\"x-mockingbird-resource\":{\"type\":\"place\",\"identity\":true}},\"reference\":{\"type\":\"string\"},\"structured_formatting\":{\"type\":\"object\",\"required\":[\"main_text\",\"secondary_text\"],\"properties\":{\"main_text\":{\"type\":\"string\"},\"main_text_matched_substrings\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/MatchedSubstring\"}},\"secondary_text\":{\"type\":\"string\"}}},\"terms\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"required\":[\"offset\",\"value\"],\"properties\":{\"offset\":{\"type\":\"integer\"},\"value\":{\"type\":\"string\"}}}},\"types\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"PlaceResult\":{\"type\":\"object\",\"description\":\"Only the fields requested with \\`fields=\\` are present.\",\"properties\":{\"address_components\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/AddressComponent\"}},\"adr_address\":{\"type\":\"string\"},\"formatted_address\":{\"type\":\"string\"},\"geometry\":{\"$ref\":\"#/components/schemas/Geometry\"},\"name\":{\"type\":\"string\"},\"place_id\":{\"type\":\"string\"},\"reference\":{\"type\":\"string\"},\"types\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"url\":{\"type\":\"string\"},\"utc_offset\":{\"type\":\"integer\"},\"vicinity\":{\"type\":\"string\"}}},\"AutocompleteResponse\":{\"type\":\"object\",\"required\":[\"predictions\",\"status\"],\"properties\":{\"predictions\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/Prediction\"}},\"status\":{\"$ref\":\"#/components/schemas/Status\"},\"error_message\":{\"type\":\"string\"}}},\"DetailsResponse\":{\"type\":\"object\",\"required\":[\"html_attributions\",\"status\"],\"properties\":{\"html_attributions\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"result\":{\"$ref\":\"#/components/schemas/PlaceResult\"},\"status\":{\"$ref\":\"#/components/schemas/Status\"},\"error_message\":{\"type\":\"string\"}}},\"GeocodeResult\":{\"type\":\"object\",\"required\":[\"address_components\",\"formatted_address\",\"geometry\",\"place_id\",\"types\"],\"properties\":{\"address_components\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/AddressComponent\"}},\"formatted_address\":{\"type\":\"string\"},\"geometry\":{\"$ref\":\"#/components/schemas/Geometry\"},\"place_id\":{\"type\":\"string\"},\"types\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"GeocodeResponse\":{\"type\":\"object\",\"required\":[\"results\",\"status\"],\"properties\":{\"results\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/GeocodeResult\"}},\"status\":{\"$ref\":\"#/components/schemas/Status\"},\"error_message\":{\"type\":\"string\"}}},\"FindPlaceResponse\":{\"type\":\"object\",\"required\":[\"candidates\",\"status\"],\"properties\":{\"candidates\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/PlaceResult\"}},\"status\":{\"$ref\":\"#/components/schemas/Status\"},\"error_message\":{\"type\":\"string\"}}},\"GoogleApiError\":{\"type\":\"object\",\"required\":[\"error\"],\"properties\":{\"error\":{\"type\":\"object\",\"required\":[\"code\",\"message\",\"status\"],\"properties\":{\"code\":{\"type\":\"integer\"},\"message\":{\"type\":\"string\"},\"status\":{\"type\":\"string\"},\"details\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}}}}}},\"PostalAddress\":{\"type\":\"object\",\"description\":\"google.type.PostalAddress\",\"properties\":{\"revision\":{\"type\":\"integer\"},\"regionCode\":{\"type\":\"string\",\"examples\":[\"US\"]},\"languageCode\":{\"type\":\"string\"},\"postalCode\":{\"type\":\"string\",\"examples\":[\"85004\",\"10006\",\"80202\",\"90012\",\"00000\"]},\"sortingCode\":{\"type\":\"string\"},\"administrativeArea\":{\"type\":\"string\",\"examples\":[\"AZ\",\"NY\",\"CO\",\"CA\"]},\"locality\":{\"type\":\"string\",\"examples\":[\"Phoenix\",\"New York\",\"Denver\",\"Los Angeles\",\"Springfield\"]},\"sublocality\":{\"type\":\"string\"},\"addressLines\":{\"type\":\"array\",\"maxItems\":3,\"items\":{\"type\":\"string\",\"maxLength\":80,\"examples\":[\"1625 N Central Ave\",\"1625 North Central Avenue Building A\",\"4821 Maple Street\",\"N Central Ave\",\"Apt 2\"]}},\"recipients\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"organization\":{\"type\":\"string\"}}},\"ValidateAddressRequest\":{\"type\":\"object\",\"required\":[\"address\"],\"additionalProperties\":false,\"properties\":{\"address\":{\"$ref\":\"#/components/schemas/PostalAddress\",\"examples\":[{\"regionCode\":\"US\",\"addressLines\":[\"1625 N Central Ave\"],\"locality\":\"Phoenix\",\"administrativeArea\":\"AZ\",\"postalCode\":\"85004\"},{\"regionCode\":\"US\",\"addressLines\":[\"4821 Maple Street\"],\"locality\":\"Denver\",\"administrativeArea\":\"CO\",\"postalCode\":\"80202\"},{\"regionCode\":\"US\",\"addressLines\":[\"N Central Ave\"],\"locality\":\"Phoenix\",\"administrativeArea\":\"AZ\",\"postalCode\":\"85004\"},{\"regionCode\":\"US\",\"addressLines\":[\"1625 N Central Ave, Phoenix, AZ 85004\"]},{\"regionCode\":\"US\",\"addressLines\":[\"12 Nowhere Rd\"],\"locality\":\"Springfield\",\"administrativeArea\":\"ZZ\",\"postalCode\":\"00000\"}]},\"previousResponseId\":{\"type\":\"string\"},\"enableUspsCass\":{\"type\":\"boolean\"},\"languageOptions\":{\"type\":\"object\"},\"sessionToken\":{\"type\":\"string\"}}},\"ValidationAddressComponent\":{\"type\":\"object\",\"required\":[\"componentName\",\"componentType\",\"confirmationLevel\"],\"properties\":{\"componentName\":{\"type\":\"object\",\"required\":[\"text\"],\"properties\":{\"text\":{\"type\":\"string\"},\"languageCode\":{\"type\":\"string\"}}},\"componentType\":{\"type\":\"string\"},\"confirmationLevel\":{\"type\":\"string\",\"enum\":[\"CONFIRMED\",\"UNCONFIRMED_BUT_PLAUSIBLE\",\"UNCONFIRMED_AND_SUSPICIOUS\"]},\"inferred\":{\"type\":\"boolean\"},\"spellCorrected\":{\"type\":\"boolean\"},\"replaced\":{\"type\":\"boolean\"},\"unexpected\":{\"type\":\"boolean\"}}},\"Granularity\":{\"type\":\"string\",\"enum\":[\"GRANULARITY_UNSPECIFIED\",\"SUB_PREMISE\",\"PREMISE\",\"PREMISE_PROXIMITY\",\"BLOCK\",\"ROUTE\",\"OTHER\"]},\"ValidationResult\":{\"type\":\"object\",\"properties\":{\"verdict\":{\"type\":\"object\",\"properties\":{\"inputGranularity\":{\"$ref\":\"#/components/schemas/Granularity\"},\"validationGranularity\":{\"$ref\":\"#/components/schemas/Granularity\"},\"geocodeGranularity\":{\"$ref\":\"#/components/schemas/Granularity\"},\"addressComplete\":{\"type\":\"boolean\"},\"hasUnconfirmedComponents\":{\"type\":\"boolean\"},\"hasInferredComponents\":{\"type\":\"boolean\"},\"hasReplacedComponents\":{\"type\":\"boolean\"},\"hasSpellCorrectedComponents\":{\"type\":\"boolean\"},\"possibleNextAction\":{\"type\":\"string\",\"enum\":[\"POSSIBLE_NEXT_ACTION_UNSPECIFIED\",\"FIX\",\"CONFIRM_ADD_SUBPREMISES\",\"CONFIRM\",\"ACCEPT\"]}}},\"address\":{\"type\":\"object\",\"properties\":{\"formattedAddress\":{\"type\":\"string\"},\"postalAddress\":{\"$ref\":\"#/components/schemas/PostalAddress\"},\"addressComponents\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/ValidationAddressComponent\"}},\"missingComponentTypes\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"unconfirmedComponentTypes\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"unresolvedTokens\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"geocode\":{\"type\":\"object\",\"properties\":{\"location\":{\"type\":\"object\",\"properties\":{\"latitude\":{\"type\":\"number\"},\"longitude\":{\"type\":\"number\"}}},\"placeId\":{\"type\":\"string\"},\"placeTypes\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}},\"uspsData\":{\"type\":\"object\",\"properties\":{\"standardizedAddress\":{\"type\":\"object\",\"properties\":{\"firstAddressLine\":{\"type\":\"string\"},\"secondAddressLine\":{\"type\":\"string\"},\"cityStateZipAddressLine\":{\"type\":\"string\"},\"city\":{\"type\":\"string\"},\"state\":{\"type\":\"string\"},\"zipCode\":{\"type\":\"string\"},\"zipCodeExtension\":{\"type\":\"string\"}}},\"dpvConfirmation\":{\"type\":\"string\",\"enum\":[\"Y\",\"N\",\"S\",\"D\"]},\"dpvFootnote\":{\"type\":\"string\"},\"postOfficeCity\":{\"type\":\"string\"},\"postOfficeState\":{\"type\":\"string\"},\"errorMessage\":{\"type\":\"string\"},\"cassProcessed\":{\"type\":\"boolean\"}}}}},\"ValidateAddressResponse\":{\"type\":\"object\",\"required\":[\"result\",\"responseId\"],\"properties\":{\"result\":{\"$ref\":\"#/components/schemas/ValidationResult\"},\"responseId\":{\"type\":\"string\"}}}}}}`) as OpenAPIDocument\n\nexport type OperationId = \"PlaceAutocomplete\" | \"PlaceDetails\" | \"Geocode\" | \"FindPlaceFromText\" | \"MapsJavaScriptApi\" | \"ValidateAddress\"\nexport type SupportedOperationId = \"PlaceAutocomplete\" | \"PlaceDetails\" | \"Geocode\" | \"FindPlaceFromText\" | \"MapsJavaScriptApi\" | \"ValidateAddress\"\nexport const operationIds = [\"PlaceAutocomplete\",\"PlaceDetails\",\"Geocode\",\"FindPlaceFromText\",\"MapsJavaScriptApi\",\"ValidateAddress\"] as const\nexport const supportedOperationIds = [\"PlaceAutocomplete\",\"PlaceDetails\",\"Geocode\",\"FindPlaceFromText\",\"MapsJavaScriptApi\",\"ValidateAddress\"] as const\n", "import type { ValidationOverrides } from \"./validation.js\"\n\n/**\n * The addresses the mock knows, matching our QA fixtures: every row of `ROUTING_ZIP_CORPUS`\n * (`packages/qa/src/world/gen/addresses.ts`, \u22651 real ZIP per state + DC, ids kept stable), the\n * `packages/app/src/test-addresses` members it reuses (the Phoenix AZ at-home demo member\n * `ADDRESS_AT_HOME_PHLEBOTOMY` among them), and `ADDRESS_AT_HOME_PHLEBOTOMY_2`. Coordinates are\n * the city's civic centre, rounded; counties are the real ones.\n */\nexport type CorpusAddress = {\n /** Stable row id (the QA corpus id). */\n id: string\n line1: string\n city: string\n /** Two-letter code. */\n state: string\n zip: string\n county: string\n lat: number\n lng: number\n /** Address Validation controls for this row (admin rows only): pin a verdict, flag units. */\n validation?: ValidationOverrides\n}\n\nconst row = (\n id: string,\n line1: string,\n city: string,\n state: string,\n zip: string,\n county: string,\n lat: number,\n lng: number,\n): CorpusAddress => ({ id, line1, city, state, zip, county, lat, lng })\n\nexport const DEFAULT_CORPUS: readonly CorpusAddress[] = [\n row(\n \"al-birmingham\",\n \"2100 1st Ave N\",\n \"Birmingham\",\n \"AL\",\n \"35203\",\n \"Jefferson County\",\n 33.5167,\n -86.807,\n ),\n row(\"ak-anchorage\", \"320 W 5th Ave\", \"Anchorage\", \"AK\", \"99501\", \"Anchorage\", 61.218, -149.894),\n row(\n \"az-phoenix\",\n \"1625 N Central Ave\",\n \"Phoenix\",\n \"AZ\",\n \"85004\",\n \"Maricopa County\",\n 33.4665,\n -112.0738,\n ),\n row(\n \"az-phoenix-2\",\n \"501 N 5th St\",\n \"Phoenix\",\n \"AZ\",\n \"85004\",\n \"Maricopa County\",\n 33.454,\n -112.066,\n ),\n row(\n \"az-gilbert\",\n \"420 E Stonebridge Dr\",\n \"Gilbert\",\n \"AZ\",\n \"85234\",\n \"Maricopa County\",\n 33.37,\n -111.783,\n ),\n row(\n \"ar-little-rock\",\n \"500 President Clinton Ave\",\n \"Little Rock\",\n \"AR\",\n \"72201\",\n \"Pulaski County\",\n 34.747,\n -92.265,\n ),\n row(\n \"ca-alturas\",\n \"712 Western Street\",\n \"Alturas\",\n \"CA\",\n \"96101\",\n \"Modoc County\",\n 41.487,\n -120.542,\n ),\n row(\n \"ca-los-angeles\",\n \"200 N Spring St\",\n \"Los Angeles\",\n \"CA\",\n \"90012\",\n \"Los Angeles County\",\n 34.0537,\n -118.2427,\n ),\n row(\"co-denver\", \"1437 Bannock St\", \"Denver\", \"CO\", \"80202\", \"Denver County\", 39.7392, -104.9903),\n row(\n \"ct-hartford\",\n \"550 Main St\",\n \"Hartford\",\n \"CT\",\n \"06103\",\n \"Hartford County\",\n 41.7637,\n -72.6851,\n ),\n row(\n \"dc-washington\",\n \"1350 Pennsylvania Ave NW\",\n \"Washington\",\n \"DC\",\n \"20001\",\n \"District of Columbia\",\n 38.8951,\n -77.031,\n ),\n row(\n \"de-wilmington\",\n \"800 N French St\",\n \"Wilmington\",\n \"DE\",\n \"19801\",\n \"New Castle County\",\n 39.7447,\n -75.5484,\n ),\n row(\n \"fl-miami\",\n \"3500 Pan American Dr\",\n \"Miami\",\n \"FL\",\n \"33130\",\n \"Miami-Dade County\",\n 25.728,\n -80.233,\n ),\n row(\"ga-atlanta\", \"55 Trinity Ave SW\", \"Atlanta\", \"GA\", \"30303\", \"Fulton County\", 33.749, -84.39),\n row(\n \"hi-honolulu\",\n \"530 S King St\",\n \"Honolulu\",\n \"HI\",\n \"96813\",\n \"Honolulu County\",\n 21.3069,\n -157.8583,\n ),\n row(\"id-boise\", \"150 N Capitol Blvd\", \"Boise\", \"ID\", \"83702\", \"Ada County\", 43.615, -116.2023),\n row(\"il-chicago\", \"121 N LaSalle St\", \"Chicago\", \"IL\", \"60601\", \"Cook County\", 41.8837, -87.6323),\n row(\n \"in-newburgh\",\n \"5366 E Sherwood Dr\",\n \"Newburgh\",\n \"IN\",\n \"47630\",\n \"Warrick County\",\n 37.9445,\n -87.4053,\n ),\n row(\n \"in-indianapolis\",\n \"200 E Washington St\",\n \"Indianapolis\",\n \"IN\",\n \"46204\",\n \"Marion County\",\n 39.767,\n -86.155,\n ),\n row(\n \"ia-des-moines\",\n \"400 Robert D Ray Dr\",\n \"Des Moines\",\n \"IA\",\n \"50309\",\n \"Polk County\",\n 41.5868,\n -93.625,\n ),\n row(\"ks-wichita\", \"455 N Main St\", \"Wichita\", \"KS\", \"67202\", \"Sedgwick County\", 37.6872, -97.339),\n row(\n \"ky-louisville\",\n \"527 W Jefferson St\",\n \"Louisville\",\n \"KY\",\n \"40202\",\n \"Jefferson County\",\n 38.2542,\n -85.7594,\n ),\n row(\n \"la-new-orleans\",\n \"1300 Perdido St\",\n \"New Orleans\",\n \"LA\",\n \"70112\",\n \"Orleans Parish\",\n 29.9511,\n -90.0715,\n ),\n row(\n \"me-portland\",\n \"389 Congress St\",\n \"Portland\",\n \"ME\",\n \"04101\",\n \"Cumberland County\",\n 43.6591,\n -70.2568,\n ),\n row(\n \"md-baltimore\",\n \"100 Holliday St\",\n \"Baltimore\",\n \"MD\",\n \"21201\",\n \"Baltimore City\",\n 39.2904,\n -76.6122,\n ),\n row(\n \"ma-boston\",\n \"1 City Hall Square\",\n \"Boston\",\n \"MA\",\n \"02108\",\n \"Suffolk County\",\n 42.3601,\n -71.0589,\n ),\n row(\"mi-detroit\", \"2 Woodward Ave\", \"Detroit\", \"MI\", \"48226\", \"Wayne County\", 42.3292, -83.044),\n row(\n \"mn-minneapolis\",\n \"350 S 5th St\",\n \"Minneapolis\",\n \"MN\",\n \"55415\",\n \"Hennepin County\",\n 44.9778,\n -93.265,\n ),\n row(\n \"ms-jackson\",\n \"219 S President St\",\n \"Jackson\",\n \"MS\",\n \"39201\",\n \"Hinds County\",\n 32.2988,\n -90.1848,\n ),\n row(\n \"mo-kansas-city\",\n \"414 E 12th St\",\n \"Kansas City\",\n \"MO\",\n \"64106\",\n \"Jackson County\",\n 39.0997,\n -94.5786,\n ),\n row(\n \"mt-billings\",\n \"210 N 27th St\",\n \"Billings\",\n \"MT\",\n \"59101\",\n \"Yellowstone County\",\n 45.7833,\n -108.5007,\n ),\n row(\"ne-omaha\", \"1819 Farnam St\", \"Omaha\", \"NE\", \"68102\", \"Douglas County\", 41.2587, -95.9378),\n row(\n \"nv-las-vegas\",\n \"495 S Main St\",\n \"Las Vegas\",\n \"NV\",\n \"89101\",\n \"Clark County\",\n 36.1672,\n -115.1485,\n ),\n row(\n \"nh-manchester\",\n \"1 City Hall Plaza\",\n \"Manchester\",\n \"NH\",\n \"03101\",\n \"Hillsborough County\",\n 42.9956,\n -71.4548,\n ),\n row(\"nj-hoboken\", \"1 Hudson Pl\", \"Hoboken\", \"NJ\", \"07030\", \"Hudson County\", 40.7359, -74.0275),\n row(\n \"nm-albuquerque\",\n \"1 Civic Plaza NW\",\n \"Albuquerque\",\n \"NM\",\n \"87102\",\n \"Bernalillo County\",\n 35.0853,\n -106.651,\n ),\n row(\n \"ny-port-washington\",\n \"136 Murray Avenue\",\n \"Port Washington\",\n \"NY\",\n \"11050\",\n \"Nassau County\",\n 40.8257,\n -73.6982,\n ),\n row(\n \"ny-manhattan\",\n \"88 Greenwich St\",\n \"New York\",\n \"NY\",\n \"10006\",\n \"New York County\",\n 40.7077,\n -74.0137,\n ),\n row(\n \"nc-charlotte\",\n \"600 E 4th St\",\n \"Charlotte\",\n \"NC\",\n \"28202\",\n \"Mecklenburg County\",\n 35.221,\n -80.839,\n ),\n row(\"nd-fargo\", \"225 4th St N\", \"Fargo\", \"ND\", \"58102\", \"Cass County\", 46.8772, -96.7898),\n row(\n \"oh-columbus\",\n \"90 W Broad St\",\n \"Columbus\",\n \"OH\",\n \"43215\",\n \"Franklin County\",\n 39.9612,\n -83.0007,\n ),\n row(\n \"ok-oklahoma-city\",\n \"200 N Walker Ave\",\n \"Oklahoma City\",\n \"OK\",\n \"73102\",\n \"Oklahoma County\",\n 35.4689,\n -97.5195,\n ),\n row(\n \"or-portland\",\n \"1221 SW 4th Ave\",\n \"Portland\",\n \"OR\",\n \"97204\",\n \"Multnomah County\",\n 45.5152,\n -122.6784,\n ),\n row(\n \"pa-east-berlin\",\n \"100 W King St\",\n \"East Berlin\",\n \"PA\",\n \"17316\",\n \"Adams County\",\n 39.9376,\n -76.9786,\n ),\n row(\n \"pa-philadelphia\",\n \"1401 John F Kennedy Blvd\",\n \"Philadelphia\",\n \"PA\",\n \"19107\",\n \"Philadelphia County\",\n 39.9535,\n -75.1636,\n ),\n row(\n \"ri-providence\",\n \"1 Park Row\",\n \"Providence\",\n \"RI\",\n \"02903\",\n \"Providence County\",\n 41.824,\n -71.4128,\n ),\n row(\n \"sc-columbia\",\n \"1737 Main St\",\n \"Columbia\",\n \"SC\",\n \"29201\",\n \"Richland County\",\n 34.0007,\n -81.0348,\n ),\n row(\n \"sd-sioux-falls\",\n \"224 W 9th St\",\n \"Sioux Falls\",\n \"SD\",\n \"57104\",\n \"Minnehaha County\",\n 43.5446,\n -96.7311,\n ),\n row(\n \"tn-nashville\",\n \"1 Public Square\",\n \"Nashville\",\n \"TN\",\n \"37219\",\n \"Davidson County\",\n 36.1667,\n -86.7784,\n ),\n row(\"tx-plano\", \"2601 Preston Rd\", \"Frisco\", \"TX\", \"75034\", \"Collin County\", 33.1507, -96.8236),\n row(\"tx-houston\", \"901 Bagby St\", \"Houston\", \"TX\", \"77002\", \"Harris County\", 29.7604, -95.3698),\n row(\n \"ut-salt-lake\",\n \"451 S State St\",\n \"Salt Lake City\",\n \"UT\",\n \"84111\",\n \"Salt Lake County\",\n 40.7608,\n -111.891,\n ),\n row(\n \"vt-burlington\",\n \"149 Church St\",\n \"Burlington\",\n \"VT\",\n \"05401\",\n \"Chittenden County\",\n 44.4759,\n -73.2121,\n ),\n row(\n \"va-richmond\",\n \"900 E Broad St\",\n \"Richmond\",\n \"VA\",\n \"23219\",\n \"Richmond City\",\n 37.5407,\n -77.436,\n ),\n row(\"wa-seattle\", \"600 4th Ave\", \"Seattle\", \"WA\", \"98104\", \"King County\", 47.6036, -122.3294),\n row(\n \"wv-charleston\",\n \"501 Virginia St E\",\n \"Charleston\",\n \"WV\",\n \"25301\",\n \"Kanawha County\",\n 38.3498,\n -81.6326,\n ),\n row(\n \"wi-scandinavia\",\n \"N7145 Rosholt Road\",\n \"Scandinavia\",\n \"WI\",\n \"54977\",\n \"Waupaca County\",\n 44.46,\n -89.146,\n ),\n row(\n \"wi-milwaukee\",\n \"200 E Wells St\",\n \"Milwaukee\",\n \"WI\",\n \"53202\",\n \"Milwaukee County\",\n 43.0418,\n -87.9097,\n ),\n row(\n \"wy-cheyenne\",\n \"2101 O Neil Ave\",\n \"Cheyenne\",\n \"WY\",\n \"82001\",\n \"Laramie County\",\n 41.14,\n -104.8202,\n ),\n]\n\n/** The Phoenix AZ at-home demo member (`ADDRESS_AT_HOME_PHLEBOTOMY`). */\nexport const PHOENIX_DEMO_ADDRESS = DEFAULT_CORPUS.find(\n (a) => a.id === \"az-phoenix\",\n) as CorpusAddress\n\nexport const STATE_NAMES: Readonly<Record<string, string>> = {\n AL: \"Alabama\",\n AK: \"Alaska\",\n AZ: \"Arizona\",\n AR: \"Arkansas\",\n CA: \"California\",\n CO: \"Colorado\",\n CT: \"Connecticut\",\n DC: \"District of Columbia\",\n DE: \"Delaware\",\n FL: \"Florida\",\n GA: \"Georgia\",\n HI: \"Hawaii\",\n ID: \"Idaho\",\n IL: \"Illinois\",\n IN: \"Indiana\",\n IA: \"Iowa\",\n KS: \"Kansas\",\n KY: \"Kentucky\",\n LA: \"Louisiana\",\n ME: \"Maine\",\n MD: \"Maryland\",\n MA: \"Massachusetts\",\n MI: \"Michigan\",\n MN: \"Minnesota\",\n MS: \"Mississippi\",\n MO: \"Missouri\",\n MT: \"Montana\",\n NE: \"Nebraska\",\n NV: \"Nevada\",\n NH: \"New Hampshire\",\n NJ: \"New Jersey\",\n NM: \"New Mexico\",\n NY: \"New York\",\n NC: \"North Carolina\",\n ND: \"North Dakota\",\n OH: \"Ohio\",\n OK: \"Oklahoma\",\n OR: \"Oregon\",\n PA: \"Pennsylvania\",\n RI: \"Rhode Island\",\n SC: \"South Carolina\",\n SD: \"South Dakota\",\n TN: \"Tennessee\",\n TX: \"Texas\",\n UT: \"Utah\",\n VT: \"Vermont\",\n VA: \"Virginia\",\n WA: \"Washington\",\n WV: \"West Virginia\",\n WI: \"Wisconsin\",\n WY: \"Wyoming\",\n}\n", "import { fromBase64, opaqueToken, toBase64 } from \"@crvouga/mockingbird-service\"\nimport { type CorpusAddress, STATE_NAMES } from \"./corpus.js\"\n\n/**\n * Address resolution over the corpus, in Google's response shapes.\n *\n * Every answer is a pure function of the request and the namespace's corpus, so two instances\n * always agree. Addresses the corpus does not hold but whose city (and state/ZIP) it does are\n * *synthesized*: QA types `\"<fuzzed number and street> <corpus city>\"`, and the mock answers\n * with that street in the corpus row's city, state and ZIP. A synthesized place id carries the\n * whole address (`Ei\u2026`, as Google's own address-only place ids carry theirs), so Place Details\n * resolves it without any stored state.\n */\n\n/** One resolvable place: a corpus row, a synthesized street address, or a ZIP centroid. */\nexport type Place = {\n placeId: string\n kind: \"street_address\" | \"postal_code\"\n line1: string\n city: string\n state: string\n zip: string\n county: string\n lat: number\n lng: number\n}\n\nexport type AddressComponent = { long_name: string; short_name: string; types: string[] }\nexport type Prediction = {\n description: string\n matched_substrings: { length: number; offset: number }[]\n place_id: string\n reference: string\n structured_formatting: {\n main_text: string\n main_text_matched_substrings: { length: number; offset: number }[]\n secondary_text: string\n }\n terms: { offset: number; value: string }[]\n types: string[]\n}\n\nconst MAX_PREDICTIONS = 5\n\nexport const normalize = (value: string): string =>\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .trim()\n\nconst base64url = (value: string) =>\n toBase64(new TextEncoder().encode(value))\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\")\nconst fromBase64url = (value: string): string | undefined => {\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(\n fromBase64(value.replace(/-/g, \"+\").replace(/_/g, \"/\")),\n )\n } catch {\n return undefined\n }\n}\n\n/** The stable place id of a corpus row. */\nexport const corpusPlaceId = (row: Pick<CorpusAddress, \"id\">): string =>\n `ChIJ${opaqueToken(`gmaps:${row.id}`, 23)}`\n\nconst postalPlaceId = (zip: string): string => `ChIJ${opaqueToken(`gmaps:zip:${zip}`, 23)}`\n\nconst fromRow = (row: CorpusAddress): Place => ({\n placeId: corpusPlaceId(row),\n kind: \"street_address\",\n line1: row.line1,\n city: row.city,\n state: row.state,\n zip: row.zip,\n county: row.county,\n lat: row.lat,\n lng: row.lng,\n})\n\n/** A deterministic offset (\u00B10.009\u00B0) so synthesized addresses do not all sit on one point. */\nconst jitter = (seed: string, axis: string): number => {\n const token = opaqueToken(`gmaps:jitter:${axis}:${seed}`, 4)\n let n = 0\n for (const char of token) n = (n * 31 + char.charCodeAt(0)) % 1800\n return (n - 900) / 100_000\n}\n\nconst round = (value: number) => Math.round(value * 1e7) / 1e7\n\ntype SynthPayload = { l: string; c: string; s: string; z: string; n: string; a: number; o: number }\n\n/** A street address the corpus does not hold, in a corpus row's city. */\nexport const synthesize = (line1: string, row: CorpusAddress): Place => {\n const payload: SynthPayload = {\n l: line1,\n c: row.city,\n s: row.state,\n z: row.zip,\n n: row.county,\n a: round(row.lat + jitter(line1, \"lat\")),\n o: round(row.lng + jitter(line1, \"lng\")),\n }\n return {\n placeId: `Ei${base64url(JSON.stringify(payload))}`,\n kind: \"street_address\",\n line1,\n city: row.city,\n state: row.state,\n zip: row.zip,\n county: row.county,\n lat: payload.a,\n lng: payload.o,\n }\n}\n\nconst postalPlace = (row: CorpusAddress): Place => ({\n placeId: postalPlaceId(row.zip),\n kind: \"postal_code\",\n line1: \"\",\n city: row.city,\n state: row.state,\n zip: row.zip,\n county: row.county,\n lat: row.lat,\n lng: row.lng,\n})\n\n/** Resolve a place id minted by this mock (corpus row, synthesized address, ZIP centroid). */\nexport const placeById = (placeId: string, rows: readonly CorpusAddress[]): Place | undefined => {\n if (placeId.startsWith(\"Ei\")) {\n const decoded = fromBase64url(placeId.slice(2))\n if (decoded === undefined) return undefined\n try {\n const p = JSON.parse(decoded) as Partial<SynthPayload>\n if (\n typeof p.l !== \"string\" ||\n typeof p.c !== \"string\" ||\n typeof p.s !== \"string\" ||\n typeof p.z !== \"string\" ||\n typeof p.a !== \"number\" ||\n typeof p.o !== \"number\"\n ) {\n return undefined\n }\n return {\n placeId,\n kind: \"street_address\",\n line1: p.l,\n city: p.c,\n state: p.s,\n zip: p.z,\n county: typeof p.n === \"string\" ? p.n : \"\",\n lat: p.a,\n lng: p.o,\n }\n } catch {\n return undefined\n }\n }\n for (const row of rows) {\n if (corpusPlaceId(row) === placeId) return fromRow(row)\n if (postalPlaceId(row.zip) === placeId) return postalPlace(row)\n }\n return undefined\n}\n\nconst STREET_NUMBER = /^([A-Za-z]?\\d+[A-Za-z]?(?:-\\d+)?)\\s+(.+)$/\n\n/** Split `line1` into Google's street_number and route. */\nconst splitStreet = (line1: string): { number: string | undefined; route: string } => {\n const match = STREET_NUMBER.exec(line1.trim())\n return match\n ? { number: match[1] as string, route: (match[2] as string).trim() }\n : { number: undefined, route: line1.trim() }\n}\n\nexport const addressComponents = (place: Place): AddressComponent[] => {\n const out: AddressComponent[] = []\n if (place.kind === \"street_address\") {\n const { number, route } = splitStreet(place.line1)\n if (number) out.push({ long_name: number, short_name: number, types: [\"street_number\"] })\n out.push({ long_name: route, short_name: route, types: [\"route\"] })\n } else {\n out.push({ long_name: place.zip, short_name: place.zip, types: [\"postal_code\"] })\n }\n out.push({ long_name: place.city, short_name: place.city, types: [\"locality\", \"political\"] })\n if (place.county) {\n out.push({\n long_name: place.county,\n short_name: place.county,\n types: [\"administrative_area_level_2\", \"political\"],\n })\n }\n out.push({\n long_name: STATE_NAMES[place.state] ?? place.state,\n short_name: place.state,\n types: [\"administrative_area_level_1\", \"political\"],\n })\n out.push({ long_name: \"United States\", short_name: \"US\", types: [\"country\", \"political\"] })\n if (place.kind === \"street_address\") {\n out.push({ long_name: place.zip, short_name: place.zip, types: [\"postal_code\"] })\n }\n return out\n}\n\nexport const formattedAddress = (place: Place): string =>\n place.kind === \"street_address\"\n ? `${place.line1}, ${place.city}, ${place.state} ${place.zip}, USA`\n : `${place.city}, ${place.state} ${place.zip}, USA`\n\nexport const geometry = (place: Place, withType = false) => {\n const span = place.kind === \"street_address\" ? 0.00135 : 0.02\n return {\n location: { lat: place.lat, lng: place.lng },\n ...(withType\n ? { location_type: place.kind === \"street_address\" ? \"ROOFTOP\" : \"APPROXIMATE\" }\n : {}),\n viewport: {\n northeast: { lat: round(place.lat + span), lng: round(place.lng + span) },\n southwest: { lat: round(place.lat - span), lng: round(place.lng - span) },\n },\n }\n}\n\nconst placeTypes = (place: Place) =>\n place.kind === \"street_address\" ? [\"street_address\"] : [\"postal_code\"]\n\n/** Every Place Details field, keyed by the `fields` names Google accepts. */\nexport const placeResult = (place: Place): Record<string, unknown> => ({\n address_components: addressComponents(place),\n adr_address:\n place.kind === \"street_address\"\n ? `<span class=\"street-address\">${place.line1}</span>, <span class=\"locality\">${place.city}</span>, <span class=\"region\">${place.state}</span> <span class=\"postal-code\">${place.zip}</span>, <span class=\"country-name\">USA</span>`\n : `<span class=\"locality\">${place.city}</span>, <span class=\"region\">${place.state}</span> <span class=\"postal-code\">${place.zip}</span>, <span class=\"country-name\">USA</span>`,\n formatted_address: formattedAddress(place),\n geometry: geometry(place),\n name: place.kind === \"street_address\" ? place.line1 : place.zip,\n place_id: place.placeId,\n reference: place.placeId,\n types: placeTypes(place),\n url: `https://maps.google.com/?q=${encodeURIComponent(formattedAddress(place))}`,\n utc_offset: 0,\n vicinity: place.city,\n})\n\n/** Google's field names (and the JS API's plural spellings) to result keys. */\nconst FIELD_ALIASES: Record<string, string> = {\n address_component: \"address_components\",\n address_components: \"address_components\",\n adr_address: \"adr_address\",\n formatted_address: \"formatted_address\",\n geometry: \"geometry\",\n \"geometry/location\": \"geometry\",\n \"geometry/viewport\": \"geometry\",\n name: \"name\",\n place_id: \"place_id\",\n reference: \"reference\",\n type: \"types\",\n types: \"types\",\n url: \"url\",\n utc_offset: \"utc_offset\",\n vicinity: \"vicinity\",\n}\n\n/** Only the requested fields (`fields=address_component,geometry`); every field when absent. */\nexport const pickFields = (\n result: Record<string, unknown>,\n fields: string | undefined,\n fallback: readonly string[] | \"all\",\n): Record<string, unknown> => {\n const requested = (fields ?? \"\")\n .split(\",\")\n .map((f) => f.trim())\n .filter(Boolean)\n if (requested.length === 0) {\n if (fallback === \"all\") return result\n return Object.fromEntries(fallback.map((key) => [key, result[key]]))\n }\n if (requested.includes(\"*\")) return result\n const keys = new Set(requested.map((f) => FIELD_ALIASES[f]).filter((k): k is string => !!k))\n return Object.fromEntries(Object.entries(result).filter(([key]) => keys.has(key)))\n}\n\n/** Whether every field named in `fields` is one Google knows (unknown ones are INVALID_REQUEST). */\nexport const unknownFields = (fields: string | undefined): string[] =>\n (fields ?? \"\")\n .split(\",\")\n .map((f) => f.trim())\n .filter((f) => f && f !== \"*\" && !(f in FIELD_ALIASES))\n\nconst secondary = (place: Place) => `${place.city}, ${place.state}, USA`\n\nexport const prediction = (place: Place, input: string): Prediction => {\n const main = place.kind === \"street_address\" ? place.line1 : place.zip\n const second = secondary(place)\n const description = `${main}, ${second}`\n const matched = Math.min(input.trim().length, main.length)\n const terms: { offset: number; value: string }[] = []\n let offset = 0\n for (const value of [main, place.city, place.state, \"USA\"]) {\n terms.push({ offset, value })\n offset += value.length + 2\n }\n return {\n description,\n matched_substrings: [{ length: matched, offset: 0 }],\n place_id: place.placeId,\n reference: place.placeId,\n structured_formatting: {\n main_text: main,\n main_text_matched_substrings: [{ length: matched, offset: 0 }],\n secondary_text: second,\n },\n terms,\n types: place.kind === \"street_address\" ? [\"premise\", \"geocode\"] : [\"postal_code\", \"geocode\"],\n }\n}\n\nconst tokens = (value: string) => normalize(value).split(\" \").filter(Boolean)\nconst IGNORED = new Set([\"usa\", \"us\", \"united\", \"states\"])\n\n/** Every input token is a prefix of a distinct haystack token. */\nconst tokensMatch = (input: string[], haystack: string[]): boolean => {\n const used = new Set<number>()\n for (const token of input) {\n const at = haystack.findIndex((h, i) => !used.has(i) && h.startsWith(token))\n if (at < 0) return false\n used.add(at)\n }\n return true\n}\n\nconst rowHaystack = (row: CorpusAddress) =>\n tokens(`${row.line1} ${row.city} ${row.state} ${STATE_NAMES[row.state] ?? \"\"} ${row.zip}`)\n\n/**\n * `\"<number> <street\u2026> <city>[ <ST>][ <zip>]\"` where the city is a corpus city: the street and\n * the row it lands in. Comma-separated input (`\"<line1>, <city>, <ST> <zip>\"`) works too.\n */\nexport const parseStreetInCity = (\n input: string,\n rows: readonly CorpusAddress[],\n): { line1: string; row: CorpusAddress } | undefined => {\n const trimmed = input.trim().replace(/[,\\s]+(USA|US|United States)$/i, \"\")\n const match = STREET_NUMBER.exec(trimmed)\n if (!match) return undefined\n const number = match[1] as string\n const rest = (match[2] as string).replace(/,/g, \" \").replace(/\\s+/g, \" \").trim()\n const restNorm = normalize(rest)\n // Longest city first, so \"New York\" beats \"York\".\n const candidates = [...rows].sort((a, b) => b.city.length - a.city.length)\n for (const row of candidates) {\n const city = normalize(row.city)\n const suffixes = [\n `${city} ${row.state.toLowerCase()} ${row.zip}`,\n `${city} ${row.state.toLowerCase()}`,\n `${city} ${row.zip}`,\n city,\n ]\n for (const suffix of suffixes) {\n if (!restNorm.endsWith(` ${suffix}`)) continue\n const streetNorm = restNorm.slice(0, restNorm.length - suffix.length).trim()\n if (!streetNorm) continue\n // Recover the street in the caller's casing: the words before the city.\n const words = rest.split(\" \")\n const streetWords = words.slice(0, streetNorm.split(\" \").length)\n const street = streetWords.join(\" \").replace(/[,\\s]+$/, \"\")\n return { line1: `${number} ${street}`, row }\n }\n }\n return undefined\n}\n\n/** Place Autocomplete over the corpus: synthesized first, then matching rows. */\nexport const autocomplete = (input: string, rows: readonly CorpusAddress[]): Place[] => {\n const wanted = tokens(input).filter((t) => !IGNORED.has(t))\n if (wanted.length === 0) return []\n const out: Place[] = []\n const synth = parseStreetInCity(input, rows)\n if (synth) {\n const exact = rows.find(\n (row) =>\n normalize(row.line1) === normalize(synth.line1) &&\n normalize(row.city) === normalize(synth.row.city),\n )\n out.push(exact ? fromRow(exact) : synthesize(synth.line1, synth.row))\n }\n for (const row of rows) {\n if (out.length >= MAX_PREDICTIONS) break\n if (out.some((p) => p.placeId === corpusPlaceId(row))) continue\n if (tokensMatch(wanted, rowHaystack(row))) out.push(fromRow(row))\n }\n return out\n}\n\n/**\n * Geocoding: a full address resolves to its corpus row or a synthesized address; a bare ZIP\n * or `\"<city>, <ST>\"` resolves to the ZIP centroid. A street with no locatable city is none.\n */\nexport const geocode = (address: string, rows: readonly CorpusAddress[]): Place | undefined => {\n const n = normalize(address)\n if (!n) return undefined\n const synth = parseStreetInCity(address, rows)\n if (synth) {\n const exact = rows.find(\n (row) =>\n normalize(row.line1) === normalize(synth.line1) &&\n normalize(row.city) === normalize(synth.row.city),\n )\n return exact ? fromRow(exact) : synthesize(synth.line1, synth.row)\n }\n const wanted = tokens(address).filter((t) => !IGNORED.has(t))\n if (wanted.length === 1 && /^\\d{5}$/.test(wanted[0] as string)) {\n const row = rows.find((r) => r.zip === wanted[0])\n return row ? postalPlace(row) : undefined\n }\n if (!/\\d/.test(n)) {\n const row = rows.find((r) => {\n const city = tokens(r.city)\n return (\n wanted.length >= city.length &&\n city.every((t, i) => wanted[i] === t) &&\n wanted.slice(city.length).every((t) => t === r.state.toLowerCase())\n )\n })\n return row ? postalPlace(row) : undefined\n }\n return undefined\n}\n\n/** Find Place From Text: geocoding first, then the looser autocomplete match. */\nexport const findPlace = (input: string, rows: readonly CorpusAddress[]): Place | undefined =>\n geocode(input, rows) ?? autocomplete(input, rows)[0]\n", "/**\n * The Maps JavaScript API shim served at `GET /maps/api/js`: `google.maps.places.*` and\n * `google.maps.Geocoder`, backed by this mock's own REST endpoints (same corpus, same faults,\n * same namespace), in the callback shapes and status enums the real script uses.\n */\nexport type ShimOptions = {\n /** Origin (plus any `/ns/<name>` prefix) the shim's `fetch` calls go to. */\n base: string\n key: string\n /** The key was refused: the shim calls `window.gm_authFailure()` once loaded. */\n authFailed: boolean\n /** `&callback=` from the script URL, called once `google.maps` is ready. */\n callback: string | null\n}\n\n/** JSON embedded in a `<script>` body, with `<` escaped so `</script>` cannot close it. */\nconst embed = (value: unknown) => JSON.stringify(value).replace(/</g, \"\\\\u003c\")\n\nexport const mapsJavaScript = (\n options: ShimOptions,\n): string => `/* Mockingbird Google Maps JavaScript API shim (places, geocoder) */\n(function () {\n var BASE = ${embed(options.base)};\n var KEY = ${embed(options.key)};\n var AUTH_FAILED = ${options.authFailed ? \"true\" : \"false\"};\n var CALLBACK = ${embed(options.callback)};\n var w = typeof window !== \"undefined\" ? window : globalThis;\n var doFetch = (w.fetch && w.fetch.bind(w)) || fetch;\n\n function request(path, params) {\n var parts = [];\n for (var name in params) {\n var value = params[name];\n if (value === undefined || value === null || value === \"\") continue;\n parts.push(encodeURIComponent(name) + \"=\" + encodeURIComponent(String(value)));\n }\n parts.push(\"key=\" + encodeURIComponent(KEY));\n return doFetch(BASE + path + \"?\" + parts.join(\"&\")).then(\n function (response) {\n if (!response.ok) return { status: \"UNKNOWN_ERROR\" };\n return response.json().then(null, function () { return { status: \"UNKNOWN_ERROR\" }; });\n },\n function () { return { status: \"UNKNOWN_ERROR\" }; }\n );\n }\n\n function LatLng(lat, lng) { this._lat = Number(lat); this._lng = Number(lng); }\n LatLng.prototype.lat = function () { return this._lat; };\n LatLng.prototype.lng = function () { return this._lng; };\n LatLng.prototype.toJSON = function () { return { lat: this._lat, lng: this._lng }; };\n LatLng.prototype.toString = function () { return \"(\" + this._lat + \", \" + this._lng + \")\"; };\n LatLng.prototype.equals = function (other) { return !!other && other.lat() === this._lat && other.lng() === this._lng; };\n\n function LatLngBounds(sw, ne) { this._sw = sw; this._ne = ne; }\n LatLngBounds.prototype.getSouthWest = function () { return this._sw; };\n LatLngBounds.prototype.getNorthEast = function () { return this._ne; };\n LatLngBounds.prototype.toJSON = function () {\n return { south: this._sw.lat(), west: this._sw.lng(), north: this._ne.lat(), east: this._ne.lng() };\n };\n\n function wrapGeometry(g) {\n if (!g || !g.location) return g;\n var out = { location: new LatLng(g.location.lat, g.location.lng) };\n if (g.location_type) out.location_type = g.location_type;\n if (g.viewport) {\n out.viewport = new LatLngBounds(\n new LatLng(g.viewport.southwest.lat, g.viewport.southwest.lng),\n new LatLng(g.viewport.northeast.lat, g.viewport.northeast.lng)\n );\n }\n return out;\n }\n\n function wrapPlace(p) {\n if (!p) return p;\n var out = {};\n for (var k in p) out[k] = p[k];\n if (p.geometry) out.geometry = wrapGeometry(p.geometry);\n return out;\n }\n\n var PlacesServiceStatus = {\n OK: \"OK\", ZERO_RESULTS: \"ZERO_RESULTS\", INVALID_REQUEST: \"INVALID_REQUEST\",\n OVER_QUERY_LIMIT: \"OVER_QUERY_LIMIT\", REQUEST_DENIED: \"REQUEST_DENIED\",\n UNKNOWN_ERROR: \"UNKNOWN_ERROR\", NOT_FOUND: \"NOT_FOUND\"\n };\n var GeocoderStatus = {\n OK: \"OK\", ZERO_RESULTS: \"ZERO_RESULTS\", INVALID_REQUEST: \"INVALID_REQUEST\",\n OVER_QUERY_LIMIT: \"OVER_QUERY_LIMIT\", REQUEST_DENIED: \"REQUEST_DENIED\",\n UNKNOWN_ERROR: \"UNKNOWN_ERROR\", ERROR: \"ERROR\"\n };\n\n function MapsRequestError(status, endpoint) {\n var error = new Error(endpoint + \": \" + status);\n error.name = \"MapsRequestError\";\n error.code = status;\n error.endpoint = endpoint;\n return error;\n }\n\n /** Call back, or settle the returned promise (rejecting on errors) when there is no callback. */\n function settle(callback, results, status, value, endpoint, okStatuses) {\n if (typeof callback === \"function\") {\n callback(results, status);\n return value;\n }\n if (okStatuses.indexOf(status) < 0) throw MapsRequestError(status, endpoint);\n return value;\n }\n\n var tokenSeq = 0;\n function AutocompleteSessionToken() {\n tokenSeq += 1;\n this._id = \"mbst-\" + tokenSeq + \"-\" + tokenSeq.toString(36).padStart(8, \"0\");\n }\n AutocompleteSessionToken.prototype.toString = function () { return this._id; };\n\n function countries(restrictions) {\n if (!restrictions || !restrictions.country) return undefined;\n var list = [].concat(restrictions.country);\n return list.map(function (c) { return \"country:\" + String(c).toLowerCase(); }).join(\"|\");\n }\n\n function fieldList(fields) {\n if (!fields) return undefined;\n return [].concat(fields).join(\",\");\n }\n\n function AutocompleteService() {}\n AutocompleteService.prototype.getPlacePredictions = function (req, callback) {\n req = req || {};\n return request(\"/maps/api/place/autocomplete/json\", {\n input: req.input,\n sessiontoken: req.sessionToken ? String(req.sessionToken) : undefined,\n types: req.types ? [].concat(req.types).join(\"|\") : undefined,\n components: countries(req.componentRestrictions)\n }).then(function (data) {\n var status = data.status || \"UNKNOWN_ERROR\";\n var predictions = status === \"OK\" ? data.predictions : null;\n return settle(callback, predictions, status, { predictions: predictions || [] },\n \"PLACES_AUTOCOMPLETE\", [\"OK\", \"ZERO_RESULTS\"]);\n });\n };\n\n function PlacesService(attributions) { this._attributions = attributions || null; }\n PlacesService.prototype.getDetails = function (req, callback) {\n req = req || {};\n return request(\"/maps/api/place/details/json\", {\n place_id: req.placeId,\n fields: fieldList(req.fields),\n sessiontoken: req.sessionToken ? String(req.sessionToken) : undefined\n }).then(function (data) {\n var status = data.status || \"UNKNOWN_ERROR\";\n var place = status === \"OK\" ? wrapPlace(data.result) : null;\n return settle(callback, place, status, place, \"PLACES_GET_PLACE\", [\"OK\"]);\n });\n };\n PlacesService.prototype.findPlaceFromQuery = function (req, callback) {\n req = req || {};\n return request(\"/maps/api/place/findplacefromtext/json\", {\n input: req.query,\n inputtype: \"textquery\",\n fields: fieldList(req.fields)\n }).then(function (data) {\n var status = data.status || \"UNKNOWN_ERROR\";\n var results = status === \"OK\" ? (data.candidates || []).map(wrapPlace) : null;\n return settle(callback, results, status, { results: results || [] },\n \"PLACES_FIND_PLACE_FROM_QUERY\", [\"OK\", \"ZERO_RESULTS\"]);\n });\n };\n\n function Geocoder() {}\n Geocoder.prototype.geocode = function (req, callback) {\n req = req || {};\n return request(\"/maps/api/geocode/json\", {\n address: req.address,\n place_id: req.placeId,\n components: req.componentRestrictions && req.componentRestrictions.postalCode\n ? \"postal_code:\" + req.componentRestrictions.postalCode : undefined\n }).then(function (data) {\n var status = data.status || \"ERROR\";\n var results = status === \"OK\" ? (data.results || []).map(wrapPlace) : null;\n return settle(callback, results, status, { results: results || [] }, \"GEOCODER_GEOCODE\", [\"OK\"]);\n });\n };\n\n w.google = w.google || {};\n w.google.maps = {\n version: \"mockingbird\",\n LatLng: LatLng,\n LatLngBounds: LatLngBounds,\n Geocoder: Geocoder,\n GeocoderStatus: GeocoderStatus,\n places: {\n AutocompleteService: AutocompleteService,\n AutocompleteSessionToken: AutocompleteSessionToken,\n PlacesService: PlacesService,\n PlacesServiceStatus: PlacesServiceStatus\n },\n importLibrary: function (name) {\n if (name === \"places\") return Promise.resolve(w.google.maps.places);\n if (name === \"geocoding\") return Promise.resolve({ Geocoder: Geocoder, GeocoderStatus: GeocoderStatus });\n return Promise.resolve({ LatLng: LatLng, LatLngBounds: LatLngBounds });\n }\n };\n\n if (AUTH_FAILED) {\n setTimeout(function () { if (typeof w.gm_authFailure === \"function\") w.gm_authFailure(); }, 0);\n }\n if (CALLBACK && typeof w[CALLBACK] === \"function\") w[CALLBACK]();\n})();\n`\n", "import { Collection } from \"@crvouga/mockingbird-service\"\nimport type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport { type CorpusAddress, DEFAULT_CORPUS } from \"./corpus.js\"\n\n/** Per-namespace knobs, set through `PUT /__admin/settings`; cleared on reset. */\nexport type Settings = {\n /** Only these API keys are accepted; empty means any non-empty key is. */\n keys: string[]\n /**\n * Origin the Maps JavaScript shim calls back to, when the browser reaches the mock at a\n * different address than the request that loaded the script (a rewriting proxy).\n */\n publicUrl: string | null\n}\n\nexport const DEFAULT_SETTINGS: Settings = { keys: [], publicUrl: null }\n\nexport class GoogleMapsState {\n /** Addresses a suite added to this namespace, on top of the built-in corpus. */\n readonly custom: Collection<CorpusAddress>\n readonly settings: Collection<Settings>\n\n constructor(\n sqlite: SqliteClient,\n namespace: string,\n private readonly seed: { corpus: readonly CorpusAddress[]; settings: Partial<Settings> },\n ) {\n this.custom = new Collection(sqlite, namespace, \"addresses\")\n this.settings = new Collection(sqlite, namespace, \"settings\")\n this.ensureSeeded()\n }\n\n ensureSeeded(): void {\n if (!this.settings.has(\"settings\")) {\n this.settings.insert(\"settings\", { ...DEFAULT_SETTINGS, ...this.seed.settings })\n }\n }\n\n current(): Settings {\n return this.settings.get(\"settings\") ?? DEFAULT_SETTINGS\n }\n\n update(patch: Partial<Settings>): Settings {\n const next = { ...this.current(), ...patch }\n this.settings.insert(\"settings\", next)\n return next\n }\n\n /** Custom rows first (a suite's own addresses win ties), then the built-in corpus. */\n corpus(): CorpusAddress[] {\n const custom = this.custom.list({ order: \"oldest\" }).map((row) => row.value)\n const ids = new Set(custom.map((row) => row.id))\n const base = this.seed.corpus.length > 0 ? this.seed.corpus : DEFAULT_CORPUS\n return [...custom, ...base.filter((row) => !ids.has(row.id))]\n }\n\n replaceCustom(rows: CorpusAddress[]): void {\n for (const { id } of this.custom.list()) this.custom.delete(id)\n for (const row of rows) this.custom.insert(row.id, row)\n }\n}\n", "import { type CorpusAddress, STATE_NAMES } from \"./corpus.js\"\nimport { corpusPlaceId, normalize, parseStreetInCity, synthesize } from \"./places.js\"\n\n/**\n * The Address Validation API (`POST https://addressvalidation.googleapis.com/v1:validateAddress`)\n * over the same corpus as Places and Geocoding.\n *\n * Shapes follow Google's reference: `ValidationResult` (`verdict`, `address`, `geocode`,\n * `uspsData`) and `google.rpc.Status` errors. Google encodes responses as proto3 JSON, so\n * `false` booleans and empty lists are omitted rather than sent.\n *\n * - https://developers.google.com/maps/documentation/address-validation/reference/rest/v1/TopLevel/validateAddress\n * - https://developers.google.com/maps/documentation/address-validation/reference/rest/v1/ValidationResult\n * - https://developers.google.com/maps/documentation/address-validation/understand-response\n *\n * Every answer is a pure function of the request and the namespace's corpus. A street the corpus\n * holds (or one synthesized in a corpus city, as for Autocomplete) is a delivery point: DPV `Y`,\n * with a deterministic ZIP+4. Admin rows can pin any part of the verdict (`validation`).\n */\n\nexport type Granularity =\n | \"SUB_PREMISE\"\n | \"PREMISE\"\n | \"PREMISE_PROXIMITY\"\n | \"BLOCK\"\n | \"ROUTE\"\n | \"OTHER\"\nexport type PossibleNextAction = \"FIX\" | \"CONFIRM_ADD_SUBPREMISES\" | \"CONFIRM\" | \"ACCEPT\"\nexport type DpvConfirmation = \"Y\" | \"N\" | \"S\" | \"D\"\n\nexport const GRANULARITIES: readonly Granularity[] = [\n \"SUB_PREMISE\",\n \"PREMISE\",\n \"PREMISE_PROXIMITY\",\n \"BLOCK\",\n \"ROUTE\",\n \"OTHER\",\n]\nexport const NEXT_ACTIONS: readonly PossibleNextAction[] = [\n \"FIX\",\n \"CONFIRM_ADD_SUBPREMISES\",\n \"CONFIRM\",\n \"ACCEPT\",\n]\nexport const DPV_CODES: readonly DpvConfirmation[] = [\"Y\", \"N\", \"S\", \"D\"]\n\n/** Per-row controls set through `PUT /__admin/corpus`: pin the verdict a test needs. */\nexport type ValidationOverrides = {\n granularity?: Granularity\n addressComplete?: boolean\n possibleNextAction?: PossibleNextAction\n dpvConfirmation?: DpvConfirmation\n unconfirmedComponentTypes?: string[]\n /** USPS refuses the address: `uspsData.errorMessage`, and no DPV code. */\n uspsErrorMessage?: string\n /** An apartment building: a missing unit is `D`, an unknown one `S`. */\n multiUnit?: boolean\n /** The units USPS knows for a `multiUnit` row. Absent: every unit is known. */\n units?: string[]\n}\n\n/** A `google.rpc.Status` error, as Google's API front end sends it. */\nexport type GoogleApiError = {\n code: number\n message: string\n status: string\n details?: Record<string, unknown>[]\n}\n\nexport class ValidationRequestError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"ValidationRequestError\"\n }\n}\n\ntype InputAddress = {\n regionCode: string | undefined\n addressLines: string[]\n locality: string | undefined\n administrativeArea: string | undefined\n postalCode: string | undefined\n}\n\nexport type ValidateRequest = { address: InputAddress; enableUspsCass: boolean }\n\nconst TOP_LEVEL = new Set([\n \"address\",\n \"previousResponseId\",\n \"enableUspsCass\",\n \"languageOptions\",\n \"sessionToken\",\n])\n/** `google.type.PostalAddress` fields (camelCase, as the JSON mapping accepts). */\nconst POSTAL_ADDRESS = new Set([\n \"revision\",\n \"regionCode\",\n \"languageCode\",\n \"postalCode\",\n \"sortingCode\",\n \"administrativeArea\",\n \"locality\",\n \"sublocality\",\n \"addressLines\",\n \"recipients\",\n \"organization\",\n])\nconst MAX_INPUT_LENGTH = 280\n/** Vendored PostalAddress limits: `addressLines` has `maxItems: 3`, items `maxLength: 80`. */\nconst MAX_ADDRESS_LINES = 3\nconst MAX_ADDRESS_LINE_LENGTH = 80\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst optionalString = (value: unknown, field: string): string | undefined => {\n if (value === undefined || value === null) return undefined\n if (typeof value !== \"string\") {\n throw new ValidationRequestError(\n `Invalid value at '${field}' (TYPE_STRING), ${JSON.stringify(value)}`,\n )\n }\n const trimmed = value.trim()\n return trimmed ? trimmed : undefined\n}\n\n/** Parse and check a request body; throws {@link ValidationRequestError} for a 400. */\nexport const parseValidateRequest = (body: unknown): ValidateRequest => {\n if (!isRecord(body)) throw new ValidationRequestError(\"Invalid JSON payload received.\")\n for (const key of Object.keys(body)) {\n if (!TOP_LEVEL.has(key)) {\n throw new ValidationRequestError(\n `Invalid JSON payload received. Unknown name \"${key}\": Cannot find field.`,\n )\n }\n }\n const address = body.address\n if (address === undefined || address === null) {\n throw new ValidationRequestError(\"Address is missing from the request.\")\n }\n if (!isRecord(address)) {\n throw new ValidationRequestError(\n `Invalid value at 'address' (type.googleapis.com/google.type.PostalAddress), ${JSON.stringify(address)}`,\n )\n }\n for (const key of Object.keys(address)) {\n if (!POSTAL_ADDRESS.has(key)) {\n throw new ValidationRequestError(\n `Invalid JSON payload received. Unknown name \"${key}\" at 'address': Cannot find field.`,\n )\n }\n }\n const rawLines = address.addressLines ?? []\n if (!Array.isArray(rawLines) || rawLines.some((line) => typeof line !== \"string\")) {\n throw new ValidationRequestError(\n `Invalid value at 'address.address_lines' (TYPE_STRING), ${JSON.stringify(rawLines)}`,\n )\n }\n // The vendored PostalAddress caps addressLines at 3 items of 80 characters each; the mock\n // echoes the lines into the response, whose schema caps them the same way, so an over-long or\n // over-long-list request is rejected here rather than echoed into a non-conformant response.\n if ((rawLines as string[]).length > MAX_ADDRESS_LINES) {\n throw new ValidationRequestError(\n `Invalid value at 'address.address_lines' (repeated STRING), a maximum of ${MAX_ADDRESS_LINES} address lines is allowed.`,\n )\n }\n const overLong = (rawLines as string[]).findIndex((line) => line.length > MAX_ADDRESS_LINE_LENGTH)\n if (overLong !== -1) {\n throw new ValidationRequestError(\n `Invalid value at 'address.address_lines[${overLong}]' (STRING), the maximum length is ${MAX_ADDRESS_LINE_LENGTH} characters.`,\n )\n }\n const addressLines = (rawLines as string[]).map((line) => line.trim()).filter(Boolean)\n if (addressLines.length === 0) {\n throw new ValidationRequestError(\"Address lines are missing from the request.\")\n }\n const enable = body.enableUspsCass\n if (enable !== undefined && enable !== null && typeof enable !== \"boolean\") {\n throw new ValidationRequestError(\n `Invalid value at 'enable_usps_cass' (TYPE_BOOL), ${JSON.stringify(enable)}`,\n )\n }\n const input: InputAddress = {\n regionCode: optionalString(address.regionCode, \"address.region_code\")?.toUpperCase(),\n addressLines,\n locality: optionalString(address.locality, \"address.locality\"),\n administrativeArea: optionalString(address.administrativeArea, \"address.administrative_area\"),\n postalCode: optionalString(address.postalCode, \"address.postal_code\"),\n }\n const length = [\n ...input.addressLines,\n input.locality ?? \"\",\n input.administrativeArea ?? \"\",\n input.postalCode ?? \"\",\n ].join(\"\").length\n if (length > MAX_INPUT_LENGTH) {\n throw new ValidationRequestError(\n `The total length of the address fields must not exceed ${MAX_INPUT_LENGTH} characters.`,\n )\n }\n const region = input.regionCode ?? \"US\"\n if (enable === true && region !== \"US\" && region !== \"PR\") {\n throw new ValidationRequestError(\n \"USPS CASS validation is only supported for addresses in the US and PR regions.\",\n )\n }\n return { address: input, enableUspsCass: enable === true }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Street parsing\n\n/** USPS Publication 28 suffix and directional abbreviations (the ones the corpus uses). */\nconst ABBREVIATIONS: Record<string, string> = {\n north: \"N\",\n south: \"S\",\n east: \"E\",\n west: \"W\",\n northeast: \"NE\",\n northwest: \"NW\",\n southeast: \"SE\",\n southwest: \"SW\",\n avenue: \"Ave\",\n av: \"Ave\",\n street: \"St\",\n str: \"St\",\n road: \"Rd\",\n drive: \"Dr\",\n boulevard: \"Blvd\",\n lane: \"Ln\",\n parkway: \"Pkwy\",\n place: \"Pl\",\n court: \"Ct\",\n circle: \"Cir\",\n highway: \"Hwy\",\n terrace: \"Ter\",\n square: \"Sq\",\n plaza: \"Plz\",\n trail: \"Trl\",\n way: \"Way\",\n mall: \"Mall\",\n}\nconst DIRECTIONALS = new Set([\"n\", \"s\", \"e\", \"w\", \"ne\", \"nw\", \"se\", \"sw\"])\n\n/** Secondary unit designators to their USPS abbreviation. */\nconst DESIGNATORS: Record<string, string> = {\n apt: \"Apt\",\n apartment: \"Apt\",\n unit: \"Unit\",\n ste: \"Ste\",\n suite: \"Ste\",\n bldg: \"Bldg\",\n building: \"Bldg\",\n fl: \"Fl\",\n floor: \"Fl\",\n rm: \"Rm\",\n room: \"Rm\",\n spc: \"Spc\",\n space: \"Spc\",\n lot: \"Lot\",\n trlr: \"Trlr\",\n \"#\": \"#\",\n}\n\nconst UNIT_AT_END =\n /[\\s,]+(#|apt|apartment|unit|ste|suite|bldg|building|fl|floor|rm|room|spc|space|lot|trlr)\\.?\\s*#?\\s*([A-Za-z0-9-]+)$/i\nconst UNIT_ONLY =\n /^(#|apt|apartment|unit|ste|suite|bldg|building|fl|floor|rm|room|spc|space|lot|trlr)?\\.?\\s*#?\\s*([A-Za-z0-9-]+)$/i\nconst STREET_NUMBER = /^([A-Za-z]?\\d+[A-Za-z]?(?:-\\d+)?)\\s+(.+)$/\n\ntype Unit = { designator: string; value: string }\n\nconst unitText = (unit: Unit) =>\n unit.designator === \"#\" ? `#${unit.value}` : `${unit.designator} ${unit.value}`\n\nconst parseUnit = (designator: string | undefined, value: string): Unit => ({\n designator: DESIGNATORS[(designator ?? \"#\").toLowerCase()] ?? \"#\",\n value: value.toUpperCase(),\n})\n\n/** Split a trailing unit (`\u2026 Apt 4`, `\u2026 Building A`) off a street line. */\nconst splitUnit = (line: string): { street: string; unit: Unit | undefined } => {\n const match = UNIT_AT_END.exec(line)\n if (!match || match.index === 0) return { street: line.trim(), unit: undefined }\n return {\n street: line.slice(0, match.index).trim(),\n unit: parseUnit(match[1], match[2] as string),\n }\n}\n\n/** A street key for matching: lowercase, USPS abbreviations, no punctuation. */\nexport const streetKey = (street: string): string =>\n normalize(street)\n .split(\" \")\n .map((word) => (ABBREVIATIONS[word] ?? word).toLowerCase())\n .join(\" \")\n\n/** USPS-standardize the caller's street spelling, keeping the other words as typed. */\nconst standardizeStreet = (street: string): string =>\n street\n .replace(/[.,]/g, \" \")\n .split(/\\s+/)\n .filter(Boolean)\n .map((word) => {\n const lower = word.toLowerCase()\n if (DIRECTIONALS.has(lower)) return lower.toUpperCase()\n return ABBREVIATIONS[lower] ?? word\n })\n .join(\" \")\n\nconst stateCode = (value: string | undefined): string | undefined => {\n if (!value) return undefined\n const upper = value.trim().toUpperCase()\n if (STATE_NAMES[upper]) return upper\n const byName = Object.entries(STATE_NAMES).find(([, name]) => name.toUpperCase() === upper)\n return byName?.[0] ?? upper\n}\n\n// ---------------------------------------------------------------------------------------------\n// Resolution\n\ntype Resolved = {\n /** The corpus row the address resolved to (for a synthesized street: its city's row). */\n row: CorpusAddress\n /** Output street line, without the unit. */\n street: string | undefined\n number: string | undefined\n route: string\n unit: Unit | undefined\n /** The corpus holds this exact premise (not synthesized). */\n inCorpus: boolean\n postal: \"confirmed\" | \"replaced\" | \"inferred\"\n locality: \"confirmed\" | \"replaced\"\n state: \"confirmed\" | \"replaced\"\n}\n\ntype Unresolved = { street: string; unit: Unit | undefined; hasNumber: boolean }\n\nconst cityRows = (rows: readonly CorpusAddress[], city: string, state: string | undefined) =>\n rows.filter(\n (row) =>\n normalize(row.city) === normalize(city) && (state === undefined || row.state === state),\n )\n\nconst resolve = (\n input: InputAddress,\n rows: readonly CorpusAddress[],\n): { resolved: Resolved } | { unresolved: Unresolved } => {\n const [first = \"\", ...rest] = input.addressLines\n let streetLine = first\n let unit: Unit | undefined\n let locality = input.locality\n let state = stateCode(input.administrativeArea)\n let zip = input.postalCode?.slice(0, 5)\n let candidates: CorpusAddress[] = []\n\n if (locality || zip) {\n // Componentized: line 1 is the street, an optional line 2 the unit.\n const second = rest.join(\" \").trim()\n if (second) {\n const only = UNIT_ONLY.exec(second)\n if (only) unit = parseUnit(only[1], only[2] as string)\n }\n } else {\n // Everything in addressLines: \"<street>, <city>, <ST> <zip>\".\n const joined = input.addressLines.join(\", \")\n const parsed = parseStreetInCity(joined, rows)\n if (parsed) {\n streetLine = parsed.line1\n locality = parsed.row.city\n state = parsed.row.state\n const zipMatch = /\\b(\\d{5})(?:-\\d{4})?\\s*(?:,?\\s*(?:USA|US|United States))?$/i.exec(joined)\n zip = zipMatch?.[1]\n }\n }\n\n const split = splitUnit(streetLine)\n const street = split.street\n unit = unit ?? split.unit\n const numbered = STREET_NUMBER.exec(street)\n\n if (locality) candidates = cityRows(rows, locality, state)\n let localityStatus: Resolved[\"locality\"] = \"confirmed\"\n let stateStatus: Resolved[\"state\"] = \"confirmed\"\n if (candidates.length === 0 && zip) {\n // Google corrects the city (and state) from a ZIP it knows.\n candidates = rows.filter((row) => row.zip === zip)\n if (candidates.length > 0) {\n localityStatus = \"replaced\"\n if (state !== undefined && candidates[0]?.state !== state) stateStatus = \"replaced\"\n }\n }\n if (candidates.length === 0 || !numbered) {\n return { unresolved: { street, unit, hasNumber: !!numbered } }\n }\n\n const number = numbered[1] as string\n const key = streetKey(street)\n const exact = candidates.find((row) => streetKey(row.line1) === key)\n const base =\n exact ??\n candidates.find((row) => zip !== undefined && row.zip === zip) ??\n (candidates[0] as CorpusAddress)\n const outStreet = exact ? exact.line1 : standardizeStreet(street)\n const routeMatch = STREET_NUMBER.exec(outStreet)\n return {\n resolved: {\n row: base,\n street: outStreet,\n number,\n route: routeMatch ? (routeMatch[2] as string) : outStreet,\n unit,\n inCorpus: !!exact,\n postal: zip === undefined ? \"inferred\" : zip === base.zip ? \"confirmed\" : \"replaced\",\n locality: localityStatus,\n state: stateStatus,\n },\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Response\n\n/** A small deterministic hash (FNV-1a), for ZIP+4 digits and response ids. */\nconst fnv = (value: string, seed = 0x811c9dc5): number => {\n let hash = seed >>> 0\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 0x01000193) >>> 0\n }\n return hash\n}\n\nconst zipPlus4 = (row: CorpusAddress, street: string): string =>\n String((fnv(`${row.id}|${streetKey(street)}`) % 9999) + 1).padStart(4, \"0\")\n\n/** A deterministic UUID-shaped `responseId` for a request body. */\nexport const responseId = (seed: string): string => {\n const hex = [0x811c9dc5, 0x01000193, 0x9e3779b9, 0x7f4a7c15]\n .map((s) => fnv(seed, s).toString(16).padStart(8, \"0\"))\n .join(\"\")\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-a${hex.slice(17, 20)}-${hex.slice(20, 32)}`\n}\n\ntype ConfirmationLevel = \"CONFIRMED\" | \"UNCONFIRMED_BUT_PLAUSIBLE\" | \"UNCONFIRMED_AND_SUSPICIOUS\"\n\ntype Component = {\n componentName: { text: string; languageCode?: string }\n componentType: string\n confirmationLevel: ConfirmationLevel\n inferred?: true\n replaced?: true\n}\n\nconst component = (\n text: string,\n componentType: string,\n confirmationLevel: ConfirmationLevel,\n flags: { inferred?: boolean; replaced?: boolean } = {},\n): Component => ({\n componentName: { text, languageCode: \"en\" },\n componentType,\n confirmationLevel,\n ...(flags.inferred ? { inferred: true as const } : {}),\n ...(flags.replaced ? { replaced: true as const } : {}),\n})\n\n/** A short, PII-free label of the answer, for the request journal (`FIX/N`, `ACCEPT/Y`). */\nexport type ValidationOutcome = {\n body: Record<string, unknown>\n /** The corpus row id the address resolved to, if any. */\n rowId: string | undefined\n verdictClass: string\n}\n\nconst compact = <T extends Record<string, unknown>>(value: T): T =>\n Object.fromEntries(\n Object.entries(value).filter(\n ([, v]) => v !== undefined && v !== false && !(Array.isArray(v) && v.length === 0),\n ),\n ) as T\n\nconst uniq = (values: string[]) => [...new Set(values)]\n\n/** Validate one address against the namespace's corpus. */\nexport const validateAddress = (\n request: ValidateRequest,\n rows: readonly CorpusAddress[],\n options: { dpvOverride?: DpvConfirmation } = {},\n): ValidationOutcome => {\n const { address: input, enableUspsCass } = request\n const region = input.regionCode ?? \"US\"\n const usps = region === \"US\" || region === \"PR\"\n const outcome = region === \"US\" ? resolve(input, rows) : undefined\n\n let granularity: Granularity\n let inputGranularity: Granularity\n let addressComplete: boolean\n let nextAction: PossibleNextAction\n let dpv: DpvConfirmation | undefined\n let dpvFootnote: string | undefined\n let unconfirmed: string[] = []\n let missing: string[] = []\n let hasReplaced = false\n let hasInferred = false\n let uspsError: string | undefined\n const components: Component[] = []\n let postalAddress: Record<string, unknown>\n let formattedAddress: string\n let geocode: Record<string, unknown> | undefined\n let standardized: Record<string, unknown> | undefined\n let rowId: string | undefined\n\n if (!outcome || \"unresolved\" in outcome) {\n // Nothing the corpus can place: Google cannot confirm the street or the city.\n const street = outcome && \"unresolved\" in outcome ? outcome.unresolved : undefined\n const hasNumber = street?.hasNumber ?? STREET_NUMBER.test(input.addressLines[0] ?? \"\")\n const unit = street?.unit\n const cityKnown =\n input.locality !== undefined &&\n cityRows(rows, input.locality, stateCode(input.administrativeArea)).length > 0\n inputGranularity = unit ? \"SUB_PREMISE\" : hasNumber ? \"PREMISE\" : \"ROUTE\"\n addressComplete = false\n nextAction = \"FIX\"\n if (cityKnown && !hasNumber) {\n // A known street without a house number (`N Central Ave`, Phoenix): route level.\n granularity = \"ROUTE\"\n missing = [\"street_number\"]\n dpv = undefined\n } else {\n granularity = \"OTHER\"\n dpv = usps ? \"N\" : undefined\n }\n const streetText = street?.street ?? input.addressLines[0] ?? \"\"\n const split = STREET_NUMBER.exec(streetText)\n const routeLevel: ConfirmationLevel = cityKnown\n ? \"UNCONFIRMED_BUT_PLAUSIBLE\"\n : \"UNCONFIRMED_AND_SUSPICIOUS\"\n if (split) {\n components.push(component(split[1] as string, \"street_number\", routeLevel))\n components.push(component(split[2] as string, \"route\", routeLevel))\n } else if (streetText) {\n components.push(\n component(streetText, \"route\", cityKnown ? \"CONFIRMED\" : \"UNCONFIRMED_AND_SUSPICIOUS\"),\n )\n }\n if (unit) components.push(component(unitText(unit), \"subpremise\", routeLevel))\n if (input.locality) {\n components.push(\n component(\n input.locality,\n \"locality\",\n cityKnown ? \"CONFIRMED\" : \"UNCONFIRMED_AND_SUSPICIOUS\",\n ),\n )\n }\n const state = stateCode(input.administrativeArea)\n if (state) {\n components.push(\n component(\n state,\n \"administrative_area_level_1\",\n STATE_NAMES[state] ? \"CONFIRMED\" : \"UNCONFIRMED_AND_SUSPICIOUS\",\n ),\n )\n }\n if (input.postalCode) {\n const zipKnown = rows.some((row) => row.zip === input.postalCode?.slice(0, 5))\n components.push(\n component(\n input.postalCode,\n \"postal_code\",\n zipKnown ? \"CONFIRMED\" : \"UNCONFIRMED_AND_SUSPICIOUS\",\n ),\n )\n }\n components.push(\n component(region === \"US\" ? \"USA\" : region, \"country\", \"CONFIRMED\", {\n inferred: input.regionCode === undefined,\n }),\n )\n hasInferred = input.regionCode === undefined\n unconfirmed = components\n .filter((c) => c.confirmationLevel !== \"CONFIRMED\")\n .map((c) => c.componentType)\n const line = [streetText, unit ? unitText(unit) : \"\"].filter(Boolean).join(\" \")\n postalAddress = compact({\n regionCode: region,\n languageCode: \"en\",\n postalCode: input.postalCode,\n administrativeArea: state,\n locality: input.locality,\n addressLines: line ? [line] : undefined,\n })\n formattedAddress = [\n line,\n input.locality,\n [state, input.postalCode].filter(Boolean).join(\" \"),\n region === \"US\" ? \"USA\" : region,\n ]\n .filter(Boolean)\n .join(\", \")\n } else {\n const r = outcome.resolved\n const row = r.row\n rowId = row.id\n const street = r.street as string\n const validation = row.validation ?? {}\n const plus4 = zipPlus4(row, street)\n inputGranularity = r.unit ? \"SUB_PREMISE\" : \"PREMISE\"\n granularity = \"PREMISE\"\n addressComplete = true\n nextAction = \"ACCEPT\"\n dpv = \"Y\"\n dpvFootnote = \"AABB\"\n let unitLevel: ConfirmationLevel = \"CONFIRMED\"\n\n if (validation.multiUnit) {\n if (!r.unit) {\n missing = [\"subpremise\"]\n addressComplete = false\n nextAction = \"CONFIRM_ADD_SUBPREMISES\"\n dpv = \"D\"\n dpvFootnote = \"AAN1\"\n } else if (\n validation.units === undefined ||\n validation.units.some((u) => u.toUpperCase() === r.unit?.value)\n ) {\n granularity = \"SUB_PREMISE\"\n } else {\n unitLevel = \"UNCONFIRMED_BUT_PLAUSIBLE\"\n nextAction = \"CONFIRM\"\n dpv = \"S\"\n dpvFootnote = \"AACC\"\n }\n } else if (r.unit) {\n // A unit on a single delivery point: USPS delivers without it (footnote CC).\n unitLevel = \"UNCONFIRMED_BUT_PLAUSIBLE\"\n nextAction = \"CONFIRM\"\n dpvFootnote = \"AACC\"\n }\n\n if (r.postal === \"replaced\" || r.locality === \"replaced\" || r.state === \"replaced\") {\n hasReplaced = true\n if (nextAction === \"ACCEPT\") nextAction = \"CONFIRM\"\n }\n\n components.push(component(r.number as string, \"street_number\", \"CONFIRMED\"))\n components.push(component(r.route, \"route\", \"CONFIRMED\"))\n if (r.unit) components.push(component(unitText(r.unit), \"subpremise\", unitLevel))\n components.push(\n component(row.city, \"locality\", \"CONFIRMED\", { replaced: r.locality === \"replaced\" }),\n )\n components.push(\n component(row.state, \"administrative_area_level_1\", \"CONFIRMED\", {\n replaced: r.state === \"replaced\",\n }),\n )\n components.push(\n component(row.zip, \"postal_code\", \"CONFIRMED\", {\n inferred: r.postal === \"inferred\",\n replaced: r.postal === \"replaced\",\n }),\n )\n components.push(component(plus4, \"postal_code_suffix\", \"CONFIRMED\", { inferred: true }))\n components.push(\n component(\"USA\", \"country\", \"CONFIRMED\", { inferred: input.regionCode === undefined }),\n )\n hasInferred = true\n unconfirmed = components\n .filter((c) => c.confirmationLevel !== \"CONFIRMED\")\n .map((c) => c.componentType)\n\n if (validation.granularity) granularity = validation.granularity\n if (validation.addressComplete !== undefined) addressComplete = validation.addressComplete\n if (validation.possibleNextAction) nextAction = validation.possibleNextAction\n if (validation.dpvConfirmation) dpv = validation.dpvConfirmation\n if (validation.unconfirmedComponentTypes)\n unconfirmed = [...validation.unconfirmedComponentTypes]\n if (validation.uspsErrorMessage) uspsError = validation.uspsErrorMessage\n\n const line = [street, r.unit ? unitText(r.unit) : \"\"].filter(Boolean).join(\" \")\n const zip = `${row.zip}-${plus4}`\n postalAddress = {\n regionCode: \"US\",\n languageCode: \"en\",\n postalCode: zip,\n administrativeArea: row.state,\n locality: row.city,\n addressLines: [line],\n }\n formattedAddress = `${line}, ${row.city}, ${row.state} ${zip}, USA`\n const place = r.inCorpus\n ? { placeId: corpusPlaceId(row), lat: row.lat, lng: row.lng }\n : synthesize(street, row)\n geocode = {\n location: { latitude: place.lat, longitude: place.lng },\n placeId: place.placeId,\n placeTypes: r.unit ? [\"subpremise\"] : [\"premise\"],\n }\n standardized = {\n firstAddressLine: line.toUpperCase(),\n cityStateZipAddressLine: `${row.city.toUpperCase()} ${row.state} ${zip}`,\n city: row.city.toUpperCase(),\n state: row.state,\n zipCode: row.zip,\n zipCodeExtension: plus4,\n }\n }\n\n if (options.dpvOverride) dpv = options.dpvOverride\n if (dpv === \"N\") standardized = undefined\n if (dpv !== undefined && dpvFootnote === undefined) dpvFootnote = dpv === \"N\" ? \"A1M1\" : \"AABB\"\n if (dpv === \"N\") dpvFootnote = \"A1M1\"\n\n const verdict = compact({\n inputGranularity,\n validationGranularity: granularity,\n geocodeGranularity: granularity === \"SUB_PREMISE\" ? \"PREMISE\" : granularity,\n addressComplete,\n hasUnconfirmedComponents: unconfirmed.length > 0,\n hasInferredComponents: hasInferred,\n hasReplacedComponents: hasReplaced,\n possibleNextAction: nextAction,\n })\n const address = compact({\n formattedAddress,\n postalAddress,\n addressComponents: components,\n missingComponentTypes: uniq(missing),\n unconfirmedComponentTypes: uniq(unconfirmed),\n })\n const uspsData = usps\n ? uspsError\n ? compact({ errorMessage: uspsError, cassProcessed: enableUspsCass })\n : compact({\n standardizedAddress: standardized,\n dpvConfirmation: dpv,\n dpvFootnote: dpv ? dpvFootnote : undefined,\n postOfficeCity: standardized ? standardized.city : undefined,\n postOfficeState: standardized ? standardized.state : undefined,\n cassProcessed: enableUspsCass,\n })\n : undefined\n const result = compact({ verdict, address, geocode, uspsData })\n const verdictClass = `${nextAction}/${uspsError ? \"ERROR\" : (dpv ?? \"-\")}`\n return {\n body: { result, responseId: responseId(JSON.stringify({ input, enableUspsCass })) },\n rowId,\n verdictClass,\n }\n}\n", "import {\n type AdminRoutes,\n type Clock,\n createRuntime as createServiceRuntime,\n type FaultPreset,\n type RequestLog,\n type ServiceRuntime,\n} from \"@crvouga/mockingbird-service\"\nimport type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport { type CorpusAddress, DEFAULT_CORPUS } from \"./corpus.js\"\nimport { document } from \"./generated/openapi.js\"\nimport { GOOGLE_MAPS_NAMESPACE, GoogleMapsAPI, keyCredential } from \"./index.js\"\nimport type { Settings } from \"./state.js\"\nimport { DPV_CODES, GRANULARITIES, NEXT_ACTIONS, type ValidationOverrides } from \"./validation.js\"\n\nconst WEB_SERVICES = [\"PlaceAutocomplete\", \"PlaceDetails\", \"Geocode\", \"FindPlaceFromText\"] as const\n\nconst everyWebService = (rule: Record<string, unknown>) =>\n WEB_SERVICES.map((operationId) => ({ operationId, ...rule }))\n\n/**\n * Every named Google misbehaviour our consumer branches on, switched on with\n * `POST /__admin/faults {\"preset\": \"<name>\", \"count\"?: n}`. Google answers these with HTTP 200\n * and a non-OK `status`, which is what our client's consecutive-failure counter reads.\n */\nexport const GOOGLE_MAPS_PRESETS: Record<string, FaultPreset> = {\n over_query_limit: {\n description: \"Every web-service call answers status OVER_QUERY_LIMIT (HTTP 200)\",\n rules: everyWebService({ effect: \"google_status\", params: { status: \"OVER_QUERY_LIMIT\" } }),\n },\n request_denied: {\n description: \"Every web-service call answers status REQUEST_DENIED, as for a revoked key\",\n rules: everyWebService({ effect: \"google_status\", params: { status: \"REQUEST_DENIED\" } }),\n },\n unknown_error: {\n description: \"Every web-service call answers status UNKNOWN_ERROR (Google's transient failure)\",\n rules: everyWebService({ effect: \"google_status\", params: { status: \"UNKNOWN_ERROR\" } }),\n },\n zero_results: {\n description: \"Every web-service call answers status ZERO_RESULTS\",\n rules: everyWebService({ effect: \"google_status\", params: { status: \"ZERO_RESULTS\" } }),\n },\n geocode_zero_results: {\n description: \"Geocoding answers ZERO_RESULTS, so our client falls back to Find Place\",\n rules: [\n { operationId: \"Geocode\", effect: \"google_status\", params: { status: \"ZERO_RESULTS\" } },\n ],\n },\n autocomplete_over_query_limit: {\n description:\n \"Only Place Autocomplete answers OVER_QUERY_LIMIT (the manual-entry fallback path)\",\n rules: [\n {\n operationId: \"PlaceAutocomplete\",\n effect: \"google_status\",\n params: { status: \"OVER_QUERY_LIMIT\" },\n },\n ],\n },\n server_error: {\n description: \"Every web-service call answers HTTP 500 (our client counts !res.ok as a failure)\",\n rules: everyWebService({ status: 500, body: { error: \"Internal Server Error\" } }),\n },\n slow: {\n description: \"Every web-service call is held 6 s: past QA's 5 s wait for predictions\",\n rules: everyWebService({ latencyMs: 6_000 }),\n },\n address_validation_denied: {\n description:\n \"Address Validation answers 403 PERMISSION_DENIED, as for a key without the API enabled\",\n rules: [\n {\n operationId: \"ValidateAddress\",\n status: 403,\n body: {\n error: {\n code: 403,\n message:\n \"Requests to this API addressvalidation.googleapis.com method google.maps.addressvalidation.v1.AddressValidation.ValidateAddress are blocked.\",\n status: \"PERMISSION_DENIED\",\n details: [\n {\n \"@type\": \"type.googleapis.com/google.rpc.ErrorInfo\",\n reason: \"API_KEY_SERVICE_BLOCKED\",\n domain: \"googleapis.com\",\n metadata: { service: \"addressvalidation.googleapis.com\" },\n },\n ],\n },\n },\n },\n ],\n },\n address_validation_unavailable: {\n description: \"Address Validation answers 503 UNAVAILABLE (Google's transient failure)\",\n rules: [\n {\n operationId: \"ValidateAddress\",\n status: 503,\n body: {\n error: {\n code: 503,\n message: \"The service is currently unavailable.\",\n status: \"UNAVAILABLE\",\n },\n },\n },\n ],\n },\n address_validation_slow: {\n description: \"Address Validation is held 3 s: past a 2.5 s checkout timeout\",\n rules: [{ operationId: \"ValidateAddress\", latencyMs: 3_000 }],\n },\n address_validation_no_verdict: {\n description:\n 'Address Validation answers 200 {\"result\": {}} (no verdict): a malformed answer, for a client\\'s defensive branch',\n rules: [{ operationId: \"ValidateAddress\", status: 200, body: { result: {} } }],\n },\n address_validation_dpv_n: {\n description: \"Address Validation reports USPS DPV confirmation N (not deliverable)\",\n rules: [\n { operationId: \"ValidateAddress\", effect: \"usps_dpv\", params: { dpvConfirmation: \"N\" } },\n ],\n },\n script_unavailable: {\n description: \"The Maps JavaScript API answers 503, so the script's onerror fires\",\n rules: [{ operationId: \"MapsJavaScriptApi\", status: 503, body: \"Service Unavailable\" }],\n },\n}\n\nexport type GoogleMapsRuntimeOptions = {\n sqlite?: SqliteClient\n clock?: Clock\n seed?: number | string\n adminKey?: string\n onLog?: (entry: RequestLog) => void\n /** Addresses every namespace resolves. Default: the QA corpus. */\n corpus?: readonly CorpusAddress[]\n settings?: Partial<Settings>\n}\n\nexport type GoogleMapsRuntime = ServiceRuntime<GoogleMapsAPI>\n\nconst json = (status: number, body: unknown) =>\n new Response(JSON.stringify(body), { status, headers: { \"content-type\": \"application/json\" } })\nconst adminError = (status: number, message: string) =>\n json(status, { error: { type: \"mockingbird_admin\", message } })\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst stringList = (value: unknown): string[] | undefined =>\n Array.isArray(value) && value.every((v) => typeof v === \"string\")\n ? (value as string[])\n : undefined\n\n/** A row's Address Validation overrides, or the reason they are refused. */\nconst parseValidation = (\n value: unknown,\n index: number,\n): ValidationOverrides | undefined | string => {\n if (value === undefined || value === null) return undefined\n const at = `addresses[${index}].validation`\n if (!isRecord(value)) return `${at} must be an object`\n const out: ValidationOverrides = {}\n const enums = [\n [\"granularity\", GRANULARITIES],\n [\"possibleNextAction\", NEXT_ACTIONS],\n [\"dpvConfirmation\", DPV_CODES],\n ] as const\n for (const [key, allowed] of enums) {\n if (value[key] === undefined) continue\n if (!(allowed as readonly unknown[]).includes(value[key])) {\n return `${at}.${key} must be one of ${allowed.join(\", \")}`\n }\n Object.assign(out, { [key]: value[key] })\n }\n for (const key of [\"addressComplete\", \"multiUnit\"] as const) {\n if (value[key] === undefined) continue\n if (typeof value[key] !== \"boolean\") return `${at}.${key} must be a boolean`\n out[key] = value[key] as boolean\n }\n for (const key of [\"unconfirmedComponentTypes\", \"units\"] as const) {\n if (value[key] === undefined) continue\n const list = stringList(value[key])\n if (!list) return `${at}.${key} must be a string[]`\n out[key] = list\n }\n if (value.uspsErrorMessage !== undefined) {\n if (typeof value.uspsErrorMessage !== \"string\" || !value.uspsErrorMessage) {\n return `${at}.uspsErrorMessage must be a non-empty string`\n }\n out.uspsErrorMessage = value.uspsErrorMessage\n }\n return out\n}\n\n/** One admin-supplied address, or the reason it is refused. */\nexport const parseAddress = (value: unknown, index: number): CorpusAddress | string => {\n if (!isRecord(value)) return `addresses[${index}] must be an object`\n for (const key of [\"line1\", \"city\", \"state\", \"zip\"] as const) {\n if (typeof value[key] !== \"string\" || !(value[key] as string).trim()) {\n return `addresses[${index}].${key} must be a non-empty string`\n }\n }\n const state = String(value.state).toUpperCase()\n if (!/^[A-Z]{2}$/.test(state)) return `addresses[${index}].state must be a two-letter code`\n const validation = parseValidation(value.validation, index)\n if (typeof validation === \"string\") return validation\n const lat = value.lat === undefined ? 0 : Number(value.lat)\n const lng = value.lng === undefined ? 0 : Number(value.lng)\n if (!Number.isFinite(lat) || !Number.isFinite(lng)) {\n return `addresses[${index}].lat/lng must be numbers`\n }\n return {\n id:\n typeof value.id === \"string\" && value.id\n ? value.id\n : `custom-${String(value.zip)}-${String(value.line1)\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")}`,\n line1: String(value.line1).trim(),\n city: String(value.city).trim(),\n state,\n zip: String(value.zip).trim(),\n county: typeof value.county === \"string\" ? value.county : \"\",\n lat,\n lng,\n ...(validation ? { validation } : {}),\n }\n}\n\nconst adminRoutes = (runtime: ServiceRuntime<GoogleMapsAPI>): AdminRoutes => ({\n \"GET /corpus\": ({ namespace }) => {\n const api = runtime.instance(namespace)\n return json(200, {\n addresses: api.corpus(),\n custom: api.state.custom.count(),\n })\n },\n \"PUT /corpus\": ({ body, namespace }) => {\n const list = Array.isArray(body) ? body : isRecord(body) ? body.addresses : undefined\n if (!Array.isArray(list)) {\n return adminError(\n 400,\n 'expected {\"addresses\": [{line1, city, state, zip, lat?, lng?, validation?}]}',\n )\n }\n const rows: CorpusAddress[] = []\n for (const [index, each] of list.entries()) {\n const parsed = parseAddress(each, index)\n if (typeof parsed === \"string\") return adminError(400, parsed)\n rows.push(parsed)\n }\n const api = runtime.instance(namespace)\n api.state.replaceCustom(rows)\n return json(200, { custom: rows })\n },\n \"DELETE /corpus\": ({ namespace }) => {\n runtime.instance(namespace).state.replaceCustom([])\n return json(200, { status: \"ok\" })\n },\n \"GET /settings\": ({ namespace }) => json(200, runtime.instance(namespace).state.current()),\n \"PUT /settings\": ({ body, namespace }) => {\n if (!isRecord(body)) return adminError(400, \"expected a JSON object\")\n const patch: Partial<Settings> = {}\n if (body.keys !== undefined) {\n if (!Array.isArray(body.keys)) return adminError(400, \"keys: string[]\")\n patch.keys = body.keys.map(String)\n }\n if (body.publicUrl !== undefined) {\n if (body.publicUrl !== null && typeof body.publicUrl !== \"string\") {\n return adminError(400, \"publicUrl: string | null\")\n }\n patch.publicUrl = body.publicUrl as string | null\n }\n return json(200, runtime.instance(namespace).state.update(patch))\n },\n})\n\n/**\n * The Google Maps mock with Mockingbird's full service contract: `/health`, `/__admin/*`,\n * namespaces by header, by `/ns/<name>` path prefix, or by API key\n * (`PUT /__admin/credentials {\"credentials\": {\"<PLACES_KEY>\": \"<namespace>\"}}`), clock control,\n * fault presets and a request journal. Google Maps sends no webhooks.\n */\nexport const createRuntime = (options: GoogleMapsRuntimeOptions = {}): GoogleMapsRuntime =>\n createServiceRuntime<GoogleMapsAPI>({\n name: GOOGLE_MAPS_NAMESPACE,\n document,\n ...(options.sqlite ? { sqlite: options.sqlite } : {}),\n ...(options.clock ? { clock: options.clock } : {}),\n ...(options.seed !== undefined ? { seed: options.seed } : {}),\n ...(options.adminKey !== undefined ? { adminKey: options.adminKey } : {}),\n ...(options.onLog ? { onLog: options.onLog } : {}),\n credential: keyCredential,\n presets: GOOGLE_MAPS_PRESETS,\n create: ({ sqlite, namespace, publicNamespace, clock }) =>\n new GoogleMapsAPI({\n sqlite,\n namespace,\n publicNamespace,\n now: clock.now,\n ...(options.corpus ? { corpus: options.corpus } : {}),\n ...(options.settings ? { settings: options.settings } : {}),\n }),\n describe: () => ({\n corpus: options.corpus\n ? `custom (${options.corpus.length})`\n : `qa-routing-zip-corpus (${DEFAULT_CORPUS.length})`,\n }),\n admin: adminRoutes,\n })\n", "import type { FetchAPI } from \"@crvouga/mockingbird-core\"\nimport {\n type APIOptions,\n annotateResponse,\n bootSqlite,\n createService,\n defineOperations,\n faultEffect,\n HttpError,\n type OperationContext,\n type Service,\n} from \"@crvouga/mockingbird-service\"\nimport type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nimport type { Hono } from \"hono\"\nimport type { CorpusAddress } from \"./corpus.js\"\nimport { document, type SupportedOperationId } from \"./generated/openapi.js\"\nimport {\n autocomplete,\n findPlace,\n geocode,\n geometry,\n normalize,\n type Place,\n pickFields,\n placeById,\n placeResult,\n prediction,\n unknownFields,\n} from \"./places.js\"\nimport { mapsJavaScript } from \"./shim.js\"\nimport { GoogleMapsState, type Settings } from \"./state.js\"\nimport {\n DPV_CODES,\n type DpvConfirmation,\n type GoogleApiError,\n parseValidateRequest,\n ValidationRequestError,\n validateAddress,\n} from \"./validation.js\"\n\nexport type { FetchAPI } from \"@crvouga/mockingbird-core\"\nexport type { SqliteClient } from \"@crvouga/mockingbird-sqlite\"\nexport type { CorpusAddress } from \"./corpus.js\"\nexport { DEFAULT_CORPUS, PHOENIX_DEMO_ADDRESS, STATE_NAMES } from \"./corpus.js\"\nexport type { OperationId, SupportedOperationId } from \"./generated/openapi.js\"\nexport { document, operationIds, supportedOperationIds } from \"./generated/openapi.js\"\nexport type { AddressComponent, Place, Prediction } from \"./places.js\"\nexport { corpusPlaceId } from \"./places.js\"\nexport type { ShimOptions } from \"./shim.js\"\nexport { mapsJavaScript } from \"./shim.js\"\nexport type { Settings } from \"./state.js\"\nexport type {\n DpvConfirmation,\n GoogleApiError,\n Granularity,\n PossibleNextAction,\n ValidationOverrides,\n} from \"./validation.js\"\n\nexport const GOOGLE_MAPS_NAMESPACE = \"google-maps\"\n\n/** Google's own wording for the two ways a key is refused. */\nexport const MISSING_KEY_MESSAGE =\n \"You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account\"\nexport const INVALID_KEY_MESSAGE = \"The provided API key is invalid. \"\n\n/**\n * The Address Validation API is a Google Cloud API (`addressvalidation.googleapis.com`): keys\n * are refused with a `google.rpc.Status` envelope and an HTTP error, not a 200 with `status`.\n */\nexport const MISSING_API_KEY_MESSAGE = \"The request is missing a valid API key.\"\nexport const INVALID_API_KEY_MESSAGE = \"API key not valid. Please pass a valid API key.\"\n\n/** Google statuses the mock answers with (always HTTP 200, as Google does). */\nexport type GoogleStatus =\n | \"OK\"\n | \"ZERO_RESULTS\"\n | \"INVALID_REQUEST\"\n | \"OVER_QUERY_LIMIT\"\n | \"REQUEST_DENIED\"\n | \"UNKNOWN_ERROR\"\n | \"NOT_FOUND\"\n\nexport type GoogleMapsAPIOptions = APIOptions & {\n /** Addresses every namespace resolves. Default: {@link DEFAULT_CORPUS}. */\n corpus?: readonly CorpusAddress[]\n /** Initial per-namespace settings (accepted keys, public URL for the JS shim). */\n settings?: Partial<Settings>\n /** The public namespace name, so the JS shim can call back into the same namespace. */\n publicNamespace?: string\n}\n\n/**\n * The API key a request carries (`?key=`, or the `X-Goog-Api-Key` header Google Cloud APIs\n * also accept): how keys map to namespaces.\n */\nexport const keyCredential = (request: Request): string | undefined =>\n new URL(request.url).searchParams.get(\"key\") ?? request.headers.get(\"x-goog-api-key\") ?? undefined\n\nconst CORS = { \"access-control-allow-origin\": \"*\" }\n\nconst json = (body: unknown, status = 200): Response =>\n new Response(JSON.stringify(body, null, 3), {\n status,\n headers: { \"content-type\": \"application/json; charset=UTF-8\", ...CORS },\n })\n\n/** The empty collection each endpoint carries next to a non-OK status. */\nconst EMPTY: Record<string, Record<string, unknown>> = {\n PlaceAutocomplete: { predictions: [] },\n PlaceDetails: { html_attributions: [] },\n Geocode: { results: [] },\n FindPlaceFromText: { candidates: [] },\n}\n\nconst DEFAULT_MESSAGES: Partial<Record<GoogleStatus, string>> = {\n OVER_QUERY_LIMIT:\n \"You have exceeded your rate-limit for this API. For more information on Google Maps Platform rate limits, please see https://developers.google.com/maps/documentation/places/web-service/usage-and-billing\",\n UNKNOWN_ERROR: \"An unknown error occurred. Please try again.\",\n REQUEST_DENIED: INVALID_KEY_MESSAGE,\n}\n\n/** A Google Cloud API error (`{\"error\": {code, message, status}}`). */\nconst apiError = (error: GoogleApiError): Response => json({ error }, error.code)\n\n/** The JSON a Google Cloud API reads from a body (it parses bodies sent without a JSON type too). */\nconst requestJson = (body: OperationContext[\"body\"]): unknown => {\n if (body.kind === \"json\") return body.value\n if (body.kind === \"empty\") return {}\n const raw =\n body.kind === \"bytes\"\n ? new TextDecoder().decode(body.value)\n : body.kind === \"text\"\n ? body.value\n : body.kind === \"invalid\"\n ? body.text\n : undefined\n try {\n return JSON.parse(raw ?? \"\")\n } catch {\n throw new ValidationRequestError(\"Invalid JSON payload received.\")\n }\n}\n\nconst text = (value: unknown): string | undefined =>\n typeof value === \"string\" ? value : Array.isArray(value) ? String(value[0]) : undefined\n\n/**\n * Stateless-over-a-corpus mock of Google Places Autocomplete / Details / Find Place, the\n * Geocoding API and a Maps JavaScript shim. Every answer is HTTP 200 with Google's `status`.\n */\nexport class GoogleMapsAPI implements FetchAPI {\n readonly app: Hono\n readonly sqlite: SqliteClient\n readonly state: GoogleMapsState\n private readonly service: Service\n private readonly publicNamespace: string\n\n constructor(options: GoogleMapsAPIOptions = {}) {\n const sqlite = bootSqlite(options.sqlite)\n const namespace = options.namespace ?? GOOGLE_MAPS_NAMESPACE\n this.publicNamespace = options.publicNamespace ?? \"default\"\n this.state = new GoogleMapsState(sqlite, namespace, {\n corpus: options.corpus ?? [],\n settings: options.settings ?? {},\n })\n const handlers = defineOperations<SupportedOperationId>({\n PlaceAutocomplete: (context) => this.autocomplete(context),\n PlaceDetails: (context) => this.details(context),\n Geocode: (context) => this.geocode(context),\n FindPlaceFromText: (context) => this.findPlace(context),\n MapsJavaScriptApi: (context) => this.script(context),\n ValidateAddress: (context) => this.validate(context),\n })\n this.service = createService({\n document,\n handlers,\n sqlite,\n namespace,\n ...(options.now ? { now: options.now } : {}),\n notFound: () =>\n new Response(\"<html><body><h1>Not Found</h1></body></html>\", {\n status: 404,\n headers: { \"content-type\": \"text/html; charset=UTF-8\", ...CORS },\n }),\n onError: (error) => {\n if (error instanceof HttpError) return error.toResponse()\n throw error\n },\n before: (context) => this.gate(context),\n })\n this.app = this.service.app\n this.sqlite = this.service.sqlite\n }\n\n fetch(request: Request): Promise<Response> {\n return this.service.fetch(request)\n }\n\n async reset(): Promise<void> {\n await this.service.reset()\n this.state.ensureSeeded()\n }\n\n /** The addresses this namespace resolves (custom rows first). */\n corpus(): CorpusAddress[] {\n return this.state.corpus()\n }\n\n private status(operationId: string, status: GoogleStatus, message?: string): Response {\n return json({\n ...EMPTY[operationId],\n ...(message ? { error_message: message } : {}),\n status,\n })\n }\n\n /** Key check and status-effect faults, before every web-service call. */\n private gate(context: OperationContext): Response | undefined {\n const operationId = context.operation.operationId\n if (operationId === \"MapsJavaScriptApi\") return undefined\n if (operationId === \"ValidateAddress\") return this.cloudGate(context)\n const key = text(context.query.key)\n if (!key) return this.status(operationId, \"REQUEST_DENIED\", MISSING_KEY_MESSAGE)\n const keys = this.state.current().keys\n if (keys.length > 0 && !keys.includes(key)) {\n return this.status(operationId, \"REQUEST_DENIED\", INVALID_KEY_MESSAGE)\n }\n const forced = faultEffect(context.request, \"google_status\")\n if (forced !== undefined) {\n const status = (\n typeof forced.status === \"string\" ? forced.status : \"UNKNOWN_ERROR\"\n ) as GoogleStatus\n const message =\n typeof forced.error_message === \"string\" ? forced.error_message : DEFAULT_MESSAGES[status]\n return this.status(operationId, status, message)\n }\n return undefined\n }\n\n /** Key check for the Google Cloud-style Address Validation API. */\n private cloudGate(context: OperationContext): Response | undefined {\n const key = text(context.query.key) ?? context.request.headers.get(\"x-goog-api-key\")\n if (!key) {\n return apiError({ code: 403, message: MISSING_API_KEY_MESSAGE, status: \"PERMISSION_DENIED\" })\n }\n const keys = this.state.current().keys\n if (keys.length > 0 && !keys.includes(key)) {\n return apiError({\n code: 400,\n message: INVALID_API_KEY_MESSAGE,\n status: \"INVALID_ARGUMENT\",\n details: [\n {\n \"@type\": \"type.googleapis.com/google.rpc.ErrorInfo\",\n reason: \"API_KEY_INVALID\",\n domain: \"googleapis.com\",\n metadata: { service: \"addressvalidation.googleapis.com\" },\n },\n ],\n })\n }\n return undefined\n }\n\n private validate(context: OperationContext): Response {\n let request: ReturnType<typeof parseValidateRequest>\n try {\n request = parseValidateRequest(requestJson(context.body))\n } catch (error) {\n if (!(error instanceof ValidationRequestError)) throw error\n return apiError({ code: 400, message: error.message, status: \"INVALID_ARGUMENT\" })\n }\n const forced = faultEffect(context.request, \"usps_dpv\")?.dpvConfirmation\n const dpvOverride = DPV_CODES.includes(forced as DpvConfirmation)\n ? (forced as DpvConfirmation)\n : undefined\n const outcome = validateAddress(request, this.state.corpus(), {\n ...(dpvOverride ? { dpvOverride } : {}),\n })\n // The journal gets the resolved row and the verdict class, never the address itself.\n return annotateResponse(json(outcome.body), {\n ids: {\n ...(outcome.rowId ? { addressRowId: outcome.rowId } : {}),\n verdict: outcome.verdictClass,\n },\n })\n }\n\n private noted(response: Response, context: OperationContext, place?: Place): Response {\n const session = text(context.query.sessiontoken)\n const ids: Record<string, string> = {}\n if (place) ids.placeId = place.placeId\n // The session token is an opaque UUID, not an address: metadata only.\n if (session) ids.sessionToken = session\n return Object.keys(ids).length > 0 ? annotateResponse(response, { ids }) : response\n }\n\n private autocomplete(context: OperationContext): Response {\n const input = text(context.query.input)\n if (!input) return this.status(\"PlaceAutocomplete\", \"INVALID_REQUEST\")\n const components = text(context.query.components)\n if (components !== undefined) {\n const countries = components\n .split(\"|\")\n .map((c) => c.trim().toLowerCase())\n .filter((c) => c.startsWith(\"country:\"))\n .map((c) => c.slice(\"country:\".length))\n if (countries.length > 0 && !countries.includes(\"us\")) {\n return this.noted(json({ predictions: [], status: \"ZERO_RESULTS\" }), context)\n }\n }\n const types = text(context.query.types)\n let places = autocomplete(input, this.state.corpus())\n if (types === \"address\") places = places.filter((p) => p.kind === \"street_address\")\n if (places.length === 0) {\n return this.noted(json({ predictions: [], status: \"ZERO_RESULTS\" }), context)\n }\n return this.noted(\n json({ predictions: places.map((p) => prediction(p, input)), status: \"OK\" }),\n context,\n places[0],\n )\n }\n\n private details(context: OperationContext): Response {\n const placeId = text(context.query.place_id)\n if (!placeId) return this.status(\"PlaceDetails\", \"INVALID_REQUEST\")\n const fields = text(context.query.fields)\n if (unknownFields(fields).length > 0) {\n return this.status(\n \"PlaceDetails\",\n \"INVALID_REQUEST\",\n `Error while parsing 'fields' parameter: Unsupported field name '${unknownFields(fields)[0]}'. `,\n )\n }\n const place = placeById(placeId, this.state.corpus())\n if (!place) return this.noted(this.status(\"PlaceDetails\", \"NOT_FOUND\"), context)\n return this.noted(\n json({\n html_attributions: [],\n result: pickFields(placeResult(place), fields, \"all\"),\n status: \"OK\",\n }),\n context,\n place,\n )\n }\n\n private geocode(context: OperationContext): Response {\n const address = text(context.query.address)\n const placeId = text(context.query.place_id)\n const components = text(context.query.components)\n const zip = components\n ?.split(\"|\")\n .find((c) => c.startsWith(\"postal_code:\"))\n ?.slice(\"postal_code:\".length)\n if (!address && !placeId && !zip) return this.status(\"Geocode\", \"INVALID_REQUEST\")\n const rows = this.state.corpus()\n const place = placeId\n ? placeById(placeId, rows)\n : address\n ? geocode(address, rows)\n : geocode(zip as string, rows)\n if (!place) return this.noted(json({ results: [], status: \"ZERO_RESULTS\" }), context)\n const full = placeResult(place)\n return this.noted(\n json({\n results: [\n {\n address_components: full.address_components,\n formatted_address: full.formatted_address,\n geometry: geometry(place, true),\n place_id: place.placeId,\n types: full.types,\n },\n ],\n status: \"OK\",\n }),\n context,\n place,\n )\n }\n\n private findPlace(context: OperationContext): Response {\n const input = text(context.query.input)\n const inputtype = text(context.query.inputtype)\n if (!input || (inputtype !== \"textquery\" && inputtype !== \"phonenumber\")) {\n return this.status(\"FindPlaceFromText\", \"INVALID_REQUEST\")\n }\n const fields = text(context.query.fields)\n if (unknownFields(fields).length > 0) {\n return this.status(\n \"FindPlaceFromText\",\n \"INVALID_REQUEST\",\n `Error while parsing 'fields' parameter: Unsupported field name '${unknownFields(fields)[0]}'. `,\n )\n }\n const place = inputtype === \"textquery\" ? findPlace(input, this.state.corpus()) : undefined\n if (!place) return this.noted(json({ candidates: [], status: \"ZERO_RESULTS\" }), context)\n return this.noted(\n json({ candidates: [pickFields(placeResult(place), fields, [\"place_id\"])], status: \"OK\" }),\n context,\n place,\n )\n }\n\n private script(context: OperationContext): Response {\n const key = text(context.query.key) ?? \"\"\n const settings = this.state.current()\n const origin = (settings.publicUrl ?? context.url.origin).replace(/\\/$/, \"\")\n const prefix =\n this.publicNamespace === \"default\" ? \"\" : `/ns/${encodeURIComponent(this.publicNamespace)}`\n const callback = text(context.query.callback) ?? null\n const safeCallback = callback && /^[A-Za-z_$][\\w$.]*$/.test(callback) ? callback : null\n const authFailed = !key || (settings.keys.length > 0 && !settings.keys.includes(key))\n return new Response(\n mapsJavaScript({ base: `${origin}${prefix}`, key, authFailed, callback: safeCallback }),\n {\n status: 200,\n headers: { \"content-type\": \"text/javascript; charset=UTF-8\", ...CORS },\n },\n )\n }\n}\n\nexport type { GoogleMapsRuntime, GoogleMapsRuntimeOptions } from \"./runtime.js\"\nexport { createRuntime, GOOGLE_MAPS_PRESETS } from \"./runtime.js\"\n/** Normalized form used for address matching (lowercase, alphanumerics, single spaces). */\nexport { normalize }\n"],
5
- "mappings": ";AAgCO,IAAM,cAAc,CAAC,SAAuB,KAAK,QAAc;AACpE,MAAI,WAAW;AACf,MAAI;AACJ,QAAM,MAAM,MAAM,YAAY,OAAM,IAAK;AACzC,SAAO;IACL;IACA,KAAK,CAAC,YAAW;AACf,UAAI,aAAa;AAAW,mBAAW;;AAClC,mBAAW,UAAU,OAAM;IAClC;IACA,SAAS,CAAC,YAAW;AACnB,UAAI,aAAa;AAAW,oBAAY;;AACnC,oBAAY;IACnB;IACA,QAAQ,MAAK;AACX,iBAAW,IAAG;IAChB;IACA,UAAU,MAAK;AACb,UAAI,aAAa;AAAW;AAC5B,iBAAW,WAAW,OAAM;AAC5B,iBAAW;IACb;IACA,OAAO,MAAK;AACV,iBAAW;AACX,iBAAW;IACb;IACA,OAAO,OAAO,EAAE,KAAK,IAAG,GAAI,QAAQ,aAAa,QAAW,SAAQ;;AAExE;;;AC1CM,IAAO,aAAP,MAAiB;EAEF;EAER;EAEA;EALX,YACmB,QAER,WAEA,gBAAsB;AAJd,SAAA,SAAA;AAER,SAAA,YAAA;AAEA,SAAA,iBAAA;EACR;EAEK,oBAAiB;AACvB,UAAMA,OAAM,KAAK,OACd,QACC,kGAAkG,EAEnG,IAAuB,KAAK,WAAW,KAAK,cAAc;AAC7D,UAAM,QAAQA,MAAK,SAAS,KAAK;AACjC,SAAK,OACF,QACC;iFACyE,EAE1E,IAAI,KAAK,WAAW,KAAK,gBAAgB,IAAI;AAChD,WAAO;EACT;EAEA,eAAY;AACV,WAAO,KAAK,OAAO,YAAY,MAAM,KAAK,kBAAiB,CAAE;EAC/D;EAEA,IAAI,IAAU;AACZ,UAAMA,OAAM,KAAK,OACd,QACC,yFAAyF,EAE1F,IAAuB,KAAK,WAAW,KAAK,gBAAgB,EAAE;AACjE,QAAI,CAACA;AAAK,aAAO;AACjB,WAAQ,KAAK,MAAMA,KAAI,KAAK,EAAgB;EAC9C;EAEA,IAAI,IAAU;AACZ,UAAMA,OAAM,KAAK,OACd,QACC,2FAA2F,EAE5F,IAAoB,KAAK,WAAW,KAAK,gBAAgB,EAAE;AAC9D,WAAOA,SAAQ;EACjB;;EAGA,OAAO,IAAY,OAAQ;AACzB,WAAO,KAAK,OAAO,YAAY,MAAK;AAClC,YAAM,MAAM,KAAK,kBAAiB;AAClC,YAAM,SAAS,EAAE,KAAK,MAAK;AAC3B,WAAK,OACF,QACC;;2GAEiG,EAElG,IAAI,KAAK,WAAW,KAAK,gBAAgB,IAAI,KAAK,KAAK,UAAU,MAAM,CAAC;AAC3E,aAAO;IACT,CAAC;EACH;;EAGA,OAAO,IAAY,OAAQ;AACzB,WAAO,KAAK,OAAO,YAAY,MAAK;AAClC,YAAMA,OAAM,KAAK,OACd,QACC,8FAA8F,EAE/F,IAAoC,KAAK,WAAW,KAAK,gBAAgB,EAAE;AAC9E,UAAI,CAACA;AAAK,eAAO;AACjB,YAAM,SAAS,EAAE,KAAKA,KAAI,KAAK,MAAK;AACpC,WAAK,OACF,QACC,4FAA4F,EAE7F,IAAI,KAAK,UAAU,MAAM,GAAG,KAAK,WAAW,KAAK,gBAAgB,EAAE;AACtE,aAAO;IACT,CAAC;EACH;EAEA,OAAO,IAAU;AACf,UAAM,SAAS,KAAK,OACjB,QAAQ,mFAAmF,EAC3F,IAAI,KAAK,WAAW,KAAK,gBAAgB,EAAE;AAC9C,WAAO,OAAO,UAAU;EAC1B;;EAGA,QAAK;AACH,UAAMA,OAAM,KAAK,OACd,QACC,sFAAsF,EAEvF,IAAmB,KAAK,WAAW,KAAK,cAAc;AACzD,WAAO,OAAOA,MAAK,KAAK,CAAC;EAC3B;EAEA,KAAK,UAAiC,CAAA,GAAE;AACtC,UAAM,OAAO,KAAK,OACf,QACC,uFAAuF,EAExF,IAAe,KAAK,WAAW,KAAK,cAAc;AACrD,UAAM,MAAyC,CAAA;AAC/C,eAAWA,QAAO,MAAM;AACtB,YAAM,SAAS,KAAK,MAAMA,KAAI,KAAK;AACnC,UAAI,QAAQ,SAAS,CAAC,QAAQ,MAAM,OAAO,OAAO,OAAO,GAAG;AAAG;AAC/D,UAAI,KAAK,EAAE,IAAIA,KAAI,IAAI,KAAK,OAAO,KAAK,OAAO,OAAO,MAAK,CAAE;IAC/D;AACA,QAAI,KAAK,CAAC,GAAG,MAAO,QAAQ,UAAU,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAI;AAC/E,WAAO;EACT;;;;AC9HK,IAAM,cAAc;AAEpB,IAAM,eAAe;AAErB,IAAM,mBAAmB;AAEzB,IAAM,mBAAmB;AAoEhC,IAAM,OAAO,CAAC,QAAgB,SAC5B,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;EACjC;EACA,SAAS,EAAE,gBAAgB,mBAAkB;CAC9C;AAGH,IAAM,aAAa,CAAC,QAAgB,YAClC,KAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,QAAO,EAAE,CAAE;AAEhE,IAAM,QAAgC;EACpC,IAAI;EACJ,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;;AAIE,IAAM,gBAAgB,CAAC,UAAsC;AAClE,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAAG,WAAO;AAChE,MAAI,OAAO,UAAU;AAAU,WAAO;AACtC,QAAM,QAAQ,qCAAqC,KAAK,MAAM,KAAI,CAAE;AACpE,MAAI,CAAC;AAAO,WAAO;AACnB,SAAO,OAAO,MAAM,CAAC,CAAC,IAAK,MAAM,MAAM,CAAC,CAAW;AACrD;AAGA,IAAM,eAAe,CAAC,UAAsC;AAC1D,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAAG,WAAO;AAChE,MAAI,OAAO,UAAU;AAAU,WAAO;AACtC,QAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,SAAO,OAAO,MAAM,MAAM,IAAI,SAAY;AAC5C;AAEA,IAAM,aAAa,CAAC,SAAiB,SAAoD;AACvF,QAAM,OAAO,QAAQ,MAAM,GAAG,EAAE,OAAO,OAAO;AAC9C,QAAM,OAAO,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC3C,MAAI,KAAK,WAAW,KAAK;AAAQ,WAAO;AACxC,QAAM,SAAiC,CAAA;AACvC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,UAAU,KAAK,CAAC;AACtB,UAAM,SAAS,KAAK,CAAC;AACrB,QAAI,QAAQ,WAAW,GAAG;AAAG,aAAO,QAAQ,MAAM,CAAC,CAAC,IAAI,mBAAmB,MAAM;aACxE,YAAY;AAAQ,aAAO;EACtC;AACA,SAAO;AACT;AAEA,IAAM,WAAW,OAAO,YAAsC;AAC5D,QAAMC,QAAO,MAAM,QAAQ,KAAI;AAC/B,MAAIA,MAAK,KAAI,MAAO;AAAI,WAAO;AAC/B,SAAO,KAAK,MAAMA,KAAI;AACxB;AAEA,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAE9D,IAAM,qBAAqB,CAAC,YAAyC;AAG1E,QAAM,YAAY,oBAAI,IAAG;AACzB,MAAI,kBAAkB;AAEtB,QAAM,kBAAkB,CAAC,YACvB,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,QAAQ;AACnD,QAAM,iBAAiB,CAAC,SAAkB,QACxC,IAAI,aAAa,IAAI,WAAW,KAAK,gBAAgB,OAAO;AAE9D,QAAM,UAAuB;IAC3B,SAAS,MACP,KAAK,KAAK;MACR,SAAS,QAAQ;MACjB,QAAQ,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,GAAG,OAAO,KAAK,QAAQ,MAAM,CAAC,EAAE,KAAI;KACvE;IAEH,eAAe,OAAO,EAAE,KAAK,UAAS,MAAM;AAC1C,YAAM,SAAS,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,MAAM;AAC3D,YAAM,QAAQ,MAAM,MAAM;AAC1B,aAAO,KAAK,KAAK,EAAE,QAAQ,MAAM,OAAO,WAAW,MAAM,QAAQ,WAAU,IAAK,CAAC,MAAM,EAAC,CAAE;IAC5F;IAEA,mBAAmB,MACjB,KAAK,KAAK,EAAE,SAAS,QAAQ,kBAAkB,YAAY,QAAQ,WAAU,EAAE,CAAE;IAEnF,cAAc,MAAM,KAAK,KAAK,QAAQ,MAAM,MAAK,CAAE;IACnD,eAAe,CAAC,EAAE,KAAI,MAAM;AAC1B,UAAI,CAAC,SAAS,IAAI;AAAG,eAAO,WAAW,KAAK,wBAAwB;AACpE,UAAI,KAAK,UAAU;AAAM,gBAAQ,MAAM,MAAK;AAC5C,UAAI,KAAK,QAAQ,QAAW;AAC1B,cAAM,UAAU,aAAa,KAAK,GAAG;AACrC,YAAI,YAAY;AAAW,iBAAO,WAAW,KAAK,oCAAoC;AACtF,gBAAQ,MAAM,IAAI,OAAO;MAC3B;AACA,UAAI,KAAK,YAAY,QAAW;AAC9B,cAAM,QAAQ,cAAc,KAAK,OAAO;AACxC,YAAI,UAAU;AAAW,iBAAO,WAAW,KAAK,qCAAqC;AACrF,gBAAQ,MAAM,QAAQ,KAAK;MAC7B;AACA,UAAI,KAAK,WAAW;AAAM,gBAAQ,MAAM,OAAM;AAC9C,UAAI,KAAK,WAAW;AAAO,gBAAQ,MAAM,SAAQ;AACjD,aAAO,KAAK,KAAK,QAAQ,MAAM,MAAK,CAAE;IACxC;IAEA,eAAe,MAAM,KAAK,KAAK,EAAE,QAAQ,QAAQ,OAAO,KAAI,EAAE,CAAE;IAChE,gBAAgB,CAAC,EAAE,MAAM,UAAS,MAAM;AACtC,UAAI,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,UAAU;AACrD,YAAI,CAAC,QAAQ;AAAa,iBAAO,WAAW,KAAK,GAAG,QAAQ,IAAI,uBAAuB;AACvF,cAAM,EAAE,QAAQ,GAAG,UAAS,IAAK;AACjC,YAAI;AACF,iBAAO,KAAK,KAAK;YACf;YACA,OAAO,QAAQ,YAAY,QAAQ,WAAW,SAA+B;WAC9E;QACH,SAAS,OAAO;AACd,iBAAO,WAAW,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;QAC/E;MACF;AACA,UACE,CAAC,SAAS,IAAI,KACb,OAAO,KAAK,WAAW,YACtB,OAAO,KAAK,YAAY,YACxB,OAAO,KAAK,cAAc,YAC1B,KAAK,SAAS,QACd,OAAO,KAAK,WAAW,UACzB;AACA,eAAO,WACL,KACA,yFAAyF;MAE7F;AACA,YAAM,OAAO;;;QAGX;QACA,GAAG;QACH,IAAI,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK,SAAS,QAAQ,OAAO,KAAI,EAAG,SAAS,CAAC;;AAEvF,aAAO,KAAK,KAAK,QAAQ,OAAO,IAAI,IAAI,CAAC;IAC3C;IACA,kBAAkB,CAAC,EAAE,IAAG,MAAM;AAC5B,YAAM,KAAK,IAAI,aAAa,IAAI,IAAI;AACpC,UAAI,OAAO,MAAM;AACf,gBAAQ,OAAO,MAAK;AACpB,eAAO,KAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;MACnC;AACA,aAAO,QAAQ,OAAO,OAAO,EAAE,IAC3B,KAAK,KAAK,EAAE,QAAQ,KAAI,CAAE,IAC1B,WAAW,KAAK,YAAY,EAAE,EAAE;IACtC;IAEA,mBAAmB,CAAC,EAAE,UAAS,MAAM;AACnC,YAAM,QAAQ,QAAQ,WAAW,WAAW,WAAW,MAAM;AAC7D,cAAQ,WAAW,OAAO,WAAW,MAAM,EAAE;AAC7C;AACA,YAAM,KAAK,QAAQ,eAAe;AAClC,gBAAU,IAAI,IAAI,EAAE,WAAW,YAAY,MAAM,GAAE,CAAE;AACrD,aAAO,KAAK,KAAK,EAAE,IAAI,WAAW,SAAS,MAAM,WAAW,EAAC,CAAE;IACjE;IACA,+BAA+B,CAAC,EAAE,QAAQ,UAAS,MAAM;AACvD,YAAM,QAAQ,UAAU,IAAI,OAAO,EAAY;AAC/C,UAAI,CAAC;AAAO,eAAO,WAAW,KAAK,eAAe,OAAO,EAAE,EAAE;AAC7D,UAAI,MAAM,cAAc,WAAW;AACjC,eAAO,WAAW,KAAK,YAAY,OAAO,EAAE,yBAAyB,MAAM,SAAS,EAAE;MACxF;AACA,cAAQ,WAAW,SAAS,MAAM,YAAY,EAAE,WAAW,QAAQ,OAAM,CAAE;AAC3E,aAAO,KAAK,KAAK,EAAE,QAAQ,MAAM,IAAI,OAAO,IAAI,UAAS,CAAE;IAC7D;IACA,yBAAyB,CAAC,EAAE,OAAM,MAAM;AACtC,YAAM,KAAK,OAAO;AAClB,YAAM,QAAQ,UAAU,IAAI,EAAE;AAC9B,UAAI,CAAC;AAAO,eAAO,WAAW,KAAK,eAAe,EAAE,EAAE;AACtD,gBAAU,OAAO,EAAE;AACnB,cAAQ,WAAW,QAAQ,MAAM,WAAW,MAAM,UAAU;AAC5D,aAAO,KAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;IACnC;IAEA,iBAAiB,CAAC,EAAE,UAAS,MAAO,KAAK,KAAK,QAAQ,WAAW,QAAQ,SAAS,CAAC;IACnF,qBAAqB,CAAC,EAAE,MAAM,UAAS,MAAM;AAC3C,YAAM,SAAS,SAAS,IAAI,KAAK,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AACjF,UAAI;AACF,eAAO,KAAK,KAAK,QAAQ,WAAW,WAAW,WAAW,MAAM,CAAC;MACnE,SAAS,OAAO;AACd,eAAO,WAAW,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;MAC/E;IACF;IACA,wBAAwB,CAAC,EAAE,QAAQ,MAAM,UAAS,MAAM;AACtD,YAAM,KAAK,SAAS,IAAI,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACrE,UAAI;AACF,eAAO,KACL,KACA,QAAQ,WAAW,OAAO,OAAO,MAAgB;UAC/C;UACA,GAAI,OAAO,SAAY,EAAE,GAAE,IAAK,CAAA;SACjC,CAAC;MAEN,SAAS,OAAO;AACd,eAAO,WAAW,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;MAC/E;IACF;IACA,iCAAiC,CAAC,EAAE,QAAQ,MAAM,UAAS,MAAM;AAC/D,UAAI,CAAC,SAAS,IAAI,KAAK,OAAO,KAAK,eAAe,UAAU;AAC1D,eAAO,WAAW,KAAK,kCAAkC;MAC3D;AACA,UAAI;AACF,gBAAQ,WAAW,SAAS,KAAK,YAAY;UAC3C;UACA,QAAQ,OAAO;SAChB;AACD,eAAO,KAAK,KAAK,EAAE,QAAQ,MAAM,QAAQ,OAAO,MAAM,YAAY,KAAK,WAAU,CAAE;MACrF,SAAS,OAAO;AACd,eAAO,WAAW,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;MAC/E;IACF;IAEA,iBAAiB,CAAC,EAAE,KAAK,UAAS,MAAM;AACtC,YAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,YAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,YAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,YAAM,UACJ,UAAU,OAAO,SAAY,aAAa,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,KAAK;AACvF,UAAI,UAAU,QAAQ,YAAY,QAAW;AAC3C,eAAO,WAAW,KAAK,sCAAsC;MAC/D;AACA,UAAI,WAAW,QAAQ,CAAC,UAAU,KAAK,MAAM;AAC3C,eAAO,WAAW,KAAK,iCAAiC;AAC1D,UAAI,UAAU,QAAQ,CAAC,QAAQ,KAAK,KAAK;AAAG,eAAO,WAAW,KAAK,yBAAyB;AAC5F,YAAM,cAAc,IAAI,aAAa,IAAI,aAAa;AACtD,YAAM,iBAAiB,IAAI,aAAa,IAAI,KAAK,MAAM;AACvD,aAAO,KAAK,KAAK;QACf,MAAM,QAAQ,QAAQ;QACtB,UAAU,QAAQ,QAAQ,KAAK;UAC7B,GAAI,iBAAiB,CAAA,IAAK,EAAE,UAAS;UACrC,GAAI,gBAAgB,OAAO,EAAE,YAAW,IAAK,CAAA;UAC7C,GAAI,WAAW,OAAO,EAAE,QAAQ,OAAO,MAAM,EAAC,IAAK,CAAA;UACnD,GAAI,YAAY,SAAY,EAAE,OAAO,QAAO,IAAK,CAAA;UACjD,GAAI,UAAU,OAAO,EAAE,OAAO,OAAO,KAAK,EAAC,IAAK,CAAA;SACjD;OACF;IACH;IACA,oBAAoB,CAAC,EAAE,KAAK,UAAS,MAAM;AACzC,cAAQ,QAAQ,MAAM,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,SAAY,SAAS;AACjF,aAAO,KAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;IACnC;IAEA,gBAAgB,MAAM,KAAK,KAAK,QAAQ,QAAQ,OAAM,CAAE;IACxD,mBAAmB,MAAK;AACtB,cAAQ,QAAQ,MAAK;AACrB,aAAO,KAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;IACnC;;AAGF,QAAM,SAAS,CAAC,GAAG,OAAO,QAAQ,QAAQ,MAAM,GAAG,GAAG,OAAO,QAAQ,OAAO,CAAC,EAAE,IAC7E,CAAC,CAAC,KAAK,OAAO,MAAK;AACjB,UAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,WAAO,EAAE,QAAQ,IAAI,MAAM,GAAG,KAAK,GAAG,SAAS,IAAI,MAAM,QAAQ,CAAC,GAAG,QAAO;EAC9E,CAAC;AAGH,SAAO;IACL,aAAa;IACb,MAAM,OAAO,SAAO;AAClB,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAI,IAAI,aAAa,eAAe,QAAQ,WAAW,OAAO;AAC5D,eAAO,KAAK,KAAK;UACf,QAAQ;UACR,SAAS,QAAQ;UACjB,UAAU,QAAQ,QAAO,IAAK,QAAQ;UACtC,OAAO,QAAQ,MAAM,MAAK;UAC1B,YAAY,QAAQ,WAAU,EAAG;UACjC,SAAS,GAAG,YAAY;UACxB,GAAG,QAAQ,SAAQ;SACpB;MACH;AACA,UAAI,IAAI,aAAa,gBAAgB,CAAC,IAAI,SAAS,WAAW,GAAG,YAAY,GAAG,GAAG;AACjF,eAAO;MACT;AACA,YAAM,OAAO,IAAI,SAAS,MAAM,aAAa,MAAM,KAAK;AAExD,YAAM,QAAQ,QAAQ,WAAW,UAAU,SAAS,SAAS,SAAS;AACtE,UACE,CAAC,SACD,QAAQ,aAAa,UACrB,QAAQ,QAAQ,IAAI,gBAAgB,MAAM,QAAQ,UAClD;AACA,eAAO,WAAW,KAAK,oBAAoB,gBAAgB,EAAE;MAC/D;AACA,iBAAW,SAAS,QAAQ;AAC1B,YAAI,MAAM,WAAW,QAAQ;AAAQ;AACrC,cAAM,SAAS,WAAW,MAAM,SAAS,IAAI;AAC7C,YAAI,CAAC;AAAQ;AACb,YAAI;AACJ,YAAI;AACF,iBAAO,MAAM,SAAS,OAAO;QAC/B,QAAQ;AACN,iBAAO,WAAW,KAAK,gCAAgC;QACzD;AACA,eAAO,MAAM,QAAQ;UACnB;UACA;UACA;UACA,WAAW,eAAe,SAAS,GAAG;UACtC;SACD;MACH;AACA,aAAO,WACL,KACA,kBAAkB,QAAQ,MAAM,IAAI,IAAI,SAAS,YAAY,aAAa;IAE9E;;AAEJ;;;ACtUO,IAAM,2BAA2B,MAAyB;AAC/D,QAAM,MAAM,oBAAI,IAAG;AACnB,SAAO;IACL,KAAK,CAAC,YAAY,cAAa;AAC7B,UAAI,IAAI,YAAY,SAAS;IAC/B;IACA,KAAK,CAAC,eAAe,IAAI,IAAI,UAAU;IACvC,QAAQ,CAAC,eAAe,IAAI,OAAO,UAAU;IAC7C,OAAO,MAAM,IAAI,MAAK;IACtB,SAAS,MACP,CAAC,GAAG,GAAG,EACJ,IAAI,CAAC,CAAC,YAAY,SAAS,OAAO,EAAE,YAAY,UAAS,EAAG,EAC5D,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,cAAc,EAAE,UAAU,CAAC;;AAEhE;AAGO,IAAM,iBAAiB,CAAC,eAC7B,WAAW,UAAU,IACjB,GAAG,WAAW,MAAM,GAAG,CAAC,CAAC,WACzB,GAAG,WAAW,MAAM,GAAG,CAAC,CAAC,SAAI,WAAW,MAAM,EAAE,CAAC;;;AC/DhD,IAAM,WAAW,CAAC,UAAyB;AAChD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAQ,MAAM,WAAW,CAAC;AAC1B,WAAO,KAAK,KAAK,MAAM,QAAQ;EACjC;AACA,SAAO,SAAS;AAClB;AAEO,IAAM,YAAY,CAAC,OAAwB,MAAU;AAC1D,QAAM,UAAU,OAAO,SAAS,WAAW,SAAS,IAAI,IAAI,SAAS;AACrE,MAAI,QAAQ;AACZ,QAAM,OAAO,MAAK;AAChB,YAAS,QAAQ,eAAgB;AACjC,QAAI,IAAI;AACR,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACnC,SAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;AACxC,aAAS,IAAK,MAAM,QAAS,KAAK;EACpC;AACA,SAAO;IACL;IACA,KAAK,CAAC,KAAK,QAAQ,MAAM,KAAK,MAAM,KAAI,KAAM,MAAM,MAAM,EAAE;IAC5D,OAAO,MAAK;AACV,cAAQ;IACV;IACA,OAAO,MAAM;IACb,UAAU,CAACC,UAAQ;AACjB,UAAI,CAAC,OAAO,cAAcA,KAAI,KAAKA,QAAO,KAAKA,QAAO,YAAY;AAChE,cAAM,IAAI,WAAW,8CAA8C;MACrE;AACA,cAAQA,UAAS;IACnB;IACA,MAAM;;AAEV;;;AC0DA,IAAM,UAAU,CAAC,MAAiB,cAAsC;AACtE,MACE,KAAK,cAAc,UACnB,KAAK,cAAc,OACnB,KAAK,cAAc,UAAU,WAC7B;AACA,WAAO;EACT;AACA,MAAI,KAAK,gBAAgB,UAAa,KAAK,gBAAgB,UAAU;AAAa,WAAO;AACzF,MAAI,KAAK,WAAW,UAAa,KAAK,OAAO,YAAW,MAAO,UAAU,OAAO,YAAW,GAAI;AAC7F,WAAO;EACT;AACA,MAAI,KAAK,eAAe,UAAa,CAAC,UAAU,KAAK,WAAW,KAAK,UAAU;AAAG,WAAO;AACzF,SAAO;AACT;AAEA,IAAM,gBAAgB,CAAC,SAA6B;AAClD,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,UAAU,EAAE,gBAAgB,oBAAoB,GAAG,KAAK,QAAO;AACrE,MAAI,OAAO,KAAK,SAAS;AAAU,WAAO,IAAI,SAAS,KAAK,MAAM,EAAE,QAAQ,QAAO,CAAE;AACrF,MAAI,KAAK,SAAS;AAAM,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,SAAS,KAAK,WAAW,CAAA,EAAE,CAAE;AACzF,QAAM,OAAO,KAAK,SAAS,SAAY,EAAE,QAAQ,0BAAyB,IAAK,KAAK;AACpF,SAAO,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,QAAO,CAAE;AAC/D;AAOO,IAAM,sBAAsB,CACjC,MAAW,UAAU,CAAC,GACtB,QAAuC,CAAC,OAAO,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC,MAC9E;AACjB,QAAM,UAAmB,CAAA;AACzB,SAAO;IACL,IAAI,MAAI;AACN,YAAM,WAAW,QAAQ,UAAU,CAAC,MAAM,EAAE,KAAK,OAAO,KAAK,EAAE;AAC/D,YAAM,QAAe,EAAE,MAAM,WAAW,KAAK,SAAS,MAAM,MAAM,EAAC;AACnE,UAAI,YAAY;AAAG,gBAAQ,QAAQ,IAAI;;AAClC,gBAAQ,KAAK,KAAK;AACvB,aAAO;IACT;IACA,MAAM,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,EAAE,WAAW,MAAM,EAAE,KAAI,EAAG;IACpF,OAAO,IAAE;AACP,YAAM,QAAQ,QAAQ,UAAU,CAAC,MAAM,EAAE,KAAK,OAAO,EAAE;AACvD,UAAI,QAAQ;AAAG,eAAO;AACtB,cAAQ,OAAO,OAAO,CAAC;AACvB,aAAO;IACT;IACA,QAAK;AACH,cAAQ,SAAS;IACnB;IACA,MAAM,KAAK,WAAS;AAClB,YAAM,OAAmB,CAAA;AACzB,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,cAAc;AAAG;AAC3B,YAAI,CAAC,QAAQ,MAAM,MAAM,SAAS;AAAG;AACrC,cAAM,OAAO,MAAM,KAAK,QAAQ;AAEhC,YAAI,IAAI,KAAI,KAAM;AAAM;AACxB,cAAM;AACN,YAAI,MAAM,cAAc;AAAM,gBAAM;AACpC,cAAM,QAAQ,MAAM,KAAK,WAAW,MAAM,KAAK;AAC/C,YAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,gBAAM,MAAM,KAAK;QACnB;AACA,cAAM,MAAgB,EAAE,IAAI,MAAM,KAAK,GAAE;AACzC,YAAI,MAAM,KAAK,WAAW,QAAW;AACnC,cAAI,SAAS,EAAE,MAAM,MAAM,KAAK,QAAQ,QAAQ,MAAM,KAAK,UAAU,CAAA,EAAE;QACzE;AACA,YAAI,MAAM,KAAK,SAAS;AAAM,cAAI,OAAO;iBAChC,MAAM,KAAK,WAAW;AAAW,cAAI,WAAW,cAAc,MAAM,IAAI;AACjF,aAAK,KAAK,GAAG;AACb,YAAI,IAAI,QAAQ,IAAI;AAAU;MAChC;AACA,aAAO;IACT;;AAEJ;;;AC/LM,IAAO,wBAAP,cAAqC,MAAK;EACzB;EAArB,YAAqB,KAAW;AAC9B,UAAM,sBAAsB,GAAG,EAAE;AADd,SAAA,MAAA;AAEnB,SAAK,OAAO;EACd;;AAGF,IAAM,kBAAkB,CAAC,YAAoB,QAAQ,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AAGpF,IAAM,cAAc,CAAC,UAC1B,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA6B,SAAS;AAGzC,IAAM,aAAa,CAACC,WAA2B,QAAwB;AAC5E,MAAI,CAAC,IAAI,WAAW,IAAI;AAAG,UAAM,IAAI,sBAAsB,GAAG;AAC9D,MAAI,SAAkBA;AACtB,aAAW,OAAO,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG;AACzC,UAAM,UAAU,gBAAgB,GAAG;AACnC,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,EAAE,WAAW,SAAS;AACzE,YAAM,IAAI,sBAAsB,GAAG;IACrC;AACA,aAAU,OAAmC,OAAO;EACtD;AACA,MAAI,WAAW;AAAW,UAAM,IAAI,sBAAsB,GAAG;AAC7D,SAAO;AACT;AAMO,IAAM,QAAQ,CAAIA,WAA2B,UAAiC;AACnF,MAAI,UAAmB;AACvB,QAAM,OAAO,oBAAI,IAAG;AACpB,SAAO,YAAY,OAAO,GAAG;AAC3B,QAAI,KAAK,IAAI,QAAQ,IAAI;AAAG,YAAM,IAAI,sBAAsB,GAAG,QAAQ,IAAI,UAAU;AACrF,SAAK,IAAI,QAAQ,IAAI;AACrB,cAAU,WAAWA,WAAU,QAAQ,IAAI;EAC7C;AACA,SAAO;AACT;;;ACuEO,IAAM,eAAe;EAC1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;;ACAF,IAAM,kBAAkB,CACtBC,WACA,MACA,QACqB;AACrB,QAAM,SAAS,oBAAI,IAAG;AACtB,aAAW,OAAO,KAAK,cAAc,CAAA,GAAI;AACvC,UAAM,YAAY,MAAuBA,WAAU,GAAG;AACtD,WAAO,IAAI,GAAG,UAAU,EAAE,IAAI,UAAU,IAAI,IAAI,SAAS;EAC3D;AACA,aAAW,OAAO,OAAO,CAAA,GAAI;AAC3B,UAAM,YAAY,MAAuBA,WAAU,GAAG;AACtD,WAAO,IAAI,GAAG,UAAU,EAAE,IAAI,UAAU,IAAI,IAAI,SAAS;EAC3D;AACA,SAAO,CAAC,GAAG,OAAO,OAAM,CAAE;AAC5B;AAGO,IAAM,iBAAiB,CAACA,cAA0C;AACvE,QAAM,aAA0B,CAAA;AAChC,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQA,UAAS,KAAK,GAAG;AACzD,eAAW,UAAU,cAAc;AACjC,YAAM,YAAY,KAAK,MAAM;AAC7B,UAAI,WAAW,gBAAgB;AAAW;AAC1C,YAAM,YAA4C,CAAA;AAClD,iBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,UAAU,SAAS,GAAG;AACpE,kBAAU,MAAM,IAAI,MAAsBA,WAAU,QAAQ;MAC9D;AACA,iBAAW,KAAK;QACd,aAAa,UAAU;QACvB;QACA;QACA;QACA,YAAY,gBAAgBA,WAAU,MAAM,UAAU,UAAU;QAChE,aACE,UAAU,gBAAgB,SACtB,SACA,MAAyBA,WAAU,UAAU,WAAW;QAC9D;OACD;IACH;EACF;AACA,SAAO;AACT;;;ACnGA,IAAM,YAAY,CAAC,WAA4B;AAC7C,QAAM,OAAO,OAAO,QAAQ,GAAG;AAC/B,MAAI,SAAS;AAAI,WAAO,CAAC,MAAM;AAC/B,QAAM,OAAO,CAAC,OAAO,MAAM,GAAG,IAAI,CAAC;AACnC,QAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,QAAM,UAAU;AAChB,MAAI,QAAgC,QAAQ,KAAK,IAAI;AACrD,MAAI,WAAW;AACf,SAAO,UAAU,MAAM;AACrB,QAAI,MAAM,UAAU;AAAU,aAAO,CAAC,MAAM;AAC5C,SAAK,KAAK,MAAM,CAAC,KAAK,EAAE;AACxB,eAAW,MAAM,QAAQ,MAAM,CAAC,EAAE;AAClC,YAAQ,QAAQ,KAAK,IAAI;EAC3B;AACA,MAAI,aAAa,KAAK;AAAQ,WAAO,CAAC,MAAM;AAC5C,SAAO;AACT;AAEA,IAAM,UAAU,CAAC,YAAoB,oBAAoB,KAAK,OAAO;AAMrE,IAAM,MAAM,CAAC,QAAgB,KAAsB,UAA0B;AAC3E,MAAI,QAAQ,aAAa;AACvB,WAAO,eAAe,QAAQ,KAAK;MACjC;MACA,YAAY;MACZ,UAAU;MACV,cAAc;KACf;AACD;EACF;AACA;AAAE,SAA8C,GAAG,IAAI;AACzD;AAEA,IAAM,SAAS,CAAC,QAAoB,MAAgB,UAAiB;AACnE,MAAI,SAAoB;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,UAAU,KAAK,CAAC;AACtB,UAAM,OAAO,MAAM,KAAK,SAAS;AACjC,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAM,QACJ,YAAY,KAAK,OAAO,SAAS,QAAQ,OAAO,IAAI,OAAO,OAAO,IAAI;AACxE,UAAI,UAAU;AAAW;AACzB,UAAI,MAAM;AACR,YAAI,QAAQ,OAAO,KAAK;AACxB;MACF;AACA,YAAM,OAA8B,OAAO,OAAO,QAAQ,KAAK,IAC1D,OAAqC,KAAK,IAC3C;AACJ,UAAI,SAAS,UAAa,OAAO,SAAS,UAAU;AAClD,cAAM,UAAqB,KAAK,IAAI,CAAC,MAAM,MAAM,QAAQ,KAAK,IAAI,CAAC,CAAW,IAAI,CAAA,IAAK,CAAA;AACvF,YAAI,QAAQ,OAAO,OAAO;AAC1B,iBAAS;MACX,OAAO;AACL,iBAAS;MACX;AACA;IACF;AACA,QAAI,OAAO,WAAW;AAAU;AAChC,QAAI,MAAM;AACR,UAAI,QAAQ,SAAS,KAAK;AAC1B;IACF;AACA,UAAM,cAAc,KAAK,IAAI,CAAC;AAC9B,UAAM,WAAkC,OAAO,OAAO,QAAQ,OAAO,IAChE,OAAqC,OAAO,IAC7C;AACJ,QAAI,aAAa,UAAa,OAAO,aAAa,UAAU;AAC1D,YAAM,UAAqB,gBAAgB,MAAM,QAAQ,WAAW,IAAI,CAAA,IAAK,CAAA;AAC7E,UAAI,QAAQ,SAAS,OAAO;AAC5B,eAAS;IACX,OAAO;AACL,eAAS;IACX;EACF;AACF;AAGO,IAAM,kBAAkB,CAAC,UAAiD;AAC/E,QAAM,MAAkB,CAAA;AACxB,aAAW,CAAC,QAAQ,KAAK,KAAK;AAAO,WAAO,KAAK,UAAU,MAAM,GAAG,KAAK;AACzE,SAAO,QAAQ,GAAG;AACpB;AAGA,IAAM,UAAU,CAAC,UAA+B;AAC9C,MAAI,OAAO,UAAU;AAAU,WAAO;AACtC,MAAI,MAAM,QAAQ,KAAK;AAAG,WAAO,MAAM,OAAO,CAAC,SAAS,SAAS,MAAS,EAAE,IAAI,OAAO;AACvF,QAAM,MAAkB,CAAA;AACxB,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK;AAAG,QAAI,KAAK,KAAK,QAAQ,IAAI,CAAC;AAC5E,SAAO;AACT;AAGO,IAAM,aAAa,CAACC,UAA4B;AACrD,QAAM,SAASA,MAAK,WAAW,GAAG,IAAIA,MAAK,MAAM,CAAC,IAAIA;AACtD,SAAO,gBAAgB,IAAI,gBAAgB,MAAM,EAAE,QAAO,CAAE;AAC9D;;;ACvKO,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AAGxB,IAAM,cAAc,CAAC,gBAA8D;AACxF,MAAI,CAAC;AAAa,WAAO;AACzB,QAAM,UAAU,YAAY,MAAM,GAAG,EAAE,CAAC,GAAG,KAAI,EAAG,YAAW;AAC7D,SAAO,UAAU,UAAU;AAC7B;AAEA,IAAM,kBAAkB,CAAC,cACvB,cAAc,mBAAmB,UAAU,SAAS,OAAO,KAAK,cAAc;AAUhF,IAAM,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,MAAK,CAAE;AAO/C,IAAM,aAAa,CACxB,aACA,UACe;AACf,MAAI,MAAM,eAAe;AAAG,WAAO,EAAE,MAAM,QAAO;AAClD,QAAM,YAAY,YAAY,WAAW;AACzC,MAAI,cAAc;AAAW,WAAO,EAAE,MAAM,SAAS,OAAO,MAAK;AACjE,MAAI,gBAAgB,SAAS,GAAG;AAC9B,UAAMC,QAAO,KAAK,OAAO,KAAK;AAC9B,QAAI;AACF,aAAO,EAAE,MAAM,QAAQ,OAAO,KAAK,MAAMA,KAAI,EAAC;IAChD,SAAS,OAAO;AACd,aAAO;QACL,MAAM;QACN;QACA,MAAAA;QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;;IAEhE;EACF;AACA,MAAI,cAAc,iBAAiB;AACjC,WAAO,EAAE,MAAM,QAAQ,OAAO,WAAW,KAAK,OAAO,KAAK,CAAC,EAAC;EAC9D;AACA,MAAI,UAAU,WAAW,OAAO;AAAG,WAAO,EAAE,MAAM,QAAQ,OAAO,KAAK,OAAO,KAAK,EAAC;AACnF,SAAO,EAAE,MAAM,SAAS,OAAO,MAAK;AACtC;AAGO,IAAM,WAAW,OAAO,YAAqD;AAClF,QAAM,QAAQ,IAAI,WAAW,MAAM,QAAQ,YAAW,CAAE;AACxD,SAAO,WAAW,QAAQ,QAAQ,IAAI,cAAc,GAAG,KAAK;AAC9D;;;AC1DO,IAAM,UAAU,CACrB,QACA,MACA,UAAkC,CAAA,MAElC,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;EACjC;EACA,SAAS,EAAE,gBAAgB,iBAAiB,GAAG,QAAO;CACvD;AAGG,IAAO,YAAP,cAAyB,MAAK;EAEvB;EACA;EACA;EAHX,YACW,QACA,MACA,UAAkC,CAAA,GAAE;AAE7C,UAAM,QAAQ,MAAM,EAAE;AAJb,SAAA,SAAA;AACA,SAAA,OAAA;AACA,SAAA,UAAA;AAGT,SAAK,OAAO;EACd;EAEA,aAAU;AACR,UAAM,cAAc,KAAK,QAAQ,cAAc,GAAG,MAAM,KAAK,CAAC,EAAE,CAAC,GAAG,KAAI,EAAG,YAAW;AACtF,QAAI,gBAAgB,cAAc;AAChC,aAAO,IAAI,SAAS,OAAO,KAAK,IAAI,GAAG;QACrC,QAAQ,KAAK;QACb,SAAS,KAAK;OACf;IACH;AACA,WAAO,QAAQ,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAO;EACrD;;;;AC/BF,IAAM,WAAW;AAGjB,IAAM,MAAM,CAAC,UAAyB;AACpC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAQ,MAAM,WAAW,CAAC;AAC1B,WAAO,KAAK,KAAK,MAAM,QAAU,MAAM;EACzC;AACA,UAAQ,SAAS;AACjB,SAAO,KAAK,KAAK,MAAM,UAAU,MAAM;AACvC,UAAQ,SAAS;AACjB,SAAO,SAAS;AAClB;AAGO,IAAM,cAAc,CAAC,OAAe,WAA0B;AACnE,MAAI,MAAM;AACV,MAAIC,SAAQ;AACZ,SAAO,IAAI,SAAS,QAAQ;AAC1B,QAAI,OAAO,IAAI,GAAG,KAAK,IAAIA,QAAO,EAAE;AACpC,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,SAAS,QAAQ,KAAK;AACjD,aAAO,SAAS,OAAO,OAAO,SAAS,MAAM;AAC7C,aAAO,KAAK,MAAM,OAAO,SAAS,MAAM;IAC1C;EACF;AACA,SAAO;AACT;;;ACHO,IAAM,uBAAuB;AAM7B,IAAM,gBAAgB,CAAC,OAAe,yBAAiC;AAC5E,QAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC;AAC7C,QAAM,QAAQ,oBAAI,IAAG;AACrB,MAAI,WAAW;AACf,QAAM,QAAQ,oBAAI,QAAO;AACzB,QAAM,UAAU,CAAC,SACf,KAAK,QAAQ,SAAS,WAClB,KAAK,UACL,CAAC,GAAG,KAAK,QAAQ,MAAM,KAAK,IAAI,GAAG,GAAG,KAAK,QAAQ,MAAM,GAAG,KAAK,IAAI,CAAC;AAC5E,SAAO;IACL,MAAM;IACN,OAAO,OAAK;AACV,UAAI,aAAa;AAAG;AACpB,YAAM,IAAI,OAAO,UAAU;AAC3B,UAAI,OAAO,MAAM,IAAI,MAAM,SAAS;AACpC,UAAI,CAAC,MAAM;AACT,eAAO,EAAE,SAAS,CAAA,GAAI,MAAM,EAAC;AAC7B,cAAM,IAAI,MAAM,WAAW,IAAI;MACjC;AACA,UAAI,KAAK,QAAQ,SAAS;AAAU,aAAK,QAAQ,KAAK,KAAK;WACtD;AACH,aAAK,QAAQ,KAAK,IAAI,IAAI;AAC1B,aAAK,QAAQ,KAAK,OAAO,KAAK;MAChC;IACF;IACA,KAAK,QAAQ,CAAA,GAAE;AACb,YAAM,SACJ,MAAM,cAAc,SAChB,QAAQ,MAAM,IAAI,MAAM,SAAS,KAAK,EAAE,SAAS,CAAA,GAAI,MAAM,EAAC,CAAE,IAC9D,CAAC,GAAG,MAAM,OAAM,CAAE,EACf,QAAQ,OAAO,EACf,KAAK,CAAC,GAAG,OAAO,MAAM,IAAI,CAAC,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE;AACjE,YAAM,UAAU,OAAO,OACrB,CAAC,WACE,MAAM,gBAAgB,UAAa,MAAM,gBAAgB,MAAM,iBAC/D,MAAM,WAAW,UAAa,MAAM,WAAW,MAAM,YACrD,MAAM,UAAU,UAAa,KAAK,MAAM,MAAM,EAAE,KAAK,MAAM,MAAM;AAEtE,aAAO,MAAM,UAAU,SAAY,QAAQ,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI;IAChF;IACA,MAAM,WAAS;AACb,UAAI,cAAc;AAAW,cAAM,MAAK;;AACnC,cAAM,OAAO,SAAS;IAC7B;;AAEJ;AAYA,IAAM,QAAQ,oBAAI,QAAO;AAMlB,IAAM,mBAAmB,CAAC,UAAoB,UAAkC;AACrF,QAAM,WAAW,MAAM,IAAI,QAAQ;AACnC,QAAM,IAAI,UAAU;IAClB,GAAG;IACH,GAAG;IACH,GAAI,UAAU,OAAO,MAAM,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,KAAK,GAAG,MAAM,IAAG,EAAE,IAAK,CAAA;GAChF;AACD,SAAO;AACT;AAEO,IAAM,gBAAgB,CAAC,aAAkD,MAAM,IAAI,QAAQ;;;AC9C3F,IAAM,gBAAgB,MAAc;AACzC,MAAI,WAAW;AACf,MAAI,SAAS;AACb,MAAI,kBAAkB;AACtB,QAAM,cAAc,oBAAI,IAAG;AAC3B,QAAM,YAAY,oBAAI,IAAG;AACzB,SAAO;IACL,OAAO,OAAK;AACV;AACA,yBAAmB,MAAM;AACzB,UAAI,MAAM,YAAY;AAAW;AACjC,YAAM,MAAM,GAAG,MAAM,eAAe,aAAa,IAAI,MAAM,MAAM;AACjE,kBAAY,IAAI,MAAM,YAAY,IAAI,GAAG,KAAK,KAAK,CAAC;AACpD,UAAI,MAAM,WAAW;AACnB,cAAM,QAAQ,GAAG,MAAM,MAAM,IAAI,MAAM,IAAI;AAC3C,kBAAU,IAAI,QAAQ,UAAU,IAAI,KAAK,KAAK,KAAK,CAAC;MACtD;IACF;IACA,QAAQ,OAAO;MACb;MACA,aAAa,OAAO,YAAY,CAAC,GAAG,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;MACvF,WAAW,CAAC,GAAG,SAAS,EACrB,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EACtD,IAAI,CAAC,CAAC,OAAO,KAAK,MAAK;AACtB,cAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,eAAO,EAAE,QAAQ,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,MAAM,MAAM,QAAQ,CAAC,GAAG,MAAK;MAC7E,CAAC;MACH;MACA;;IAEF,QAAK;AACH,iBAAW;AACX,eAAS;AACT,wBAAkB;AAClB,kBAAY,MAAK;AACjB,gBAAU,MAAK;IACjB;;AAEJ;;;AChEA,IAAM,iBAAiB;AAUjB,IAAO,WAAP,MAAe;EACV;EACQ;EACA;EACA,QAAQ,oBAAI,IAAG;EACf,QAAQ,oBAAI,IAAG;;EAEf,YAAY,oBAAI,IAAG;;EAEnB,aAAa,oBAAI,IAAG;EACpB,eAAe,oBAAI,IAAG;EAC/B,WAAW;EAEnB,YAAY,UAA2B,CAAA,GAAE;AACvC,UAAM,MAAM,QAAQ,kBAAkB;AACtC,QAAI,CAAC,OAAO,cAAc,GAAG,KAAK,MAAM;AACtC,YAAM,IAAI,WAAW,2CAA2C;AAClE,SAAK,iBAAiB;AACtB,SAAK,MAAM,QAAQ,QAAQ,MAAM,KAAK;AACtC,SAAK,SAAS,QAAQ,OAAO,CAAC,aAAa,MAAM,SAAS,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;EACzF;;EAGA,OAAO,OAAU,UAAyB,CAAA,GAAE;AAC1C,UAAM,SAAS,QAAQ,UAAU;AACjC,SAAK,aAAa,MAAM;AACxB,UAAM,SAAS,QAAQ,WAAW,SAAa,KAAK,MAAM,IAAI,MAAM,KAAK,OAAQ,QAAQ;AACzF,QAAI,WAAW,QAAQ,CAAC,KAAK,MAAM,IAAI,MAAM;AAAG,YAAM,IAAI,WAAW,iBAAiB,MAAM,EAAE;AAC9F,UAAM,KAAK,KAAK,OAAO,EAAE,KAAK,QAAQ;AACtC,QAAI,KAAK,MAAM,IAAI,EAAE;AAAG,YAAM,IAAI,WAAW,2BAA2B,EAAE,EAAE;AAC5E,UAAM,aAAa,OAAO,OAAO,EAAE,IAAI,QAAQ,QAAQ,IAAI,KAAK,IAAG,GAAI,MAAK,CAAE;AAC9E,SAAK,MAAM,IAAI,IAAI,UAAU;AAC7B,SAAK,SAAS,QAAQ,EAAE;AACxB,SAAK,QAAQ,KAAK,cAAc;AAChC,WAAO;EACT;;EAGA,KAAK,QAAgB,UAAuB,CAAA,GAAE;AAC5C,SAAK,aAAa,MAAM;AACxB,QAAI,KAAK,MAAM,IAAI,MAAM;AAAG,YAAM,IAAI,WAAW,0BAA0B,MAAM,EAAE;AACnF,UAAM,OAAO,QAAQ,QAAQ,KAAK,MAAM,IAAI,MAAM;AAClD,QAAI,SAAS;AAAW,aAAO;AAC/B,UAAM,aAAa,KAAK,IAAI,IAAI;AAChC,SAAK,SAAS,QAAQ,WAAW,EAAE;AACnC,WAAO;EACT;;EAGA,SAAS,QAAgB,IAAgB;AACvC,SAAK,aAAa,MAAM;AACxB,UAAM,aAAa,KAAK,IAAI,EAAE;AAC9B,SAAK,SAAS,QAAQ,WAAW,EAAE;AACnC,WAAO;EACT;EAEA,IAAI,IAAgB;AAClB,UAAM,aAAa,KAAK,MAAM,IAAI,EAAE;AACpC,QAAI,CAAC;AAAY,YAAM,IAAI,WAAW,iBAAiB,EAAE,EAAE;AAC3D,WAAO;EACT;EAEA,KAAK,SAAS,QAAM;AAClB,UAAM,KAAK,KAAK,MAAM,IAAI,MAAM;AAChC,WAAO,OAAO,SAAY,SAAY,KAAK,IAAI,EAAE;EACnD;EAEA,UAAU,QAAc;AACtB,WAAO,KAAK,MAAM,IAAI,MAAM;EAC9B;EAEA,WAAQ;AACN,WAAO,OAAO,OACZ,OAAO,YAAY,CAAC,GAAG,KAAK,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,CAAC;EAExF;EAEA,cAAW;AACT,WAAO,CAAC,GAAG,KAAK,MAAM,OAAM,CAAE;EAChC;;EAGA,IAAI,OAAI;AACN,WAAO,KAAK,MAAM;EACpB;;EAGA,OAAO,IAAgB;AACrB,UAAM,aAAa,KAAK,IAAI,EAAE;AAC9B,SAAK,aAAa,IAAI,KAAK,KAAK,aAAa,IAAI,EAAE,KAAK,KAAK,CAAC;AAC9D,SAAK,aAAa,EAAE;AACpB,WAAO;EACT;;EAGA,QAAQ,IAAgB;AACtB,QAAI,CAAC,KAAK,MAAM,IAAI,EAAE;AAAG,aAAO;AAChC,UAAM,OAAO,KAAK,aAAa,IAAI,EAAE,KAAK;AAC1C,QAAI,SAAS;AAAG,aAAO;AACvB,QAAI,SAAS;AAAG,WAAK,aAAa,OAAO,EAAE;;AACtC,WAAK,aAAa,IAAI,IAAI,OAAO,CAAC;AACvC,SAAK,gBAAgB,EAAE;AACvB,SAAK,QAAQ,KAAK,cAAc;AAChC,WAAO;EACT;EAEA,aAAa,QAAc;AACzB,QAAI,WAAW;AAAQ,YAAM,IAAI,WAAW,2BAA2B;AACvE,UAAM,WAAW,KAAK,MAAM,IAAI,MAAM;AACtC,UAAM,UAAU,KAAK,MAAM,OAAO,MAAM;AACxC,QAAI,aAAa;AAAW,WAAK,gBAAgB,QAAQ;AACzD,SAAK,QAAQ,KAAK,cAAc;AAChC,WAAO;EACT;;;;;;EAOA,GAAG,MAAM,KAAK,gBAAc;AAC1B,QAAI,CAAC,OAAO,cAAc,GAAG,KAAK,MAAM;AACtC,YAAM,IAAI,WAAW,gCAAgC;AACvD,UAAM,UAA0B,CAAA;AAChC,SAAK,QAAQ,KAAK,OAAO;AACzB,WAAO;EACT;EAEQ,QAAQ,KAAa,SAAwB;AACnD,WAAO,KAAK,MAAM,OAAO,OAAO,KAAK,UAAU,OAAO,GAAG;AACvD,YAAM,KAAK,KAAK,UAAU,OAAM,EAAG,KAAI,EAAG;AAC1C,WAAK,UAAU,OAAO,EAAE;AACxB,WAAK,MAAM,OAAO,EAAE;AACpB,eAAS,KAAK,EAAE;IAClB;EACF;EAEQ,SAAS,QAAgB,IAAgB;AAC/C,UAAM,WAAW,KAAK,MAAM,IAAI,MAAM;AACtC,QAAI,aAAa;AAAI;AACrB,QAAI,aAAa;AAAW,WAAK,gBAAgB,QAAQ;AACzD,SAAK,MAAM,IAAI,QAAQ,EAAE;AACzB,SAAK,aAAa,EAAE;EACtB;EAEQ,aAAa,IAAgB;AACnC,SAAK,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,EAAE,KAAK,KAAK,CAAC;AAC1D,SAAK,UAAU,OAAO,EAAE;EAC1B;EAEQ,gBAAgB,IAAgB;AACtC,UAAM,QAAQ,KAAK,WAAW,IAAI,EAAE,KAAK,KAAK;AAC9C,QAAI,OAAO;AAAG,WAAK,WAAW,IAAI,IAAI,IAAI;SACrC;AACH,WAAK,WAAW,OAAO,EAAE;AACzB,UAAI,KAAK,MAAM,IAAI,EAAE;AAAG,aAAK,UAAU,IAAI,EAAE;IAC/C;EACF;EAEQ,aAAa,QAAc;AACjC,QAAI,CAAC,eAAe,KAAK,MAAM;AAAG,YAAM,IAAI,WAAW,qBAAqB,cAAc,EAAE;EAC9F;;;;AC5MF,SAAS,gBAAgB;AAIlB,IAAM,sBAAsB,MAAoB,IAAI,SAAQ;AAG5D,IAAM,gBAAgB,CAAC,WAC5B,UAAU,oBAAmB;;;ACC/B,IAAM,wBAAwB,CAAC,WAAwB;AACrD,SAAO,KAAK;;;;;GAKX;AACH;AAQO,IAAM,UAAU,CAAC,QAAsB,eAA0C;AACtF,wBAAsB,MAAM;AAC5B,QAAM,UAAU,IAAI,IAClB,OACG,QAAQ,kCAAkC,EAC1C,IAAG,EACH,IAAI,CAACC,SAAQA,KAAI,EAAE,CAAC;AAEzB,QAAM,UAAU,WAAW,OAAO,CAAC,cAAc,CAAC,QAAQ,IAAI,UAAU,EAAE,CAAC;AAC3E,MAAI,QAAQ,WAAW;AAAG;AAE1B,QAAM,SAAS,OAAO,QAAQ,8DAA8D;AAC5F,QAAM,MAAM,KAAK,MAAM,KAAK,IAAG,IAAK,GAAI;AACxC,SAAO,YAAY,MAAK;AACtB,eAAW,aAAa,SAAS;AAC/B,aAAO,KAAK,UAAU,GAAG;AACzB,aAAO,IAAI,UAAU,IAAI,GAAG;IAC9B;EACF,CAAC;AACH;;;ACnCO,IAAM,kBAAwC;EACnD;IACE,IAAI;IACJ,KAAK;;;;;;;;;;;;;;;;;;;;;AAuBF,IAAM,cAAc,CAAC,WAA8B;AACxD,UAAQ,QAAQ,eAAe;AACjC;AAGO,IAAM,iBAAiB,CAAC,QAAsB,cAA2B;AAC9E,SAAO,YAAY,MAAK;AACtB,WAAO,QAAQ,qDAAqD,EAAE,IAAI,SAAS;AACnF,WAAO,QAAQ,uDAAuD,EAAE,IAAI,SAAS;EACvF,CAAC;AACH;;;AClCO,IAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACgBnB,SAAUC,UAAS,OAAc;AACrC,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGM,SAAU,gBACd,KACA,MACA,SACA,SAAgB;AAEhB,QAAM,OAAO,CAAC,OAAgB,QAA8B;AAC1D,QAAI,OAAO,UAAU;AAAU,aAAO;AACtC,UAAM,UAAU,MAAM,KAAI;AAC1B,QAAI,YAAY;AAAI,aAAO;AAC3B,WAAO,QAAQ,SAAS,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI;EACxD;AACA,QAAM,UAAU,CAAC,UAAiC;AAChD,QAAI,OAAO,UAAU,YAAY,MAAM,SAAS;AAAM,aAAO;AAC7D,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,KAAK;AACzB,UAAI,IAAI,aAAa,YAAY,IAAI,aAAa;AAAS,eAAO;AAClE,aAAO,IAAI;IACb,QAAQ;AACN,aAAO;IACT;EACF;AACA,QAAM,WAAW,CAAC,UAAiC;AACjD,QAAI,OAAO,UAAU;AAAU,aAAO;AACtC,UAAM,MAAM,MAAM,KAAI;AACtB,WAAO,sBAAsB,KAAK,GAAG,IAAI,MAAM;EACjD;AACA,QAAM,WAAW,CAAC,UAAyB;AACzC,QAAI;AACF,aAAO,IAAI,IAAI,KAAK,EAAE,SAAS,QAAQ,UAAU,EAAE;IACrD,QAAQ;AACN,aAAO;IACT;EACF;AACA,OAAK,gBAAe;AACpB,OAAK,SAAS;AACd,MAAI,CAACA,UAAS,OAAO,KAAK,CAAC,OAAO,OAAO,SAAS,OAAO;AAAG;AAC5D,QAAMC,OAAM,QAAQ,OAAO;AAC3B,MAAI,CAACD,UAASC,IAAG;AAAG;AACpB,QAAM,SAAS,KAAKA,KAAI,QAAQ,EAAE;AAClC,QAAM,UAAU,QAAQA,KAAI,OAAO;AACnC,QAAM,QAAQ,QAAQA,KAAI,KAAK;AAC/B,QAAM,OAAO,QAAQA,KAAI,IAAI;AAC7B,QAAM,OAAO,QAAQA,KAAI,IAAI;AAC7B,QAAM,QAAQ,SAASA,KAAI,KAAK;AAChC,QAAM,cAAc,KAAKA,KAAI,aAAa,GAAG;AAC7C,MAAI,WAAW,QAAS,YAAY,QAAQ,UAAU,QAAQ,SAAS;AAAO;AAC9E,QAAM,MAAM,CAAiB,SAAc;AACzC,SAAK,OAAO,IAAI;AAChB,WAAO;EACT;AACA,MAAI,SAAS,MAAM;AACjB,UAAM,MAAM,IAAI,cAAc,KAAK;AACnC,QAAI,MAAM;AACV,QAAI,MAAM;AACV,QAAI,QAAQ;AACZ,QAAI,SAAS;AACb,QAAI,WAAW;AACf,QAAI,iBAAiB;AACrB,QAAI,UAAU;AAAM,UAAI,MAAM,cAAc;AAC5C,QAAI,GAAG;EACT;AACA,QAAM,OAAO,IAAI,cAAc,MAAM;AACrC,OAAK,YAAY;AACjB,OAAK,cAAc;AACnB,MAAI,gBAAgB;AAAM,SAAK,QAAQ;AACvC,MAAI,IAAI;AACR,QAAM,MAAM,MAAsB;AAChC,UAAM,OAAO,IAAI,cAAc,MAAM;AACrC,SAAK,YAAY;AACjB,SAAK,aAAa,eAAe,MAAM;AACvC,SAAK,cAAc;AACnB,WAAO;EACT;AACA,QAAM,OAAO,CAAC,MAAc,OAAe,UAAoC;AAC7E,UAAM,OAAO,IAAI,cAAc,GAAG;AAClC,SAAK,YAAY;AACjB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,MAAM;AACX,SAAK,iBAAiB;AACtB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,WAAO;EACT;AACA,MAAI,YAAY,MAAM;AACpB,QAAI,IAAG,CAAE;AACT,QAAI,KAAK,SAAS,SAAS,OAAO,GAAG,GAAG,MAAM,UAAU,CAAC;EAC3D;AACA,MAAI,UAAU,MAAM;AAClB,QAAI,IAAG,CAAE;AACT,QAAI,KAAK,OAAO,QAAQ,YAAY,MAAM,EAAE,CAAC;EAC/C;AACA,MAAI,SAAS,MAAM;AACjB,QAAI,IAAG,CAAE;AACT,QAAI,KAAK,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC;EAClD;AACA,OAAK,gBAAgB,QAAQ;AAC7B,OAAK,SAAS;AAChB;AAGM,SAAU,gBAAgB,KAAkB;AAChD,QAAM,YAAY,IAAI,OAAO,IAAI,QAAQ;AACzC,MAAI,YAAY,IAAI;AACpB,MAAI,WAAW;AACb,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,WAAW,IAAI,SAAS,IAAI;AAChD,YAAM,QACJ,IAAI,aAAa,eACjB,IAAI,aAAa,eACjB,IAAI,aAAa,SACjB,IAAI,aAAa,WACjB,IAAI,WAAW,IAAI,SAAS;AAC9B,WAAK,IAAI,aAAa,YAAY,IAAI,aAAa,YAAY;AAAO,oBAAY,IAAI;IACxF,QAAQ;AACN,kBAAY,IAAI;IAClB;EACF;AACA,QAAM,aAAa,IAAI,EAAE,QAAQ;AACjC,QAAM,YAAY,IAAI,SAAS,cAAc,0BAA0B;AACvE,QAAM,eAAe,WAAW,aAAa,cAAc,KAAK;AAChE,MAAI,eAAe;AAAM;AACzB,MACG,MAAM,WAAW;IAChB,SAAS,EAAE,QAAQ,mBAAkB;IACrC,QAAQ,YAAY,QAAQ,GAAI;GACjC,EACA,KAAK,OAAO,aAAY;AACvB,QAAI,CAAC,SAAS;AAAI,aAAO;AACzB,UAAM,UAAmB,MAAM,SAAS,KAAI;AAC5C,WAAO;EACT,CAAC,EACA,KAAK,CAAC,YAAW;AAChB,oBAAgB,IAAI,UAAU,YAAY,cAAc,OAAO;EACjE,CAAC,EACA,MAAM,MAAK;EAAE,CAAC;AACnB;AAOM,SAAU,gBAAgB,OAAc;AAC5C,MAAI,CAACD,UAAS,KAAK;AAAG,UAAM,IAAI,MAAM,0CAA0C;AAChF,MAAI,CAAC,OAAO,OAAO,OAAO,SAAS,KAAK,MAAM,YAAY,UAAa,MAAM,YAAY,MAAM;AAC7F,WAAO,EAAE,SAAS,CAAA,EAAE;EACtB;AACA,MAAI,CAAC,MAAM,QAAQ,MAAM,OAAO;AAAG,UAAM,IAAI,MAAM,uCAAuC;AAC1F,SAAO;IACL,SAAS,MAAM,QAAQ,QAAQ,CAAC,SAAQ;AACtC,UAAI,CAACA,UAAS,IAAI,KAAK,OAAO,KAAK,SAAS;AAAU,eAAO,CAAA;AAC7D,aAAO,CAAC,EAAE,MAAM,KAAK,KAAI,CAAE;IAC7B,CAAC;;AAEL;AAGM,SAAU,UAAU,QAAuB;AAC/C,QAAM,aAAa,CAAC,UAAU,UAAU,WAAW,QAAQ,UAAU,SAAS,SAAS;AACvF,QAAM,UAAU,CAAC,YAAY,YAAY,OAAO;AAChD,QAAM,cAAc,CAAC,UACnB,OAAO,UAAU,YAAY,WAAW,KAAK,CAAC,SAAS,SAAS,KAAK;AACvE,QAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,QAAQ,KAAK,CAAC,WAAW,WAAW,KAAK;AACxE,QAAME,YAAW,CAACC,UAAyB;AACzC,UAAM,QAAiB,KAAK,MAAMA,KAAI;AACtC,WAAO;EACT;AACA,QAAM,MAAM,CAAC,UACX,OAAO,SAAS,EAAE,EAAE,QAAQ,YAAY,CAAC,SAAQ;AAC/C,YAAQ,MAAM;MACZ,KAAK;AACH,eAAO;MACT,KAAK;AACH,eAAO;MACT,KAAK;AACH,eAAO;MACT,KAAK;AACH,eAAO;MACT;AACE,eAAO;IACX;EACF,CAAC;AACH,QAAM,KAAK,CAAwB,IAAY,SAAwB;AACrE,UAAM,OAAO,SAAS,eAAe,EAAE;AACvC,QAAI,EAAE,gBAAgB;AAAO,YAAM,IAAI,MAAM,2BAA2B,EAAE,EAAE;AAC5E,WAAO;EACT;AACA,QAAM,eAAe,CAAC,MAAe,aAA4B;AAC/D,QAAI,CAACH,UAAS,IAAI;AAAG,aAAO;AAC5B,UAAM,QAAQ,KAAK;AACnB,QAAI,CAACA,UAAS,KAAK,KAAK,OAAO,MAAM,YAAY,YAAY,MAAM,YAAY,IAAI;AACjF,aAAO;IACT;AACA,WAAO,MAAM;EACf;AACA,QAAM,cAAc,CAAC,OAAgB,UAA4B;AAC/D,QAAI,UAAU,UAAa,UAAU;AAAM,aAAO,CAAA;AAClD,QAAI,CAAC,MAAM,QAAQ,KAAK;AAAG,YAAM,IAAI,MAAM,GAAG,KAAK,iBAAiB;AACpE,WAAO;EACT;AAEA,QAAM,QAQF;IACF,WAAW;IACX,KAAK,eAAe,QAAQ,uBAAuB,KAAK;IACxD,MAAM;IACN,YAAY;IACZ,OAAO;IACP,OAAO;IACP,SAAS;;AAEX,QAAM,WAAW,IAAI,IAAI,OAAO,cAAc;AAC9C,QAAM,SAAS,GAAG,UAAU,WAAW;AACvC,QAAM,WAAW,GAAG,aAAa,gBAAgB;AACjD,WAAS,QAAQ,MAAM;AACvB,QAAM,SAAS,IAAI,gBAAgB,SAAS,MAAM;AAClD,QAAM,WAAW,OAAO,IAAI,KAAK;AACjC,MAAI,UAAU;AACZ,UAAM,MAAM;AACZ,aAAS,QAAQ,MAAM;AACvB,mBAAe,QAAQ,yBAAyB,MAAM,GAAG;AACzD,WAAO,OAAO,KAAK;AACnB,UAAM,OAAO,OAAO,SAAQ;AAC5B,YAAQ,aAAa,MAAM,IAAI,SAAS,YAAY,OAAO,IAAI,IAAI,KAAK,GAAG;EAC7E;AACA,QAAM,iBAAiB,OAAO,IAAI,WAAW;AAC7C,MAAI;AAAgB,UAAM,YAAY;AAEtC,QAAM,YAAY,CAAC,UAAwB;AACzC,WAAO,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO,UAAU,IAAI,MAAM;EAC7B;AACA,QAAM,aAAa,MAAW;AAC5B,WAAO,UAAU,OAAO,MAAM;EAChC;AAEA,QAAM,MAAM,OAAO,QAAgB,MAAc,SAAoC;AACnF,UAAM,UAAkC,EAAE,QAAQ,mBAAkB;AACpE,QAAI,MAAM,QAAQ;AAAI,cAAQ,OAAO,cAAc,IAAI,MAAM;AAC7D,QAAI,MAAM,cAAc;AAAI,cAAQ,yBAAyB,IAAI,MAAM;AACvE,QAAI,SAAS;AAAW,cAAQ,cAAc,IAAI;AAClD,UAAM,OAAoB,EAAE,QAAQ,QAAO;AAC3C,QAAI,SAAS;AAAW,WAAK,OAAO,KAAK,UAAU,IAAI;AACvD,UAAM,WAAW,MAAM,MAAM,OAAO,cAAc,MAAM,IAAI;AAC5D,UAAMG,QAAO,MAAM,SAAS,KAAI;AAChC,QAAI,OAAgB;AACpB,QAAIA,UAAS,IAAI;AACf,UAAI;AACF,eAAOD,UAASC,KAAI;MACtB,QAAQ;AACN,eAAO,EAAE,KAAKA,MAAI;MACpB;IACF;AACA,QAAI,SAAS,WAAW,KAAK;AAC3B,eAAS,MAAK;AACd,YAAM,IAAI,MAAM,aAAa,MAAM,oBAAoB,CAAC;IAC1D;AACA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,aAAa,MAAM,GAAG,SAAS,MAAM,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;IAC5E;AACA,WAAO;EACT;AACA,QAAM,YAAY,OAAO,SAAkC;AACzD,UAAM,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,EAAE,QAAQ,mBAAkB,EAAE,CAAE;AAC9E,QAAI,CAAC,SAAS;AAAI,YAAM,IAAI,MAAM,GAAG,SAAS,MAAM,IAAI,IAAI,EAAE;AAC9D,UAAM,QAAiB,MAAM,SAAS,KAAI;AAC1C,WAAO;EACT;AAMA,QAAM,WAAqB;IACzB,KAAK,CAAC,SAAS,IAAI,OAAO,IAAI;IAC9B,MAAM,CAAC,QAAQ,MAAM,SAAS,IAAI,QAAQ,MAAM,IAAI;IACpD,WAAW,MAAM,MAAM;;AAEzB,QAAM,gBAAgB,CAAC,UACrB,OAAO,UAAU;AAEnB,QAAM,WAAW,CAAC,UAA8B;AAC9C,QAAI;AAAO,eAAS,gBAAgB,QAAQ,QAAQ;;AAC/C,aAAO,SAAS,gBAAgB,QAAQ;EAC/C;AACA,QAAM,cAAc,aAAa,QAAQ,yBAAyB;AAClE,MAAI;AAAa,aAAS,WAAW;AACrC,KAAG,SAAS,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AAC5D,UAAM,UAAU,SAAS,gBAAgB,QAAQ;AACjD,UAAM,OAAO,UAAU,YAAY,SAAS,WAAW,8BAA8B,EAAE;AACvF,UAAM,OAAO,OAAO,UAAU;AAC9B,iBAAa,QAAQ,2BAA2B,IAAI;AACpD,aAAS,IAAI;EACf,CAAC;AAED,QAAM,OAAO,CAAC,SAAsB;AAClC,UAAM,OAAO;AACb,eAAW,UAAU,SAAS,iBAAiB,aAAa,GAAG;AAC7D,UAAI,EAAE,kBAAkB;AAAoB;AAC5C,aAAO,aAAa,gBAAgB,OAAO,QAAQ,SAAS,OAAO,SAAS,OAAO;IACrF;AACA,eAAW,WAAW,SAAS,iBAAiB,YAAY,GAAG;AAC7D,UAAI,EAAE,mBAAmB;AAAc;AACvC,cAAQ,SAAS,QAAQ,OAAO,QAAQ,IAAI;IAC9C;EACF;AACA,KAAG,OAAO,WAAW,EAAE,iBAAiB,SAAS,CAAC,UAAS;AACzD,UAAM,SAAS,MAAM;AACrB,QAAI,EAAE,kBAAkB;AAAU;AAClC,UAAM,SAAS,OAAO,QAAQ,mBAAmB;AACjD,QAAI,EAAE,kBAAkB;AAAoB;AAC5C,UAAM,OAAO,OAAO,QAAQ;AAC5B,QAAI,SAAS;AAAW;AACxB,SAAK,IAAI;AACT,YAAO,EAAG,MAAM,SAAS;EAC3B,CAAC;AAED,QAAM,QAAQ,CAAC,UACb,qBAAqB,MAClB,IACC,CAAC,SACC,wCAAwC,KAAK,CAAC,wBAAwB,KAAK,CAAC,kBAAkB,EAEjG,KAAK,EAAE,CAAC;AACb,QAAM,QAAQ,CACZ,SACA,SACU;AACV,QAAI,KAAK,WAAW;AAAG,aAAO;AAC9B,UAAM,OAAO,OAAO,QAAQ,IAAI,CAAC,WAAW,OAAO,OAAO,KAAK,OAAO,EAAE,KAAK,EAAE,CAAC;AAChF,UAAM,OAAO,KACV,IAAI,CAACF,SAAO;AACX,YAAM,QAAQ,QACX,IAAI,CAAC,WAAW,mBAAmB,OAAO,KAAK,KAAK,OAAO,KAAKA,IAAG,CAAC,OAAO,EAC3E,KAAK,EAAE;AACV,YAAM,QAAQ,WAAWA,QAAO,OAAOA,KAAI,UAAU,WAAWA,KAAI,QAAQ;AAC5E,aAAO,MAAM,KAAK,IAAI,KAAK;IAC7B,CAAC,EACA,KAAK,EAAE;AACV,WAAO,iBAAiB,IAAI,kBAAkB,IAAI;EACpD;AACA,QAAM,UAAU,CAAC,UAA0B;AACzC,UAAME,QAAO,KAAK,UAAU,KAAK,KAAK;AACtC,WAAO,IAAIA,MAAK,SAAS,MAAM,GAAGA,MAAK,MAAM,GAAG,GAAG,CAAC,WAAMA,KAAI;EAChE;AACA,QAAM,OAAO,CAAC,UAAyB;AACrC,UAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,WAAO,OAAO,MAAM,KAAK,QAAO,CAAE,IAAI,OAAO,KAAK,IAAI,KAAK,YAAW;EACxE;AACA,QAAM,YAAY,CAAC,UAAyB;AAC1C,UAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,QAAI,OAAO,MAAM,KAAK,QAAO,CAAE;AAAG,aAAO,IAAI,OAAO,KAAK,CAAC;AAC1D,UAAM,MAAM,KAAK,YAAW;AAC5B,WAAO,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC,4BAA4B,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC,CAAC;EACnF;AACA,QAAM,cAAc,CAAC,UAA8B;AACjD,QACE,CAACH,UAAS,KAAK,KACf,OAAO,MAAM,QAAQ,YACrB,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,WAAW,WACxB;AACA,YAAM,IAAI,MAAM,gCAAgC;IAClD;AACA,WAAO,EAAE,KAAK,MAAM,KAAK,UAAU,MAAM,UAAU,QAAQ,MAAM,OAAM;EACzE;AACA,QAAM,cAAc,CAAC,UAA0C;AAC7D,QAAI,CAACA,UAAS,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,CAAC,YAAY,MAAM,IAAI,GAAG;AAClF,aAAO;IACT;AACA,UAAM,QAAoB;MACxB,MAAM,MAAM;MACZ,MAAM,MAAM;MACZ,UAAU,MAAM,aAAa;;AAE/B,QAAI,OAAO,MAAM,gBAAgB;AAAU,YAAM,cAAc,MAAM;AACrE,QAAI,MAAM,QAAQ,MAAM,MAAM,GAAG;AAC/B,YAAM,SAAS,MAAM,OAAO,QAAQ,CAAC,SAAQ;AAC3C,cAAM,QAAQ,YAAY,IAAI;AAC9B,eAAO,UAAU,SAAY,CAAA,IAAK,CAAC,KAAK;MAC1C,CAAC;IACH;AACA,WAAO;EACT;AACA,QAAM,mBAAmB,CAAC,UAAmD;AAC3E,QAAI,CAACA,UAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AAAU,aAAO;AAC/D,UAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IACrC,MAAM,OAAO,QAAQ,CAAC,SAAQ;AAC5B,YAAM,QAAQ,YAAY,IAAI;AAC9B,aAAO,UAAU,SAAY,CAAA,IAAK,CAAC,KAAK;IAC1C,CAAC,IACD,CAAA;AACJ,UAAM,aAAkC;MACtC,MAAM,MAAM;MACZ,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,MAAM;MAC7D,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;MACvD,QAAQ,SAAS,MAAM,MAAM,IAAI,MAAM,SAAS;MAChD;;AAEF,QAAI,OAAO,MAAM,gBAAgB;AAAU,iBAAW,cAAc,MAAM;AAC1E,WAAO;EACT;AACA,QAAM,cAAc,CAAC,UAA6B;AAChD,QAAI,CAACA,UAAS,KAAK,KAAK,CAAC,MAAM,QAAQ,MAAM,WAAW,GAAG;AACzD,YAAM,IAAI,MAAM,uCAAuC;IACzD;AACA,WAAO;MACL,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY,MAAM;MACzE,kBAAkB,OAAO,MAAM,qBAAqB,WAAW,MAAM,mBAAmB;MACxF,aAAa,MAAM,YAAY,QAAQ,CAAC,SAAQ;AAC9C,cAAM,aAAa,iBAAiB,IAAI;AACxC,eAAO,eAAe,SAAY,CAAA,IAAK,CAAC,UAAU;MACpD,CAAC;;EAEL;AAEA,QAAM,gBAAgB,CAAC,UACrB,YAAYA,UAAS,KAAK,IAAI,MAAM,UAAU,QAAW,SAAS,EAAE,QAAQ,CAAC,SAAQ;AACnF,QAAI,CAACA,UAAS,IAAI,KAAK,OAAO,KAAK,OAAO;AAAU,aAAO,CAAA;AAC3D,WAAO;MACL;QACE,IAAI,KAAK;QACT,KAAK,OAAO,KAAK,QAAQ,WAAW,KAAK,MAAM;QAC/C,OAAO,KAAK;QACZ,OAAO,+BAA+B,IAAI,KAAK,EAAE,CAAC;;;EAGxD,CAAC;AASH,QAAM,SAAS,CAAC,UACd,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,YACvE,OAAO,KAAK,IACZ;AACN,QAAM,gBAAgB,CAAC,UACrB,YAAYA,UAAS,KAAK,IAAI,MAAM,WAAW,QAAW,SAAS,EAAE,QAAQ,CAAC,SAAQ;AACpF,QAAI,CAACA,UAAS,IAAI;AAAG,aAAO,CAAA;AAC5B,WAAO;MACL;QACE,IAAI,OAAO,KAAK,EAAE;QAClB,QAAQ,OAAO,KAAK,MAAM;QAC1B,MAAM,OAAO,KAAK,IAAI;QACtB,QAAQ,OAAO,KAAK,MAAM;QAC1B,YAAY,OAAO,KAAK,UAAU;QAClC,aAAa,OAAO,KAAK,WAAW;;;EAG1C,CAAC;AAWH,QAAM,eAAe,CAAC,UACpB,YAAYA,UAAS,KAAK,IAAI,MAAM,SAAS,QAAW,QAAQ,EAAE,QAAQ,CAAC,SAAQ;AACjF,QAAI,CAACA,UAAS,IAAI;AAAG,aAAO,CAAA;AAC5B,WAAO;MACL;QACE,IAAI,OAAO,KAAK,EAAE;QAClB,QAAQ,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;QACxD,YAAY,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;QACpE,aAAa,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;QACvE,QAAQ,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;QACxD,QAAQ,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;QACxD,MAAM,OAAO,KAAK,SAAS,YAAY,KAAK,OAAO;QACnD,WAAW,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY;;;EAGvE,CAAC;AAEH,QAAM,iBAAiB,YAA0B;AAC/C,UAAM,OAAO,MAAM,IAAI,OAAO,aAAa;AAC3C,UAAM,SAAS,GAAG,aAAa,iBAAiB;AAChD,UAAM,SAAS,YAAYA,UAAS,IAAI,IAAI,KAAK,aAAa,QAAW,YAAY;AACrF,UAAM,WACJA,UAAS,IAAI,KAAK,OAAO,KAAK,YAAY,YAAY,KAAK,YAAY,KACnE,KAAK,UACL;AACN,UAAM,SAAS,OAAO,SAAS,IAAI,OAAO,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,MAAK;AACzF,QAAI,CAAC,MAAM,SAAS,MAAM,SAAS;AAAG,YAAM,QAAQ,MAAM,SAAS;AACnE,WAAO,YAAY,MAChB,IAAI,CAAC,SAAS,kBAAkB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,EAClE,KAAK,EAAE;AACV,WAAO,QAAQ,MAAM;EACvB;AAEA,QAAM,iBAAiB,YAA0B;AAC/C,UAAM,CAAC,QAAQ,OAAO,OAAO,OAAO,IAAI,MAAM,QAAQ,IAAI;MACxD,UAAU,SAAS;MACnB,IAAI,OAAO,QAAQ;MACnB,IAAI,OAAO,QAAQ;MACnB,IAAI,OAAO,mBAAmB;KAC/B;AACD,QAAI,CAACA,UAAS,MAAM;AAAG,YAAM,IAAI,MAAM,mCAAmC;AAC1E,UAAM,UAAU,YAAY,KAAK;AACjC,UAAM,QAAQ;AACd,UAAM,OAAO,YAAY,KAAK;AAC9B,OAAG,kBAAkB,WAAW,EAAE,YAAY,MAAM;MAClD;QACE,GAAG;QACH,GAAG,IACD,OAAO,OAAO,YAAY,YAAY,OAAO,YAAY,KACrD,OAAO,UACP,OAAO,OAAO;;MAGtB;QACE,GAAG;QACH,GAAG,IAAI,OAAO,OAAO,WAAW,YAAY,OAAO,WAAW,KAAK,OAAO,SAAS,IAAI;;MAEzF,EAAE,GAAG,aAAa,GAAG,IAAI,MAAM,SAAS,EAAC;MACzC,EAAE,GAAG,eAAe,GAAG,OAAO,QAAQ,YAAY,MAAM,EAAC;MACzD;QACE,GAAG;QACH,GAAG,OAAO,QAAQ,YAAY,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,OAAO,CAAC,CAAC;;MAE1E,EAAE,GAAG,SAAS,GAAG,UAAU,KAAK,GAAG,EAAC;KACrC;AACD,OAAG,qBAAqB,WAAW,EAAE,YAAY,MAC/C;MACE,EAAE,OAAO,UAAU,MAAM,CAACC,SAAoB,IAAIA,KAAI,MAAM,EAAC;MAC7D,EAAE,OAAO,QAAQ,MAAM,CAACA,SAAoB,IAAIA,KAAI,IAAI,EAAC;MACzD;QACE,OAAO;QACP,MAAM,CAACA,SACL,uBAAuBA,KAAI,OAAO,OAAO,CAAC,CAAC,KAAK,IAAIA,KAAI,MAAM,CAAC;;MAEnE,EAAE,OAAO,aAAa,MAAM,CAACA,SAAoB,IAAIA,KAAI,WAAW,EAAC;OAEvE,cAAc,OAAO,CAAC;EAE1B;AAEA,QAAM,cAAc,CAAC,eAA2C;AAC9D,QAAI,WAAW,OAAO,WAAW,GAAG;AAClC,aAAO;IACT;AACA,WAAO,sBAAsB,WAAW,OACrC,IACC,CAAC,UACC,sBAAsB,IAAI,MAAM,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,WAAW,MAAM,EAAE,aAAa,EAEvG,KAAK,EAAE,CAAC;EACb;AAEA,QAAM,cAAc,YAA0B;AAC5C,UAAM,QAAQ,YAAY,MAAM,IAAI,OAAO,QAAQ,CAAC;AACpD,UAAM,QAAQ;AACd,UAAM,OAAO,GAAG,eAAe,WAAW;AAC1C,QAAI,MAAM,YAAY,WAAW,GAAG;AAClC,WAAK,YAAY;AACjB,SAAG,UAAU,WAAW,EAAE,YAAY;AACtC,SAAG,WAAW,WAAW,EAAE,YAAY;AACvC;IACF;AACA,QAAI,CAAC,MAAM,YAAY,KAAK,CAAC,SAAS,KAAK,SAAS,MAAM,UAAU,GAAG;AACrE,YAAM,QAAQ,MAAM,YAAY,CAAC;AACjC,UAAI,UAAU;AAAW;AACzB,YAAM,aAAa,MAAM;IAC3B;AACA,SAAK,YAAY,MAAM,YACpB,IACC,CAAC,SACC,6DAA6D,IAAI,KAAK,IAAI,CAAC,mBACzE,KAAK,SAAS,MAAM,aAAa,SAAS,OAC5C,aAAa,IAAI,KAAK,KAAK,CAAC,mBAAmB,IAAI,KAAK,KAAK,CAAC,SAAM,IAAI,KAAK,MAAM,CAAC,mBAAmB,EAE1G,KAAK,EAAE;AACV,UAAM,WAAW,MAAM,YAAY,KAAK,CAAC,SAAS,KAAK,SAAS,MAAM,UAAU;AAChF,QAAI,aAAa;AAAW;AAC5B,UAAM,cAAc,SAAS,cACzB,mBAAmB,IAAI,SAAS,WAAW,CAAC,SAC5C;AACJ,OAAG,UAAU,WAAW,EAAE,YACxB,OAAO,IAAI,SAAS,KAAK,CAAC,QAAQ,WAAW,GAAG,YAAY,QAAQ,CAAC;AACvE,UAAM,OAAO,MAAM,IAAI,OAAO,UAAU,mBAAmB,MAAM,UAAU,CAAC,WAAW;AACvF,OAAG,WAAW,WAAW,EAAE,YAAY,MACrC;MACE,EAAE,OAAO,MAAM,MAAM,CAACA,SAAmB,SAAS,IAAIA,KAAI,EAAE,CAAC,UAAS;MACtE,EAAE,OAAO,OAAO,MAAM,CAACA,SAAmB,IAAIA,KAAI,GAAG,EAAC;MACtD,EAAE,OAAO,SAAS,MAAM,CAACA,SAAmB,QAAQA,KAAI,KAAK,EAAC;OAEhE,cAAc,IAAI,CAAC;EAEvB;AAEA,QAAM,cAAc,YAA0B;AAC5C,UAAM,QAAQ,YAAY,MAAM,IAAI,OAAO,QAAQ,CAAC;AACpD,OAAG,iBAAiB,WAAW,EAAE,YAC/B,0CAA0C,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC,YAAY,IAAI,MAAM,GAAG,CAAC,mBAAgB,IACtG,MAAM,QAAQ,CACf,OACC,MAAM,SACF,2CACA,oCACN;AACF,UAAM,SAAS,GAAG,UAAU,iBAAiB;AAC7C,WAAO,cAAc,MAAM,SAAS,aAAa;AACjD,WAAO,QAAQ,SAAS,MAAM,SAAS,MAAM;EAC/C;AAEA,QAAM,eAAe,YAA0B;AAC7C,UAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI;MAC1C,IAAI,OAAO,SAAS;MACpB,IAAI,OAAO,iBAAiB,EAAE,MAAM,OAAgB,EAAE,SAAS,CAAA,EAAE,EAAG;KACrE;AACD,UAAM,SAAS,GAAG,gBAAgB,iBAAiB;AACnD,UAAM,UAAU,OAAO;AACvB,UAAM,OAAO,gBAAgB,OAAO,EAAE;AACtC,WAAO,YAAY,wCAAwC,KACxD,IAAI,CAAC,WAAW,kBAAkB,IAAI,OAAO,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,WAAW,EAClF,KAAK,EAAE,CAAC;AACX,WAAO,QAAQ;AACf,OAAG,cAAc,WAAW,EAAE,YAAY,MACxC;MACE,EAAE,OAAO,MAAM,MAAM,CAACA,SAAkB,IAAIA,KAAI,EAAE,EAAC;MACnD;QACE,OAAO;QACP,MAAM,CAACA,SACL,IACE,CAACA,KAAI,QAAQA,KAAI,YAAYA,KAAI,WAAW,EACzC,OAAO,CAAC,SAAyB,QAAQ,IAAI,CAAC,EAC9C,KAAK,GAAG,KAAK,KAAK;;MAG3B;QACE,OAAO;QACP,MAAM,CAACA,SACL,IAAIA,KAAI,UAAUA,KAAI,WAAWA,KAAI,OAAO,SAASA,KAAI,aAAa,GAAG;;OAG/E,aAAa,MAAM,CAAC;EAExB;AAEA,QAAM,gBAAgB,YAA0B;AAC9C,UAAM,UAAU,MAAM,IAAI,OAAO,qBAAqB;AACtD,OAAG,WAAW,WAAW,EAAE,YAAY,MACrC;MACE,EAAE,OAAO,QAAQ,MAAM,CAACA,SAAoB,IAAIA,KAAI,EAAE,EAAC;MACvD,EAAE,OAAO,UAAU,MAAM,CAACA,SAAoB,IAAIA,KAAI,MAAM,EAAC;MAC7D,EAAE,OAAO,QAAQ,MAAM,CAACA,SAAoB,IAAIA,KAAI,IAAI,EAAC;MACzD,EAAE,OAAO,UAAU,MAAM,CAACA,SAAoB,IAAIA,KAAI,MAAM,EAAC;MAC7D,EAAE,OAAO,MAAM,MAAM,CAACA,SAAoB,IAAIA,KAAI,UAAU,EAAC;OAE/D,cAAc,OAAO,CAAC;EAE1B;AAEA,QAAM,eAAe,YAA0B;AAC7C,UAAM,OAAO,MAAM,IAAI,OAAO,GAAG;AACjC,QAAI,CAACD,UAAS,IAAI;AAAG,YAAM,IAAI,MAAM,8BAA8B;AACnE,UAAM,SAAS,YAAY,KAAK,QAAQ,QAAQ,EAAE,IAAI,CAAC,UAAU,OAAO,KAAK,CAAC;AAC9E,OAAG,cAAc,WAAW,EAAE,YAAY,OACvC,IAAI,CAAC,UAAS;AACb,YAAM,QAAQ,SAAS,IAAI,KAAK,IAAI,KAAK;AACzC,YAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,YAAM,SAAS,MAAM,CAAC,KAAK;AAC3B,YAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AACpC,aAAO,2CAA2C,IAAI,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,GAAG,KAAK,wDAAwD,IAAI,KAAK,CAAC;IAClK,CAAC,EACA,KAAK,EAAE;EACZ;AAEA,QAAM,YAAiD;IACrD,UAAU;IACV,OAAO;IACP,OAAO;IACP,QAAQ;IACR,SAAS;IACT,QAAQ;;AAEV,iBAAe,UAAO;AACpB,eAAU;AACV,UAAM,SAAS,UAAU,MAAM,IAAI;AACnC,QAAI;AAAQ,YAAM,OAAM;EAC1B;AAEA,KAAG,aAAa,iBAAiB,EAAE,iBAAiB,UAAU,MAAK;AACjE,UAAM,YAAY,GAAG,aAAa,iBAAiB,EAAE;AACrD,YAAO,EAAG,MAAM,SAAS;EAC3B,CAAC;AACD,WAAS,iBAAiB,UAAU,MAAK;AACvC,UAAM,MAAM,SAAS,MAAM,KAAI;AAC/B,mBAAe,QAAQ,yBAAyB,MAAM,GAAG;AACzD,YAAO,EAAG,MAAM,SAAS;EAC3B,CAAC;AACD,KAAG,WAAW,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AAC9D,YAAO,EAAG,MAAM,SAAS;EAC3B,CAAC;AAED,KAAG,eAAe,WAAW,EAAE,iBAAiB,SAAS,CAAC,UAAS;AACjE,UAAM,SAAS,MAAM;AACrB,QAAI,EAAE,kBAAkB;AAAU;AAClC,UAAM,SAAS,OAAO,QAAQ,mBAAmB;AACjD,QAAI,EAAE,kBAAkB;AAAc;AACtC,UAAM,aAAa,OAAO,QAAQ;AAClC,QAAI,eAAe;AAAW;AAC9B,UAAM,aAAa;AACnB,gBAAW,EAAG,MAAM,SAAS;EAC/B,CAAC;AACD,KAAG,WAAW,WAAW,EAAE,iBAAiB,SAAS,CAAC,UAAS;AAC7D,UAAM,SAAS,MAAM;AACrB,QAAI,EAAE,kBAAkB;AAAU;AAClC,UAAMC,OAAM,OAAO,QAAQ,WAAW;AACtC,QAAI,EAAEA,gBAAe;AAAc;AACnC,UAAM,KAAKA,KAAI,QAAQ;AACvB,QAAI,OAAO;AAAW;AACtB,eAAW,EAAE,EAAE,MAAM,SAAS;EAChC,CAAC;AAED,QAAM,SAAS,GAAG,UAAU,iBAAiB;AAC7C,QAAM,WAAW,GAAG,aAAa,gBAAgB;AACjD,QAAM,cAAc,GAAG,gBAAgB,mBAAmB;AAC1D,QAAM,eAAe,GAAG,iBAAiB,iBAAiB;AAC1D,iBAAe,WAAW,IAAiB;AACzC,UAAM,UAAU;AAChB,OAAG,gBAAgB,WAAW,EAAE,cAAc,KAAK,gBAAgB;AACnE,aAAS,QAAQ,MAAM;AACvB,aAAS,WAAW,OAAO;AAC3B,iBAAa,SAAS,OAAO;AAC7B,QAAI,IAAI;AACN,YAAM,SAAS,MAAM,IACnB,OACA,UAAU,mBAAmB,MAAM,UAAU,CAAC,IAAI,mBAAmB,EAAE,CAAC,EAAE;AAE5E,UAAI,CAACD,UAAS,MAAM;AAAG,cAAM,IAAI,MAAM,mCAAmC;AAC1E,kBAAY,QAAQ,KAAK,UAAU,OAAO,OAAO,MAAM,CAAC,KAAK;IAC/D,OAAO;AACL,kBAAY,QAAQ;IACtB;AACA,WAAO,UAAS;EAClB;AACA,KAAG,cAAc,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AACjE,eAAW,IAAI,EAAE,MAAM,SAAS;EAClC,CAAC;AACD,KAAG,eAAe,eAAe,EAAE,iBAAiB,UAAU,CAAC,UAAS;AACtE,UAAM,YAAY,MAAM;AACxB,QAAI,EAAE,qBAAqB,sBAAsB,UAAU,UAAU;AAAQ;AAC7E,UAAM,eAAc;AACpB,QAAI;AACJ,QAAI;AACF,cAAQE,UAAS,YAAY,KAAK;IACpC,QAAQ;AACN,gBAAU,IAAI,MAAM,mBAAmB,CAAC;AACxC;IACF;AACA,UAAM,KAAK,SAAS,MAAM,KAAI;AAC9B,UAAM,OAAO,UAAU,mBAAmB,MAAM,UAAU,CAAC;AAC3D,UAAM,UAAU,MAAM,UAClB,IAAI,OAAO,GAAG,IAAI,IAAI,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAK,CAAE,IACzD,IAAI,QAAQ,MAAM,EAAE,IAAI,MAAM,QAAW,MAAK,CAAE;AACpD,YACG,KAAK,MAAK;AACT,aAAO,MAAK;AACZ,aAAO,YAAW;IACpB,CAAC,EACA,MAAM,SAAS;EACpB,CAAC;AACD,eAAa,iBAAiB,SAAS,MAAK;AAC1C,UAAM,KAAK,MAAM;AACjB,QAAI,CAAC;AAAI;AACT,QAAI,UAAU,UAAU,mBAAmB,MAAM,UAAU,CAAC,IAAI,mBAAmB,EAAE,CAAC,EAAE,EACrF,KAAK,MAAK;AACT,aAAO,MAAK;AACZ,aAAO,YAAW;IACpB,CAAC,EACA,MAAM,SAAS;EACpB,CAAC;AAED,aAAW,UAAU,SAAS,iBAAiB,gBAAgB,GAAG;AAChE,QAAI,EAAE,kBAAkB;AAAoB;AAC5C,WAAO,iBAAiB,SAAS,MAAK;AACpC,YAAM,MAAM,OAAO,QAAQ;AAC3B,UAAI,QAAQ;AAAW;AACvB,UAAI,QAAQ,UAAU,EAAE,SAAS,OAAO,GAAG,EAAC,CAAE,EAC3C,KAAK,MAAM,YAAW,CAAE,EACxB,MAAM,SAAS;IACpB,CAAC;EACH;AACA,KAAG,UAAU,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AAC7D,UAAM,SAAS,GAAG,UAAU,iBAAiB,EAAE,QAAQ,WAAW;AAClE,QAAI,QAAQ,UAAU,EAAE,QAAQ,CAAC,OAAM,CAAE,EACtC,KAAK,MAAM,YAAW,CAAE,EACxB,MAAM,SAAS;EACpB,CAAC;AACD,KAAG,eAAe,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AAClE,QAAI,QAAQ,UAAU,EAAE,OAAO,KAAI,CAAE,EAClC,KAAK,MAAM,YAAW,CAAE,EACxB,MAAM,SAAS;EACpB,CAAC;AACD,KAAG,aAAa,eAAe,EAAE,iBAAiB,UAAU,CAAC,UAAS;AACpE,UAAM,eAAc;AACpB,UAAM,MAAM,GAAG,iBAAiB,gBAAgB,EAAE,MAAM,KAAI;AAC5D,UAAM,MAAM,UAAU,KAAK,GAAG,IAAI,OAAO,GAAG,IAAI;AAChD,QAAI,QAAQ,UAAU,EAAE,IAAG,CAAE,EAC1B,KAAK,MAAM,YAAW,CAAE,EACxB,MAAM,SAAS;EACpB,CAAC;AAED,KAAG,cAAc,eAAe,EAAE,iBAAiB,UAAU,CAAC,UAAS;AACrE,UAAM,eAAc;AACpB,UAAM,SAAS,GAAG,gBAAgB,iBAAiB,EAAE;AACrD,QAAI,WAAW,IAAI;AACjB,UAAI,QAAQ,WAAW,EAAE,OAAM,CAAE,EAC9B,KAAK,MAAM,aAAY,CAAE,EACzB,MAAM,SAAS;AAClB;IACF;AACA,UAAM,SAAS,OAAO,GAAG,gBAAgB,gBAAgB,EAAE,KAAK;AAChE,QAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,gBAAU,IAAI,MAAM,6CAA6C,CAAC;AAClE;IACF;AACA,UAAM,OAAO,GAAG,cAAc,gBAAgB,EAAE;AAChD,UAAM,SAAS,GAAG,gBAAgB,gBAAgB,EAAE;AACpD,QAAI,QAAQ,WAAW;MACrB;MACA,GAAI,SAAS,KAAK,EAAE,YAAY,KAAI,IAAK,CAAA;MACzC,GAAI,WAAW,KAAK,EAAE,OAAM,IAAK,CAAA;KAClC,EACE,KAAK,MAAM,aAAY,CAAE,EACzB,MAAM,SAAS;EACpB,CAAC;AACD,KAAG,eAAe,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AAClE,QAAI,UAAU,SAAS,EACpB,KAAK,MAAM,aAAY,CAAE,EACzB,MAAM,SAAS;EACpB,CAAC;AACD,KAAG,iBAAiB,iBAAiB,EAAE,iBAAiB,SAAS,MAAK;AACpE,QAAI,UAAU,WAAW,EACtB,KAAK,MAAM,cAAa,CAAE,EAC1B,MAAM,SAAS;EACpB,CAAC;AAED,KAAG,cAAc,WAAW,EAAE,iBAAiB,SAAS,CAAC,UAAS;AAChE,UAAM,SAAS,MAAM;AACrB,QAAI,EAAE,kBAAkB;AAAU;AAClC,UAAM,SAAS,OAAO,QAAQ,cAAc;AAC5C,QAAI,EAAE,kBAAkB;AAAc;AACtC,UAAM,QAAQ,OAAO,QAAQ;AAC7B,QAAI,UAAU;AAAW;AACzB,UAAM,QAAQ;AACd,OAAG,eAAe,WAAW,EAAE,cAAc;AAC7C,UAAM,SAAS,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK;AACtC,OAAG,cAAc,mBAAmB,EAAE,WAAW,WAAW,SAAS,WAAW;EAClF,CAAC;AACD,KAAG,cAAc,eAAe,EAAE,iBAAiB,UAAU,CAAC,UAAS;AACrE,UAAM,eAAc;AACpB,UAAM,OAAO,YAA0B;AACrC,UAAI,MAAM,UAAU;AAAM,cAAM,IAAI,MAAM,sBAAsB;AAChE,YAAM,QAAQ,MAAM,MAAM,MAAM,GAAG;AACnC,YAAM,SAAS,MAAM,CAAC;AACtB,YAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AACpC,UAAI,WAAW;AAAW,cAAM,IAAI,MAAM,sBAAsB;AAChE,YAAM,WAAW,KAAK,QACpB,qBACA,CAAC,QAAQ,QAAgB,OAAO,aAAa,GAAG,EAAE,KAAK,EAAE;AAE3D,UAAI;AACJ,YAAM,YAAY,GAAG,cAAc,mBAAmB;AACtD,UAAI,WAAW,SAAS,WAAW,YAAY,UAAU,MAAM,KAAI,MAAO,IAAI;AAC5E,YAAI;AACF,iBAAOA,UAAS,UAAU,KAAK;QACjC,QAAQ;AACN,gBAAM,IAAI,MAAM,kBAAkB;QACpC;MACF;AACA,YAAM,OAAO,MAAM,IAAI,QAAQ,UAAU,IAAI;AAC7C,SAAG,gBAAgB,WAAW,EAAE,cAAc,KAAK,UAAU,MAAM,MAAM,CAAC;IAC5E;AACA,SAAI,EAAG,MAAM,SAAS;EACxB,CAAC;AAGD,QAAM,cAAc,CAAC,UAAqC;AACxD,QAAI,CAACF,UAAS,KAAK,KAAK,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,UAAU,UAAU;AACvF,aAAO;IACT;AACA,UAAM,QAAe;MACnB,IAAI,MAAM;MACV,OAAO,MAAM;MACb,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc;MACzE,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;;AAEtD,QAAI,OAAO,MAAM,WAAW;AAAU,YAAM,SAAS,MAAM;AAC3D,WAAO;EACT;AACA,QAAM,cAAc,CAAC,WAAkC;AACrD,UAAM,MAAM,GAAG,OAAO,WAAW;AACjC,UAAM,QAAQ,GAAG,SAAS,WAAW;AACrC,eAAW,SAAS,QAAQ;AAC1B,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,OAAO;AACd,aAAO,QAAQ,OAAO,MAAM;AAC5B,aAAO,cAAc,MAAM;AAC3B,UAAI,OAAO,MAAM;AACjB,YAAM,UAAU,SAAS,cAAc,SAAS;AAChD,cAAQ,YAAY;AACpB,cAAQ,KAAK,QAAQ,MAAM,EAAE;AAC7B,cAAQ,SAAS;AACjB,YAAM,QAAQ,SAAS,cAAc,IAAI;AACzC,YAAM,cAAc,MAAM;AAC1B,YAAM,OAAO,SAAS,cAAc,GAAG;AACvC,WAAK,YAAY;AACjB,WAAK,cAAc,MAAM;AACzB,YAAM,OAAO,SAAS,cAAc,KAAK;AACzC,WAAK,YAAY;AACjB,WAAK,KAAK,SAAS,MAAM,EAAE;AAC3B,WAAK,YAAY,MAAM;AACvB,cAAQ,OAAO,OAAO,MAAM,IAAI;AAChC,YAAM,OAAO,OAAO;AACpB,UAAI,MAAM,WAAW;AAAW;AAChC,UAAI;AACF,cAAM,WAAoB,IAAI,SAAS,QAAQ,OAAO,MAAM,MAAM;AAClE,YAAI,CAAC,cAAc,QAAQ;AAAG,gBAAM,IAAI,MAAM,8BAA8B;AAC5E,iBAAS,MAAM,QAAQ;MACzB,SAAS,OAAO;AACd,cAAM,OAAO,SAAS,cAAc,GAAG;AACvC,aAAK,YAAY;AACjB,aAAK,cAAc,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACxE,aAAK,OAAO,IAAI;MAClB;IACF;EACF;AAEA,kBAAgB;IACd;IACA,GAAG,CAAC,OAAO,SAAS,eAAe,EAAE;IACrC;IACA,UAAU,EAAE,MAAM,SAAS,MAAM,QAAQ,SAAS,OAAM;IACxD;IACA,WAAW,OAAO;GACnB;AACD,iBAAc,EACX,KAAK,MAAM,IAAI,OAAO,cAAc,CAAC,EACrC,KAAK,CAAC,aAAY;AACjB,UAAM,SAAS,YACbA,UAAS,QAAQ,IAAI,SAAS,SAAS,QACvC,QAAQ,EACR,QAAQ,CAAC,UAAS;AAClB,YAAM,UAAU,YAAY,KAAK;AACjC,aAAO,YAAY,SAAY,CAAA,IAAK,CAAC,OAAO;IAC9C,CAAC;AACD,gBAAY,MAAM;AAClB,WAAO,QAAO;EAChB,CAAC,EACA,MAAM,SAAS;AACpB;AAEA,IAAM,gBAAgB,CAACA,WAAU,iBAAiB,iBAAiB,iBAAiB,SAAS,EAC1F,IAAI,CAAC,OAAO,GAAG,SAAQ,CAAE,EACzB,KAAK,IAAI;AAGL,IAAM,oBAAoB,CAAC,WAAmC;AACnE,QAAM,UAAU,KAAK,UAAU,MAAM,EAAE,QAAQ,MAAM,SAAS;AAC9D,SAAO;EAAa,aAAa;YAAe,OAAO;;AACzD;;;ACr6BO,IAAM,aAAa,CAAwB,YAAkB;AAU7D,IAAM,wBAAwB;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AA8BF,IAAM,WAAW;AAGV,IAAM,gBAAgB,CAAC,OAAiC;AAC7D,MAAI,CAAC,IAAI;AAAQ;AACjB,QAAM,OAAO,oBAAI,IAAG;AACpB,aAAW,SAAS,GAAG,QAAQ;AAC7B,QAAI,CAAC,SAAS,KAAK,MAAM,EAAE,GAAG;AAC5B,YAAM,IAAI,WAAW,6BAA6B,QAAQ,KAAK,KAAK,UAAU,MAAM,EAAE,CAAC,EAAE;IAC3F;AACA,QAAI,KAAK,IAAI,MAAM,EAAE;AAAG,YAAM,IAAI,WAAW,4BAA4B,MAAM,EAAE,EAAE;AACnF,SAAK,IAAI,MAAM,EAAE;AACjB,QAAI,MAAM,MAAM,KAAI,MAAO;AAAI,YAAM,IAAI,WAAW,eAAe,MAAM,EAAE,gBAAgB;EAC7F;AACF;;;AC5JA,IAAM,aAAa,CAAC,UAClB,MAAM,QAAQ,YAAY,CAAC,SAAQ;AACjC,UAAQ,MAAM;IACZ,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;IACT;AACE,aAAO;EACX;AACF,CAAC;AAQI,IAAM,mBAAmB;AAOzB,IAAM,sBAAsB,CAAC,YAA2B;AAC7D,QAAM,OAAO,WAAW,OAAO;AAC/B,QAAM,SAAS,kBAAkB;IAC/B,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,WAAW;IACX;GACD;AACD,SAAO;;;;;;;SAOA,IAAI;;IAET,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAuPoB,IAAI;;;;kBAInB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqIpB,MAAM;;;AAGR;AAEA,IAAM,eAAe,CAAC,SACpB,IAAI,SAAS,MAAM;EACjB,QAAQ;EACR,SAAS;IACP,gBAAgB;IAChB,iBAAiB;;CAEpB;AAEH,IAAMI,QAAO,CAAC,SACZ,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;EACjC,QAAQ;EACR,SAAS,EAAE,gBAAgB,kCAAiC;CAC7D;AAGI,IAAM,gBAAgB,CAAC,SAAiB,OAAwC;AACrF,QAAM,QAAQ,MAAM,oBAAoB,OAAO;AAC/C,QAAMC,YAAW,MAAO,IAAI,SAAS,GAAG,OAAO,EAAE,SAAS,aAAa,MAAK,CAAE,IAAI,MAAK;AACvF,SAAO;IACL,WAAW,MAAM,aAAaA,UAAQ,CAAE;IACxC,YAAY,MAAM,aAAaA,UAAQ,CAAE;IACzC,oBAAoB,MAClBD,MAAK;MACH;MACA,SAAS,IAAI,UAAU,CAAA,GAAI,IAAI,CAAC,WAAW;QACzC,IAAI,MAAM;QACV,OAAO,MAAM;QACb,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAW,IAAK,CAAA;QAC3E,MAAM,MAAM;QACZ,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAM,IAAK,CAAA;QAC5D;KACH;;AAEP;;;AClaO,IAAM,iBAAiB;EAC5B,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,aAAa;EACb,cAAc;;;;AChDhB,IAAME,YAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,cAAc,CAAC,QAAgB,QAClC,OAAmC,GAAG;AAGlC,IAAM,oBAAoB,CAAC,cAAiD;AACjF,QAAM,MAAM,YAAY,WAAW,eAAe,SAAS;AAC3D,QAAM,MAA0BA,UAAS,GAAG,IAAK,MAA6B,CAAA;AAC9E,QAAM,YAAY,IAAI,aAAa;AACnC,QAAM,SAAS,IAAI,UAAU,CAAA;AAC7B,SAAO;IACL;IACA,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;IACtD,QAAQ;MACN,SAAS,cAAc,OAAO,WAAW;MACzC,MAAM,OAAO,QAAQ;MACrB,QAAQ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;;;AAGlE;;;ACxBA,SAAuB,YAAY;;;AC0EnC,IAAM,WAAW,oBAAI,QAAO;AAGrB,IAAM,iBAAiB,CAAC,YAA8C,SAAS,IAAI,OAAO;;;ADxEjG,IAAM,aAAa,CAAC,SAAkB,aAAgC;AACpE,QAAM,SAAS,SAAS,UAAU,MAAM,eAAe,OAAO,IAAI;AAClE,SAAO,UAAU,OAAO,SAAS,IAAI,iBAAiB,UAAU,EAAE,OAAM,CAAE,IAAI;AAChF;AAsCO,IAAM,mBAAmB,CAC9B,aACiC;AAE7B,IAAO,yBAAP,cAAsC,MAAK;EAC1B;EAArB,YAAqB,UAAkB;AACrC,UAAM;EAAwC,SAAS,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AADvE,SAAA,WAAA;AAEnB,SAAK,OAAO;EACd;;AAOK,IAAM,mBAAmB,CAC9BC,WACA,aACY;AACZ,QAAM,WAAqB,CAAA;AAC3B,QAAM,aAAa,eAAeA,SAAQ;AAC1C,QAAM,OAAO,oBAAI,IAAG;AACpB,aAAW,aAAa,YAAY;AAClC,QAAI,KAAK,IAAI,UAAU,WAAW;AAChC,eAAS,KAAK,yBAAyB,UAAU,WAAW,EAAE;AAChE,SAAK,IAAI,UAAU,WAAW;AAC9B,UAAM,YAAY,kBAAkB,UAAU,SAAS,EAAE;AACzD,UAAM,UAAU,SAAS,UAAU,WAAW;AAC9C,QAAI,aAAa,CAAC;AAChB,eAAS,KAAK,uBAAuB,UAAU,WAAW,iBAAiB;AAC7E,QAAI,CAAC,aAAa;AAChB,eAAS,KAAK,aAAa,UAAU,WAAW,0CAA0C;EAC9F;AACA,aAAW,MAAM,OAAO,KAAK,QAAQ,GAAG;AACtC,QAAI,CAAC,KAAK,IAAI,EAAE;AAAG,eAAS,KAAK,WAAW,EAAE,2BAA2B;EAC3E;AACA,SAAO;AACT;AA2BA,IAAM,WAAW,CAAC,aAAqB,SAAS,QAAQ,gBAAgB,KAAK;AAG7E,IAAM,aAAa,CAAC,GAAc,MAAgB;AAChD,QAAM,KAAK,EAAE,KAAK,MAAM,GAAG;AAC3B,QAAM,KAAK,EAAE,KAAK,MAAM,GAAG;AAC3B,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK;AACvD,UAAM,IAAI,GAAG,CAAC,KAAK;AACnB,UAAM,IAAI,GAAG,CAAC,KAAK;AACnB,UAAM,KAAK,EAAE,WAAW,GAAG;AAC3B,UAAM,KAAK,EAAE,WAAW,GAAG;AAC3B,QAAI,OAAO;AAAI,aAAO,KAAK,IAAI;AAC/B,QAAI,MAAM;AAAG,aAAO,IAAI,IAAI,KAAK;EACnC;AACA,SAAO;AACT;AAEA,IAAM,UAAU,CAAC,QAAyB,gBAAgB,IAAI,aAAa,QAAO,CAAE;AAM7E,IAAM,aAAa,CAAC,WAAuC;AAChE,QAAM,SAAS,cAAc,MAAM;AACnC,cAAY,MAAM;AAClB,SAAO;AACT;AAGO,IAAM,gBAAgB,CAAC,YAAoC;AAChE,QAAM,WAAW,iBAAiB,QAAQ,UAAU,QAAQ,QAAQ;AACpE,MAAI,SAAS,SAAS;AAAG,UAAM,IAAI,uBAAuB,QAAQ;AAClE,cAAY,QAAQ,MAAM;AAC1B,QAAM,MAAM,QAAQ,QAAQ,MAAM,KAAK,IAAG;AAC1C,QAAM,MAAM,IAAI,KAAI;AACpB,MAAI,SAAS,CAAC,MAAM,QAAQ,SAAS,EAAE,IAAI,GAAG,CAAC;AAC/C,MAAI,QAAQ,CAAC,OAAO,MAAM,QAAQ,QAAQ,OAAO,EAAE,IAAI,GAAG,CAAC;AAE3D,QAAM,aAAa,CAAC,GAAG,eAAe,QAAQ,QAAQ,CAAC,EAAE,KAAK,UAAU;AACxE,aAAW,aAAa,YAAY;AAClC,UAAM,WAAW,kBAAkB,UAAU,SAAS;AACtD,UAAM,UAAU,QAAQ,SAAS,UAAU,WAAW;AACtD,UAAM,QAAQ,OAAO,MAAc;AACjC,YAAM,UAAU,EAAE,IAAI;AACtB,UAAI,CAAC,SAAS,aAAa,CAAC,SAAS;AACnC,eAAO,QAAQ,cACX,QAAQ,YAAY,SAAS,SAAS,IACtC,QAAQ,SAAS,OAAO;MAC9B;AACA,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,YAAM,UAA4B;QAChC;QACA;QACA,QAAQ,EAAE,IAAI,MAAK;QACnB,OAAO,QAAQ,GAAG;QAClB,MAAM,MAAM,SAAS,OAAO;QAC5B,QAAQ,QAAQ;QAChB,WAAW,QAAQ;QACnB;QACA,UAAU,QAAQ;QAClB;;AAEF,YAAM,QAAQ,MAAM,QAAQ,SAAS,OAAO;AAC5C,aAAO,WAAW,SAAS,SAAU,MAAM,QAAQ,OAAO,CAAE;IAC9D;AACA,QAAI,GAAG,UAAU,OAAO,YAAW,GAAI,SAAS,UAAU,IAAI,GAAG,KAAK;EACxE;AAEA,SAAO;IACL;IACA,QAAQ,QAAQ;IAChB,WAAW,QAAQ;IACnB,OAAO,OAAO,YAAY,IAAI,MAAM,OAAO;IAC3C,OAAO,YAAW;AAChB,qBAAe,QAAQ,QAAQ,QAAQ,SAAS;IAClD;;AAEJ;;;AEvLO,IAAM,oBAAoB,CAAC,QAAsB,eAA0C;EAChG;EACA,SAAS,OACN,QACC,yGAAyG,EAE1G,IAAoE,SAAS;EAChF,WAAW,OACR,QACC,6FAA6F,EAE9F,IAAmD,SAAS;;AAW1D,IAAM,mBAAmB,CAC9B,QACA,WACA,aACQ;AACR,SAAO,YAAY,MAAK;AACtB,WAAO,QAAQ,qDAAqD,EAAE,IAAI,SAAS;AACnF,WAAO,QAAQ,uDAAuD,EAAE,IAAI,SAAS;AACrF,UAAM,SAAS,OAAO,QACpB,gGAAgG;AAElG,eAAWC,QAAO,SAAS,SAAS;AAClC,aAAO,IAAI,WAAWA,KAAI,YAAYA,KAAI,IAAIA,KAAI,KAAKA,KAAI,KAAK;IAClE;AACA,UAAM,WAAW,OAAO,QACtB,sFAAsF;AAExF,eAAWA,QAAO,SAAS,WAAW;AACpC,eAAS,IAAI,WAAWA,KAAI,MAAMA,KAAI,MAAMA,KAAI,KAAK;IACvD;EACF,CAAC;AACH;;;ACYA,IAAM,kBAAkB;AACxB,IAAM,YAAY;AAClB,IAAM,SAAS;AACf,IAAM,aAAa;AACnB,IAAM,aAAa,oBAAI,IAAI,CAAC,QAAQ,eAAe,QAAQ,CAAC;AAE5D,IAAM,OAAO,CAAC,QAAgB,aAAmC,EAAE,IAAI,OAAO,QAAQ,QAAO;AAE7F,IAAMC,YAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,SAAS,CAAC,UAAkC;AAChD,MAAI,UAAU;AAAM,WAAO;AAC3B,MAAI,MAAM,QAAQ,KAAK;AAAG,WAAO;AACjC,UAAQ,OAAO,OAAO;IACpB,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO,OAAO,SAAS,KAAK,IAAI,WAAW;IAC7C,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;IACT;AACE,aAAO;EACX;AACF;AAEA,IAAM,WAAW,CAAC,SAAwB;AACxC,QAAM,QAAQ,KAAK,QAAQ,YAAY,GAAG,EAAE,KAAI;AAChD,MAAI,UAAU;AAAI,WAAO;AACzB,SAAO,MAAM,OAAO,CAAC,EAAE,YAAW,IAAK,MAAM,MAAM,CAAC;AACtD;AAGO,IAAM,YAAY,CAAC,UAAwC;AAChE,MAAI,UAAU;AAAW,WAAO,KAAK,KAAK,mBAAmB;AAC7D,MAAI;AACF,WAAO,EAAE,IAAI,MAAM,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC,EAAY;EACxE,QAAQ;AACN,WAAO,KAAK,KAAK,oBAAoB;EACvC;AACF;AAEA,IAAM,WAAW,CAAC,UAAyB;AACzC,QAAM,OAAQ,MAA8C;AAC5D,SAAO,OAAO,MAAM,SAAS,WAAW,KAAK,OAAO;AACtD;AAEA,IAAM,WAAW,CAAC,UAChB,aAAa,SACb,OAAQ,MAAgC,YAAY,cACpD,iBAAiB;AAGZ,IAAM,sBAAsB,CAAC,SAAwC;AAC1E,QAAM,QAA+B,CAAA;AACrC,QAAM,OAAO,oBAAI,IAAG;AACpB,QAAM,QAAQ,CAAC,OAAgB,UAAuB;AACpD,QAAI,MAAM,SAAS,KAAK,OAAO;AAAY;AAC3C,QAAI,UAAU,QAAQ,OAAO,UAAU;AAAU;AACjD,QAAI,KAAK,IAAI,KAAK;AAAG;AACrB,SAAK,IAAI,KAAK;AACd,QAAI,iBAAiB,YAAY;AAC/B,YAAM,KAAK,KAA4B;AACvC;IACF;AACA,QAAI,iBAAiB,KAAK;AACxB,iBAAW,SAAS,MAAM,OAAM;AAAI,cAAM,OAAO,QAAQ,CAAC;AAC1D;IACF;AACA,QAAI,iBAAiB,KAAK;AACxB,iBAAW,SAAS,MAAM,OAAM;AAAI,cAAM,OAAO,QAAQ,CAAC;AAC1D;IACF;AACA,QAAI,QAAQ,KAAK,SAAS,KAAK,KAAK,WAAW,IAAI,SAAS,KAAK,CAAC;AAAG;AACrE,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,MAAM,KAAK,IAAI,MAAM,QAAQ,EAAE;AACrC,eAAS,IAAI,GAAG,IAAI,KAAK;AAAK,cAAM,MAAM,CAAC,GAAG,QAAQ,CAAC;AACvD;IACF;AACA,QAAI;AACJ,QAAI;AACF,iBAAW,OAAO,OAAO,KAAK;IAChC,QAAQ;AACN;IACF;AACA,eAAW,SAAS;AAAU,YAAM,OAAO,QAAQ,CAAC;EACtD;AACA,QAAM,MAAM,CAAC;AACb,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,QAAsB,cAA+B;AACxE,QAAM,UAAU,OACb,QAAQ,iFAAiF,EACzF,IAAsB,SAAS;AAClC,QAAM,YAAY,OACf,QACC,6FAA6F,EAE9F,IAAsB,SAAS;AAClC,SAAO,CAAC,GAAG,SAAS,GAAG,SAAS,EAAE,IAAI,CAACC,SAAQA,KAAI,IAAI;AACzD;AASA,IAAM,aAAa,CAAC,UAA8B;EAChD;EACA,OAAO,oBAAI,IAAG;EACd,SAAS;EACT,QAAQ,oBAAI,IAAG;;AAGjB,IAAM,SAAS,CAAC,OAAmB,UAAwB;AACzD,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,MAAM,IAAI,IAAI;AACpB,QAAM;AACN,MAAI,CAACD,UAAS,KAAK;AAAG;AACtB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,UAAM,SAAS,MAAM,OAAO,IAAI,GAAG,KAAK,WAAW,GAAG;AACtD,WAAO,QAAQ,KAAK;AACpB,UAAM,OAAO,IAAI,KAAK,MAAM;EAC9B;AACF;AAEA,IAAM,cAAc,CAAC,OAAmB,YAA+B;AACrE,QAAM,QAAQ,CAAC,GAAG,MAAM,KAAK;AAC7B,QAAM,OAAO,MAAM,WAAW,IAAK,MAAM,CAAC,IAAuB;AACjE,QAAM,QAAoB;IACxB,MAAM,MAAM;IACZ;IACA,UAAU,MAAM,UAAU,WAAW,MAAM,SAAS,MAAM;;AAE5D,MAAI,MAAM,OAAO,OAAO,GAAG;AACzB,UAAM,SAAS,CAAC,GAAG,MAAM,OAAO,OAAM,CAAE,EACrC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAC3C,IAAI,CAAC,UAAU,YAAY,OAAO,MAAM,OAAO,CAAC;EACrD;AACA,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,YAAwC;AAC3D,MAAI,QAAQ,WAAW;AAAG,WAAO,CAAA;AACjC,QAAM,SAAS,QAAQ,MAAM,GAAG,MAAM;AACtC,QAAM,UAAU,OAAO,OAAO,CAAC,WAAWA,UAAS,OAAO,KAAK,CAAC;AAChE,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,QAAQ,IAAI,IAAI,OAAO,IAAI,CAAC,WAAW,OAAO,OAAO,KAAK,CAAC,CAAC;AAClE,UAAM,OAAO,CAAC,GAAG,KAAK;AACtB,WAAO;MACL;QACE,MAAM;QACN,MAAM,KAAK,WAAW,IAAK,KAAK,CAAC,IAAuB;QACxD,UAAU;;;EAGhB;AACA,QAAM,OAAO,oBAAI,IAAG;AACpB,aAAW,UAAU,SAAS;AAC5B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,KAAgC,GAAG;AAClF,YAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,WAAW,GAAG;AAC7C,aAAO,OAAO,KAAK;AACnB,WAAK,IAAI,KAAK,KAAK;IACrB;EACF;AACA,SAAO,CAAC,GAAG,KAAK,OAAM,CAAE,EACrB,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,EAC3C,IAAI,CAAC,UAAU,YAAY,OAAO,QAAQ,MAAM,CAAC;AACtD;AAEA,IAAM,cAAc,CAClB,UACA,aACgB;AAChB,QAAM,SAAS,oBAAI,IAAG;AACtB,aAAW,SAAS;AAAU,WAAO,IAAI,MAAM,MAAM,KAAK;AAC1D,QAAM,UAAwB,CAAA;AAC9B,QAAM,OAAO,oBAAI,IAAG;AACpB,aAAW,SAAS,YAAY,CAAA,GAAI;AAClC,UAAM,QAAQ,OAAO,IAAI,MAAM,IAAI;AACnC,SAAK,IAAI,MAAM,IAAI;AACnB,QAAI,CAAC,OAAO;AACV,cAAQ,KAAK,EAAE,GAAG,OAAO,UAAU,MAAM,SAAQ,CAAE;AACnD;IACF;AACA,YAAQ,KAAK;MACX,GAAG;MACH,MAAM,MAAM,SAAS,YAAY,MAAM,OAAO,MAAM;MACpD,UAAU,MAAM,YAAY,MAAM;MAClC,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAW,IAAK,CAAA;MAC3E,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,KAAI,IAAK,CAAA;MACtD,GAAI,MAAM,WAAW,SACjB,EAAE,QAAQ,YAAY,MAAM,QAAQ,MAAM,UAAU,CAAA,CAAE,EAAC,IACvD,CAAA;KACL;EACH;AACA,aAAW,SAAS,UAAU;AAC5B,QAAI,CAAC,KAAK,IAAI,MAAM,IAAI;AAAG,cAAQ,KAAK,KAAK;EAC/C;AACA,SAAO;AACT;AAEA,IAAM,eAAe,CAAC,QAAsB,WAAmB,SAC7D,IAAI,WAAoB,QAAQ,WAAW,IAAI;AAEjD,IAAM,aAAa,CAAC,YAAiC,OAAuC;AAC1F,QAAM,OAAO,WAAW,KAAK,EAAE,OAAO,CAAC,QAAQ,SAAS,MAAM,OAAO,SAAQ,CAAE;AAC/E,QAAMC,OAAM,KAAK,KAAK,CAAC,UAAU,MAAM,OAAO,EAAE;AAChD,SAAOA,OAAM,EAAE,IAAIA,KAAI,IAAI,KAAKA,KAAI,KAAK,OAAOA,KAAI,MAAK,IAAK;AAChE;AAcO,IAAM,eAAe,CAAC,UAAgC;AAC3D,QAAM,WAAW,oBAAI,IAAG;AACxB,aAAW,eAAe,MAAM,gBAAgB,CAAA,GAAI;AAClD,QAAI,gBAAgB,KAAK,YAAY,IAAI;AAAG,eAAS,IAAI,YAAY,MAAM,WAAW;EACxF;AACA,QAAM,QAAQ,IAAI,IAAY,SAAS,KAAI,CAAE;AAC7C,aAAW,QAAQ,YAAY,MAAM,QAAQ,MAAM,gBAAgB;AAAG,UAAM,IAAI,IAAI;AACpF,aAAW,cAAc,oBAAoB,MAAM,IAAI,GAAG;AACxD,QAAI,WAAW,cAAc,MAAM;AAAkB,YAAM,IAAI,WAAW,cAAc;EAC1F;AACA,QAAM,cAAqC,CAAA;AAC3C,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG;AACjC,UAAM,cAAc,SAAS,IAAI,IAAI;AACrC,UAAM,aAAa,aAAa,MAAM,QAAQ,MAAM,kBAAkB,IAAI;AAC1E,UAAM,UAAU,WACb,KAAK,EAAE,OAAO,SAAQ,CAAE,EACxB,MAAM,GAAG,MAAM,EACf,IAAI,CAACA,UAAS,EAAE,IAAIA,KAAI,IAAI,KAAKA,KAAI,KAAK,OAAOA,KAAI,MAAK,EAAG;AAChE,UAAM,WAAW,YAAY,OAAO;AACpC,UAAM,SAAS,YAAY,aAAa,QAAQ,QAAQ;AACxD,UAAM,SACJ,eAAe,QAAQ,SAAS,IAAI,UAAU,cAAc,aAAa;AAC3E,gBAAY,KAAK;MACf;MACA,OAAO,aAAa,SAAS,SAAS,IAAI;MAC1C,GAAI,aAAa,gBAAgB,SAAY,EAAE,aAAa,YAAY,YAAW,IAAK,CAAA;MACxF,OAAO,WAAW,MAAK;MACvB;MACA;MACA,GAAI,aAAa,SAAS,SAAY,EAAE,MAAM,YAAY,KAAI,IAAK,CAAA;KACpE;EACH;AACA,QAAM,QAAQ,oBAAI,IAAG;AACrB,aAAW,CAAC,OAAO,IAAI,MAAM,MAAM,gBAAgB,CAAA,GAAI,QAAO;AAAI,UAAM,IAAI,KAAK,MAAM,KAAK;AAC5F,cAAY,KAAK,CAAC,GAAG,MAAK;AACxB,UAAM,OAAO,MAAM,IAAI,EAAE,IAAI;AAC7B,UAAM,QAAQ,MAAM,IAAI,EAAE,IAAI;AAC9B,QAAI,SAAS,UAAa,UAAU;AAAW,aAAO,OAAO;AAC7D,QAAI,SAAS;AAAW,aAAO;AAC/B,QAAI,UAAU;AAAW,aAAO;AAChC,WAAO,EAAE,KAAK,cAAc,EAAE,IAAI;EACpC,CAAC;AACD,SAAO;IACL,WAAW,MAAM;IACjB,kBAAkB,MAAM;IACxB;;AAEJ;AAQA,IAAM,SAAS,CACb,QACA,kBACA,MACA,UAC0B;AAC1B,MAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG,WAAO,KAAK,KAAK,gCAAgC;AAClF,QAAM,QAAQ,MAAM,SAAS;AAC7B,MAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,KAAK;AACxD,WAAO,KAAK,KAAK,wCAAwC;EAC3D;AACA,QAAM,QAAQ,MAAM,SAAS;AAC7B,MAAI,UAAU,YAAY,UAAU;AAClC,WAAO,KAAK,KAAK,oCAAoC;AACvD,QAAM,aAAa,aAAa,QAAQ,kBAAkB,IAAI;AAC9D,QAAM,OAAO,WAAW,KAAK,EAAE,MAAK,CAAE,EAAE,OAAO,CAACA,SAAO;AACrD,QAAI,MAAM,UAAU;AAAW,aAAO;AACtC,WAAO,UAAU,WAAWA,KAAI,MAAM,MAAM,QAAQA,KAAI,MAAM,MAAM;EACtE,CAAC;AACD,QAAM,QAAQ,KAAK,MAAM,GAAG,KAAK;AACjC,QAAM,OAAO,MAAM,GAAG,EAAE;AACxB,SAAO;IACL,IAAI;IACJ,OAAO;MACL,YAAY;MACZ,OAAO,WAAW,MAAK;MACvB,SAAS,MAAM,IAAI,CAACA,UAAS,EAAE,IAAIA,KAAI,IAAI,KAAKA,KAAI,KAAK,OAAOA,KAAI,MAAK,EAAG;MAC5E,MAAM,KAAK,SAAS,SAAS,OAAO,KAAK,MAAM;;;AAGrD;AAEO,IAAM,gBAAgB,CAC3B,OACA,MACA,QAAoB,CAAA,MACO,OAAO,MAAM,QAAQ,MAAM,kBAAkB,MAAM,KAAK;AAE9E,IAAM,kBAAkB,CAC7B,OACA,MACA,OAC4B;AAC5B,MAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG,WAAO,KAAK,KAAK,gCAAgC;AAClF,MAAI,CAAC,UAAU,KAAK,EAAE;AAAG,WAAO,KAAK,KAAK,0BAA0B;AACpE,QAAM,SAAS,WAAW,aAAa,MAAM,QAAQ,MAAM,kBAAkB,IAAI,GAAG,EAAE;AACtF,SAAO,SAAS,EAAE,IAAI,MAAM,OAAO,OAAM,IAAK,KAAK,KAAK,aAAa,EAAE,OAAO,IAAI,EAAE;AACtF;AAEA,IAAM,YAAY,CAAC,OACjB,UAAU,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,OAAO,GAAE,IAAK,KAAK,KAAK,kCAAkC;AAEtF,IAAM,oBAAoB,CAC/B,OACA,MACA,UAC4B;AAC5B,MAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG,WAAO,KAAK,KAAK,gCAAgC;AAClF,QAAM,SAAS,UAAU,MAAM,KAAK;AACpC,MAAI,CAAC,OAAO;AAAI,WAAO;AACvB,QAAM,aAAa,aAAa,MAAM,QAAQ,MAAM,kBAAkB,IAAI;AAC1E,QAAM,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI,WAAW,aAAY,CAAE;AAC3D,QAAM,UAAU,UAAU,EAAE;AAC5B,MAAI,CAAC,QAAQ;AAAI,WAAO;AACxB,MAAI,WAAW,IAAI,QAAQ,KAAK;AAAG,WAAO,KAAK,KAAK,UAAU,QAAQ,KAAK,iBAAiB;AAC5F,QAAM,SAAS,WAAW,OAAO,QAAQ,OAAO,OAAO,KAAK;AAC5D,SAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,QAAQ,OAAO,KAAK,OAAO,KAAK,OAAO,OAAO,MAAK,EAAE;AACvF;AAEO,IAAM,qBAAqB,CAChC,OACA,MACA,IACA,UAC4B;AAC5B,MAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG,WAAO,KAAK,KAAK,gCAAgC;AAClF,QAAM,UAAU,UAAU,EAAE;AAC5B,MAAI,CAAC,QAAQ;AAAI,WAAO;AACxB,QAAM,SAAS,UAAU,KAAK;AAC9B,MAAI,CAAC,OAAO;AAAI,WAAO;AACvB,QAAM,aAAa,aAAa,MAAM,QAAQ,MAAM,kBAAkB,IAAI;AAC1E,MAAI,CAAC,WAAW,IAAI,QAAQ,KAAK;AAAG,WAAO,KAAK,KAAK,aAAa,QAAQ,KAAK,OAAO,IAAI,EAAE;AAC5F,QAAM,SAAS,WAAW,OAAO,QAAQ,OAAO,OAAO,KAAK;AAC5D,MAAI,CAAC;AAAQ,WAAO,KAAK,KAAK,aAAa,QAAQ,KAAK,OAAO,IAAI,EAAE;AACrE,SAAO,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,QAAQ,OAAO,KAAK,OAAO,KAAK,OAAO,OAAO,MAAK,EAAE;AACvF;AAEO,IAAM,mBAAmB,CAC9B,OACA,MACA,IACA,UAC4B;AAC5B,QAAM,UAAU,gBAAgB,OAAO,MAAM,EAAE;AAC/C,MAAI,CAAC,QAAQ;AAAI,WAAO;AACxB,QAAM,SAAS,UAAU,KAAK;AAC9B,MAAI,CAAC,OAAO;AAAI,WAAO;AACvB,QAAM,OACJD,UAAS,QAAQ,MAAM,KAAK,KAAKA,UAAS,OAAO,KAAK,IAClD,EAAE,GAAG,QAAQ,MAAM,OAAO,GAAG,OAAO,MAAK,IACzC,OAAO;AACb,SAAO,mBAAmB,OAAO,MAAM,IAAI,IAAI;AACjD;AAEO,IAAM,oBAAoB,CAC/B,OACA,MACA,OAC+B;AAC/B,MAAI,CAAC,gBAAgB,KAAK,IAAI;AAAG,WAAO,KAAK,KAAK,gCAAgC;AAClF,QAAM,UAAU,UAAU,EAAE;AAC5B,MAAI,CAAC,QAAQ;AAAI,WAAO;AACxB,QAAM,aAAa,aAAa,MAAM,QAAQ,MAAM,kBAAkB,IAAI;AAC1E,SAAO,WAAW,OAAO,QAAQ,KAAK,IAClC,EAAE,IAAI,MAAM,OAAO,EAAE,IAAI,QAAQ,MAAK,EAAE,IACxC,KAAK,KAAK,aAAa,QAAQ,KAAK,OAAO,IAAI,EAAE;AACvD;AAEA,IAAME,QAAO,CAAC,QAAgB,SAC5B,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG;EACjC;EACA,SAAS,EAAE,gBAAgB,kCAAiC;CAC7D;AAEH,IAAMC,cAAa,CAAC,QAAgB,YAClCD,MAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,QAAO,EAAE,CAAE;AAEhE,IAAM,aAAa,CAAI,QAAwB,WAC7C,OAAO,KAAKA,MAAK,QAAQ,OAAO,KAAK,IAAIC,YAAW,OAAO,QAAQ,OAAO,OAAO;AAEnF,IAAM,eAAe,CAAC,UAAoD;AACxE,MAAI,UAAU;AAAM,WAAO;AAC3B,MAAI,CAAC,UAAU,KAAK,KAAK;AAAG,WAAO;AACnC,SAAO,OAAO,KAAK;AACrB;AAUO,IAAM,mBAAmB,CAAC,WAAoC;AACnE,QAAM,OAAO,CAAC,cAA8C;AAC1D,QAAI;AACF,aAAO,EAAE,IAAI,MAAM,OAAO,OAAO,KAAK,SAAS,EAAC;IAClD,SAAS,OAAO;AACd,aAAO,KAAK,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;IACzE;EACF;AACA,QAAM,QAAQ,CAAC,cAAqB;AAClC,WAAO,aAAa,SAAS;EAC/B;AACA,SAAO;IACL,cAAc,CAAC,EAAE,UAAS,MAAM;AAC9B,YAAM,QAAQ,KAAK,SAAS;AAC5B,aAAO,WAAW,MAAM,KAAK,EAAE,IAAI,MAAM,OAAO,aAAa,MAAM,KAAK,EAAC,IAAK,OAAO,GAAG;IAC1F;IACA,0BAA0B,CAAC,EAAE,WAAW,QAAQ,IAAG,MAAM;AACvD,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,YAAM,QAAQ,aAAa,IAAI,aAAa,IAAI,OAAO,CAAC;AACxD,YAAM,QAAQ,aAAa,IAAI,aAAa,IAAI,OAAO,CAAC;AACxD,UAAI,UAAU;AAAO,eAAOA,YAAW,KAAK,4BAA4B;AACxE,UAAI,UAAU;AAAO,eAAOA,YAAW,KAAK,mCAAmC;AAC/E,YAAM,QAAQ,IAAI,aAAa,IAAI,OAAO;AAC1C,aAAO,WACL,cAAc,MAAM,OAAO,OAAO,cAAc,IAAI;QAClD,GAAI,UAAU,SAAY,EAAE,MAAK,IAAK,CAAA;QACtC,GAAI,UAAU,SAAY,EAAE,MAAK,IAAK,CAAA;QACtC,GAAI,UAAU,YAAY,UAAU,WAAW,EAAE,MAAK,IAAK,CAAA;OAC5D,GACD,GAAG;IAEP;IACA,8BAA8B,CAAC,EAAE,WAAW,OAAM,MAAM;AACtD,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,aAAO,WAAW,gBAAgB,MAAM,OAAO,OAAO,cAAc,IAAI,OAAO,MAAM,EAAE,GAAG,GAAG;IAC/F;IACA,2BAA2B,CAAC,EAAE,WAAW,QAAQ,KAAI,MAAM;AACzD,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,UAAI,CAACH,UAAS,IAAI,KAAK,EAAE,WAAW,OAAO;AACzC,eAAOG,YAAW,KAAK,2CAA2C;MACpE;AACA,YAAM,KAAK,KAAK;AAChB,UAAI,OAAO,UAAa,OAAO,OAAO;AAAU,eAAOA,YAAW,KAAK,qBAAqB;AAC5F,YAAM,UAAU,kBAAkB,MAAM,OAAO,OAAO,cAAc,IAAI;QACtE,GAAI,OAAO,OAAO,WAAW,EAAE,GAAE,IAAK,CAAA;QACtC,OAAO,KAAK;OACb;AACD,UAAI,QAAQ;AAAI,cAAM,SAAS;AAC/B,aAAO,WAAW,SAAS,GAAG;IAChC;IACA,8BAA8B,CAAC,EAAE,WAAW,QAAQ,KAAI,MAAM;AAC5D,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,UAAI,CAACH,UAAS,IAAI,KAAK,EAAE,WAAW;AAClC,eAAOG,YAAW,KAAK,4BAA4B;AACrD,YAAM,WAAW,mBACf,MAAM,OACN,OAAO,cAAc,IACrB,OAAO,MAAM,IACb,KAAK,KAAK;AAEZ,UAAI,SAAS;AAAI,cAAM,SAAS;AAChC,aAAO,WAAW,UAAU,GAAG;IACjC;IACA,gCAAgC,CAAC,EAAE,WAAW,QAAQ,KAAI,MAAM;AAC9D,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,UAAI,CAACH,UAAS,IAAI,KAAK,EAAE,WAAW;AAClC,eAAOG,YAAW,KAAK,4BAA4B;AACrD,YAAM,UAAU,iBACd,MAAM,OACN,OAAO,cAAc,IACrB,OAAO,MAAM,IACb,KAAK,KAAK;AAEZ,UAAI,QAAQ;AAAI,cAAM,SAAS;AAC/B,aAAO,WAAW,SAAS,GAAG;IAChC;IACA,iCAAiC,CAAC,EAAE,WAAW,OAAM,MAAM;AACzD,YAAM,QAAQ,KAAK,SAAS;AAC5B,UAAI,CAAC,MAAM;AAAI,eAAO,WAAW,OAAO,GAAG;AAC3C,YAAM,UAAU,kBAAkB,MAAM,OAAO,OAAO,cAAc,IAAI,OAAO,MAAM,EAAE;AACvF,UAAI,QAAQ;AAAI,cAAM,SAAS;AAC/B,aAAO,WAAW,SAAS,GAAG;IAChC;;AAEJ;;;ACtkBO,IAAM,kBACX,OACI,sBACA;;;ACLN,IAAM,UAAU,IAAI,YAAW;AAExB,IAAM,WAAW,CAAC,UAA2C;AAClE,MAAI,SAAS;AACb,aAAW,QAAQ,iBAAiB,aAAa,QAAQ,IAAI,WAAW,KAAK,GAAG;AAC9E,cAAU,OAAO,aAAa,IAAI;EACpC;AACA,SAAO,KAAK,MAAM;AACpB;AAEO,IAAM,aAAa,CAAC,UACzB,WAAW,KAAK,KAAK,KAAK,GAAG,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC;;;AC8c3D,IAAMC,QAAO,CAAC,QAAgB,SAC5B,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,SAAS,EAAE,gBAAgB,mBAAkB,EAAE,CAAE;AAEhG,IAAMC,cAAa,CAAC,QAAgB,YAClCD,MAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,QAAO,EAAE,CAAE;AAEhE,IAAME,YAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,gBAAgB,CAAC,UAA4C;AACjE,MAAI,CAACA,UAAS,KAAK,KAAK,OAAO,MAAM,QAAQ;AAAU,WAAO;AAC9D,MAAI;AACF,QAAI,IAAI,MAAM,GAAG;EACnB,QAAQ;AACN,WAAO,cAAc,MAAM,GAAG;EAChC;AACA,QAAM,WAA4B,EAAE,KAAK,MAAM,IAAG;AAClD,MAAI,OAAO,MAAM,OAAO;AAAU,aAAS,KAAK,MAAM;AACtD,MAAI,OAAO,MAAM,WAAW;AAAU,aAAS,SAAS,MAAM;AAC9D,MAAI,OAAO,MAAM,YAAY;AAAU,aAAS,UAAU,MAAM;AAChE,QAAM,SAAS,MAAM,UAAU,MAAM;AACrC,MAAI,MAAM,QAAQ,MAAM;AAAG,aAAS,SAAS,OAAO,IAAI,MAAM;AAC9D,MAAIA,UAAS,MAAM,IAAI,GAAG;AACxB,aAAS,OAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAC/F;AACA,MAAI,OAAO,MAAM,YAAY;AAC3B,aAAS,OAAO,EAAE,GAAG,SAAS,MAAM,SAAS,MAAM,QAAO;AAC5D,MAAIA,UAAS,MAAM,OAAO,GAAG;AAC3B,aAAS,UAAU,OAAO,YACxB,OAAO,QAAQ,MAAM,OAAO,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAEjE;AACA,SAAO;AACT;AAUO,IAAM,qBAAqB,CAAC,SAAkC;EACnE,iBAAiB,CAAC,EAAE,KAAK,UAAS,MAChCF,MAAK,KAAK;IACR,YAAY,IACT,WAAW,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,SAAY,SAAS,EACtE,OAAO,CAAC,MAAK;AACZ,YAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,aAAO,SAAS,QAAQ,EAAE,SAAS;IACrC,CAAC;GACJ;EACH,wBAAwB,CAAC,EAAE,KAAK,UAAS,MAAM;AAC7C,UAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,WAAOA,MAAK,KAAK;MACf,QAAQ,IACL,SAAS,IAAI,aAAa,IAAI,KAAK,MAAM,MAAM,SAAY,SAAS,EACpE,OAAO,CAAC,MAAM,SAAS,QAAQ,EAAE,SAAS,IAAI,EAC9C,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,aAAa,CAAC,EAAC,EAAG;KACnD;EACH;EACA,6BAA6B,OAAO,EAAE,OAAM,MAAM;AAChD,UAAM,WAAW,MAAM,IAAI,OAAO,OAAO,EAAY;AACrD,WAAO,WAAWA,MAAK,KAAK,QAAQ,IAAIC,YAAW,KAAK,eAAe,OAAO,EAAE,EAAE;EACpF;EACA,wBAAwB,YAAW;AACjC,UAAM,IAAI,MAAK;AACf,WAAOD,MAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;EACnC;EACA,yBAAyB,CAAC,EAAE,MAAM,UAAS,MAAM;AAC/C,QAAI,CAACE,UAAS,IAAI,KAAK,CAAC,CAAC,aAAa,WAAW,MAAM,EAAE,SAAS,OAAO,KAAK,IAAI,CAAC,GAAG;AACpF,aAAOD,YAAW,KAAK,yCAAyC;IAClE;AACA,UAAM,QAAsB,EAAE,MAAM,KAAK,KAA4B;AACrE,QAAI,OAAO,KAAK,UAAU;AAAU,YAAM,QAAQ,KAAK;AACvD,QAAI,MAAM,WAAW,KAAK;AAC1B,WAAOD,MAAK,KAAK,EAAE,WAAW,GAAG,MAAK,CAAE;EAC1C;EACA,0BAA0B,CAAC,EAAE,UAAS,MACpCA,MAAK,KAAK;IACR,WAAW,IAAI,UAAU,SAAS,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAI,OAAQ;MAChE,GAAG;MACH,QAAQ,SAAS,UAAU;MAC3B;GACH;EACH,0BAA0B,CAAC,EAAE,MAAM,UAAS,MAAM;AAChD,UAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAOE,UAAS,IAAI,IAAI,KAAK,YAAY;AAC5E,QAAI,CAAC,MAAM,QAAQ,IAAI;AAAG,aAAOD,YAAW,KAAK,oCAAoC;AACrF,UAAM,SAA4B,CAAA;AAClC,eAAW,QAAQ,MAAM;AACvB,YAAM,WAAW,cAAc,IAAI;AACnC,UAAI,OAAO,aAAa;AAAU,eAAOA,YAAW,KAAK,QAAQ;AACjE,aAAO,KAAK,QAAQ;IACtB;AACA,UAAM,MAAM,IAAI,aAAa,WAAW,MAAM;AAC9C,WAAOD,MAAK,KAAK,EAAE,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,SAAS,UAAU,KAAI,EAAG,EAAC,CAAE;EAC/F;EACA,6BAA6B,CAAC,EAAE,UAAS,MAAM;AAC7C,QAAI,aAAa,WAAW,CAAA,CAAE;AAC9B,WAAOA,MAAK,KAAK,EAAE,QAAQ,KAAI,CAAE;EACnC;;AAGF,IAAM,eAAe,CAAC,YAAoC;AACxD,MAAI,QAAQ,YAAY,WAAW,kBAAkB,GAAG;AACtD,QAAI;AACF,aAAO,KAAK,MAAM,QAAQ,IAAI;IAChC,QAAQ;AACN,aAAO,QAAQ;IACjB;EACF;AACA,MAAI,QAAQ,YAAY,WAAW,mCAAmC,GAAG;AACvE,WAAO,OAAO,YAAY,IAAI,gBAAgB,QAAQ,IAAI,CAAC;EAC7D;AACA,SAAO,QAAQ;AACjB;;;ACnjBO,IAAM,qBAAqB;AAE3B,IAAM,gBAAgB;AAEtB,IAAM,YAAY;AAElB,IAAM,oBAAoB;AAyH1B,IAAM,oBAAoB;AAEjC,IAAM,oBAAoB;AAG1B,IAAM,cAAc;AACpB,IAAMG,kBAAiB;AACvB,IAAM,mBAAmB,oBAAI,IAAI,CAAC,QAAQ,OAAO,SAAS,QAAQ,CAAC;AAEnE,IAAM,UAAU,oBAAI,QAAO;AAM3B,IAAM,cAAc,CAClB,OACA,UACA,SACA,UACO;AACP,MAAI,CAAC,YAAY,SAAS,WAAW;AAAG,WAAO,MAAM,IAAI,CAACC,SAAQ,OAAO,OAAOA,IAAG,CAAC;AACpF,QAAM,SAAS,IAAI,MAAS,MAAM,MAAM;AACxC,MAAI,YAAY,MAAM,WAAW,SAAS;AAC1C,MAAI,WAAW;AACf,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;AACjD,UAAMA,OAAM,MAAM,KAAK;AACvB,WAAO,WAAW,SAAS,UAAU,QAAQ,SAAS,QAAQ,GAAQA,IAAG,IAAI,GAAG;AAC9E;IACF;AACA,UAAM,MAAM,SAAS,QAAQ;AAC7B,WAAO,KAAK,IACV,QAAQ,UAAa,QAAQ,KAAKA,IAAG,MAAM,KAAK,MAAM,KAAKA,IAAG,IAAI,MAAM,OAAO,OAAOA,IAAG;AAC3F,QAAI,OAAO,KAAK,MAAM,SAAS,KAAK;AAAG,kBAAY;EACrD;AACA,SAAO,YAAY,WAAW;AAChC;AAMO,IAAM,eAAe,CAC1B,aAEC,QAAQ,IAAI,OAAO,KAAK,CAAA,GAAI,OAAO,CAAC,MAAkC,MAAM,MAAS;AAGjF,IAAM,cAAc,CAAC,SAAkB,SAC5C,aAAa,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,GAAG;AAMhD,IAAO,yBAAP,cAAsC,UAAS;EAC1C,OAAO;EAChB,cAAA;AACE,UAAM,uDAAuD;AAC7D,SAAK,OAAO;EACd;;AAMF,IAAM,mBAAmB,CAACC,cAA6B;AACrD,QAAM,WAAsB,eAAeA,SAAQ,EAChD,IAAI,CAAC,eAAe;IACnB,aAAa,UAAU;IACvB,QAAQ,UAAU,OAAO,YAAW;IACpC,SAAS,IAAI,OACX,IAAI,UAAU,KACX,MAAM,GAAG,EACT,IAAI,CAAC,YACJ,QAAQ,WAAW,GAAG,IAAI,UAAU,QAAQ,QAAQ,uBAAuB,MAAM,CAAC,EAEnF,KAAK,GAAG,CAAC,KAAK;IAEnB,SAAS,UAAU,KAAK,MAAM,KAAK,KAAK,CAAA,GAAI;IAC5C,EACD,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM;AACrC,SAAO,CAAC,SAAkB,SACxB,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAC,GAAG;AAC/E;AAWO,IAAM,gBAAgB,CAC3B,YACqB;AACrB,gBAAc,QAAQ,OAAO;AAC7B,QAAM,SAAS,WAAW,QAAQ,MAAM;AACxC,QAAM,QAAQ,QAAQ,SAAS,YAAW;AAC1C,QAAM,MAAM,UAAU,QAAQ,QAAQ,CAAC;AACvC,QAAM,UAAU,QAAQ,IAAI,WAAW,KAAK;AAC5C,QAAM,eAAe,QAAQ,IAAI,iBAAiB,MAAM,YAAY,IAAG;AACvE,QAAM,QACJ,QAAQ,IAAI,UAAU,CAAC,OAAe,IAAI,QAAc,CAACC,aAAY,WAAWA,UAAS,EAAE,CAAC;AAC9F,QAAM,SAAS,oBAAoB,UAAU,QAAQ,QAAQ,CAAC,GAAG,KAAK;AACtE,QAAM,UAAU,cAAa;AAC7B,QAAM,UAAU,cAAc,QAAQ,eAAe,oBAAoB;AACzE,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,YAAY,oBAAI,IAAG;AACzB,QAAM,mBAAmB,oBAAI,IAAG;AAChC,QAAM,aAAa,oBAAI,IAAG;AAC1B,QAAM,YAAY,oBAAI,IAAG;AACzB,QAAM,gBAAgB,oBAAI,IAAG;AAC7B,QAAM,WAAW,oBAAI,IAAG;AACxB,QAAM,cAAc,yBAAwB;AAC5C,QAAM,iBAAiB,QAAQ,WAAW,iBAAiB,QAAQ,QAAQ,IAAI,MAAM;AAErF,QAAM,mBAAmB,CAAC,SACxB,SAAS,oBAAoB,QAAQ,OAAO,GAAG,QAAQ,IAAI,IAAI,IAAI;AAErE,QAAM,cAAc,CAAC,KAAa,kBAAkB,KAAK,gBAAwB;AAC/E,UAAM,WAAW,UAAU,IAAI,GAAG;AAClC,QAAI;AAAU,aAAO;AACrB,QAAI,CAAC,kBAAkB,KAAK,GAAG,KAAK,CAAC,kBAAkB,KAAK,eAAe,GAAG;AAC5E,YAAM,IAAI,WACR,wBAAwB,iBAAiB,KAAK,KAAK,UAAU,eAAe,CAAC,EAAE;IAEnF;AACA,UAAM,UAAU,QAAQ,OAAO;MAC7B,WAAW,iBAAiB,GAAG;MAC/B;MACA;MACA;MACA,KAAK,eAAe;KACrB;AACD,cAAU,IAAI,KAAK,OAAO;AAC1B,qBAAiB,IAAI,eAAe;AACpC,QAAI;AAAa,iBAAW,IAAI,KAAK,WAAW;AAChD,WAAO;EACT;AAEA,QAAM,WAAW,CAAC,OAAe,sBAAyB,YAAY,IAAI;AAE1E,QAAM,UAAU,CAAC,YAAyC;AACxD,UAAM,QAAQ,kBAAkB,QAAQ,iBAAiB,OAAO,CAAC;AACjE,UAAM,WAAW,SAAS,IAAI,OAAO;AACrC,UAAMC,YAA8B;MAClC,WAAW,MAAM;MACjB,SAAS,YACP,MAAM,SACN,UAAU,SACV,CAAC,MAAM,UACL,KAAK,aAAa,MAAM,aACpB,KACA,KAAK,aAAa,MAAM,aACtB,IACA,KAAK,MAAM,MAAM,KACzB,CAAC,MAAM,UAAU,KAAK,OAAO,MAAM,MAAM,KAAK,UAAU,MAAM,KAAK;MAErE,WAAW,YACT,MAAM,WACN,UAAU,WACV,CAAC,MAAM,UACL,KAAK,OAAO,MAAM,OACd,KACA,KAAK,OAAO,MAAM,OAChB,IACA,KAAK,OAAO,MAAM,OAChB,KACA,KAAK,OAAO,MAAM,OAChB,IACA,GACZ,CAAC,MAAM,UAAU,KAAK,UAAU,MAAM,KAAK;;AAG/C,WAAO,OAAOA,UAAS,OAAO;AAC9B,WAAO,OAAOA,UAAS,SAAS;AAChC,WAAO,OAAOA,SAAQ;AACtB,aAAS,IAAI,SAASA,SAAQ;AAC9B,WAAO,OAAO,OAAO;MACnB,UAAAA;MACA,OAAO,OAAO,OAAO,MAAM,MAAK,CAAE;MAClC,WAAW,WAAW,IAAI,OAAO,KAAK,KAAK,MAAK;KACjD;EACH;AAEA,QAAM,WAAW,CAAC,OAAe,sBAAqD;AACpF,QAAI,QAAQ,UAAU,IAAI,IAAI;AAC9B,QAAI;AAAO,aAAO;AAClB,aAAS,IAAI;AACb,YAAQ,IAAI,SAA+B;MACzC,KAAK,MAAM;MACX,GAAI,QAAQ,mBAAmB,SAAY,EAAE,gBAAgB,QAAQ,eAAc,IAAK,CAAA;KACzF;AACD,UAAM,OAAO,QAAQ,IAAI,CAAC;AAC1B,cAAU,IAAI,MAAM,KAAK;AACzB,WAAO;EACT;AAEA,QAAM,iBAAiB,CAAC,WAAmBC,YAA0B;AACnE,QAAIA,YAAW;AAAQ,aAAO;AAC9B,UAAM,SAAS,GAAG,SAAS,KAAKA,OAAM;AACtC,UAAM,WAAW,cAAc,IAAI,MAAM;AACzC,QAAI;AAAU,aAAO;AAErB,UAAM,MAAM,UAAU,SAAS,GAAG,QAAQ,IAAI,KAAK,SAAS,KAAKA,OAAM,EAAE,EAAE,SAAS,EAAE,CAAC;AACvF,kBAAc,IAAI,QAAQ,GAAG;AAC7B,WAAO;EACT;AAEA,QAAM,eAAe,CAAC,WAAmBA,SAAgB,OAAuB;AAC9E,QAAI,CAACL,gBAAe,KAAKK,OAAM;AAAG,YAAM,IAAI,WAAW,qBAAqBL,eAAc,EAAE;AAC5F,UAAMM,WAAU,SAAS,SAAS;AAClC,QAAID,YAAW,QAAQ;AACrB,UAAI,OAAO,QAAW;AACpB,cAAM,QAAQC,SAAQ,SAAS,QAAQ,EAAE;AACzC,yBAAiB,QAAQ,iBAAiB,SAAS,GAAG,MAAM,MAAM,QAAQ;AAC1E,iBAAS,IAAI,WAAW,MAAM,MAAM,QAAQ;AAC5C,YAAI,SAAS,MAAM,MAAM,QAAQ;AACjC,cAAM,IAAI,MAAM,MAAM,MAAM,GAAG;AAC/B,YAAI,MAAM,MAAM,MAAM;AAAQ,gBAAM,OAAM;;AACrC,gBAAM,SAAQ;MACrB;AACA,aAAO;IACT;AACA,UAAM,UAAU,eAAe,WAAWD,OAAM;AAChD,QAAI,CAACC,SAAQ,UAAUD,OAAM,GAAG;AAE9B,UAAI,OAAO;AAAW,QAAAC,SAAQ,OAAO,QAAQ,SAAS,CAAC;AACvD,YAAM,QAAQA,SAAQ,KAAKD,SAAQ,OAAO,SAAY,CAAA,IAAK,EAAE,MAAM,GAAE,CAAE;AACvE,YAAM,YAAY,UAAU,QAAQ,QAAQ,CAAC;AAC7C,UAAI;AAAO,kBAAU,SAAS,MAAM,MAAM,QAAQ;AAClD,kBAAY,SAAS,WAAW,SAAS;AACzC,UAAI;AAAO,yBAAiB,QAAQ,iBAAiB,OAAO,GAAG,MAAM,MAAM,QAAQ;AACnF,UAAI;AAAO,iBAAS,IAAI,SAAS,MAAM,MAAM,QAAQ;IACvD,WAAW,OAAO,UAAaC,SAAQ,KAAKD,OAAM,GAAG,OAAO,IAAI;AAC9D,YAAM,QAAQC,SAAQ,SAASD,SAAQ,EAAE;AACzC,UAAI,CAAC,UAAU,IAAI,OAAO,GAAG;AAC3B,cAAM,YAAY,UAAU,QAAQ,QAAQ,CAAC;AAC7C,kBAAU,SAAS,MAAM,MAAM,QAAQ;AACvC,oBAAY,SAAS,WAAW,SAAS;MAC3C;AACA,iBAAW,IAAI,OAAO,GAAG,SAAS,MAAM,MAAM,QAAQ;AACtD,uBAAiB,QAAQ,iBAAiB,OAAO,GAAG,MAAM,MAAM,QAAQ;AACxE,eAAS,IAAI,SAAS,MAAM,MAAM,QAAQ;IAC5C,OAAO;AACL,UAAI,CAAC,UAAU,IAAI,OAAO,GAAG;AAC3B,cAAM,QAAQC,SAAQ,KAAKD,OAAM;AACjC,cAAM,YAAY,UAAU,QAAQ,QAAQ,CAAC;AAC7C,YAAI;AAAO,oBAAU,SAAS,MAAM,MAAM,QAAQ;AAClD,oBAAY,SAAS,WAAW,SAAS;MAC3C;IACF;AACA,WAAO;EACT;AAEA,QAAM,aAAa,CAAC,YAAY,mBAAmBA,UAAS,WAA6B;AACvF,UAAM,UAAU,aAAa,WAAWA,OAAM;AAC9C,WAAO,SAAS,SAAS,EAAE,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAAA,QAAM,CAAE;EAChE;AAEA,QAAM,SAAS,CACb,MACA,gBAAqD,CAAA,MAChC;AACrB,UAAM,YAAY,cAAc,aAAa;AAC7C,iBAAa,WAAW,MAAM,cAAc,EAAE;AAC9C,UAAM,OAAO,SAAS,SAAS,EAAE,KAAK,IAAI;AAC1C,QAAI,CAAC;AAAM,YAAM,IAAI,WAAW,UAAU,IAAI,oBAAoB;AAClE,WAAO;EACT;AAEA,QAAM,WAAW,CACf,cACA,kBAA2D,CAAA,MACnD;AACR,UAAM,YAAY,gBAAgB,aAAa;AAC/C,UAAM,aAAa,gBAAgB,UAAU;AAC7C,UAAMC,WAAU,SAAS,SAAS;AAClC,UAAM,QAAQA,SAAQ,SAAS,YAAY,YAAY;AACvD,UAAM,UAAU,aAAa,WAAW,UAAU;AAClD,qBAAiB,QAAQ,iBAAiB,OAAO,GAAG,MAAM,MAAM,QAAQ;AACxE,aAAS,IAAI,SAAS,MAAM,MAAM,QAAQ;AAC1C,UAAM,IAAI,MAAM,MAAM,MAAM,GAAG;AAC/B,QAAI,MAAM,MAAM,MAAM;AAAQ,YAAM,OAAM;;AACrC,YAAM,SAAQ;AAClB,KAAC,WAAW,IAAI,OAAO,KAAK,KAAK,SAAS,MAAM,MAAM,QAAQ;EACjE;AAEA,QAAM,QAAQ,OAAO,OAAe,sBAAoC;AACtE,QAAI,SAAS,KAAK;AAChB,cAAQ,UAAU,MAAK;AACvB,iBAAW,QAAQ,UAAU,OAAM;AAAI,cAAM,KAAK,MAAK;AACvD,gBAAU,MAAK;AACf,oBAAc,MAAK;AACnB,iBAAW,MAAK;AAChB,eAAS,MAAK;AACd;IACF;AACA,YAAQ,UAAU,MAAM,IAAI;AAC5B,UAAM,SAAS,UAAU,IAAI,IAAI;AACjC,QAAI;AAAQ,YAAM,OAAO,MAAK;;AACzB,qBAAe,QAAQ,iBAAiB,IAAI,CAAC;AAClD,eAAW,CAAC,SAAS,OAAO,KAAK,eAAe;AAC9C,UAAI,CAAC,QAAQ,WAAW,GAAG,IAAI,IAAI;AAAG;AACtC,YAAM,iBAAiB,UAAU,IAAI,OAAO;AAC5C,UAAI;AAAgB,cAAM,eAAe,MAAK;;AACzC,uBAAe,QAAQ,iBAAiB,OAAO,CAAC;AACrD,oBAAc,OAAO,OAAO;AAC5B,iBAAW,OAAO,OAAO;AACzB,eAAS,OAAO,OAAO;IACzB;AACA,cAAU,OAAO,IAAI;AACrB,aAAS,OAAO,IAAI;EACtB;AAEA,QAAM,WAAW,CAAC,OAAe,sBAAwC;AACvE,WAAO,WAAW,MAAM,MAAM,EAAE,MAAM;EACxC;AAEA,QAAM,UAAU,CAAC,MAAyB,OAAe,sBAA2B;AAClF,aAAS,IAAI;AACb,qBAAiB,QAAQ,iBAAiB,IAAI,GAAG,IAAI;AACrD,aAAS,IAAI,MAAM,IAAI;AAGvB,UAAMA,WAAU,UAAU,IAAI,IAAI;AAClC,QAAIA;AAAS,MAAAA,SAAQ,OAAO,QAAQ,IAAI,GAAG,EAAE,QAAQ,OAAM,CAAE;;AACxD,eAAS,IAAI;EACpB;AAEA,QAAM,kBAAkB,CAAC,cAAkD;AACzE,UAAM,WAAW,QAAQ;AACzB,QAAI,CAAC;AAAU,aAAO,CAAA;AACtB,WAAO,OAAO,aAAa,aAAa,SAAS,SAAS,SAAS,GAAG,SAAS,IAAI;EACrF;AAEA,QAAM,aAAa,CAAC,eAAuB;IACzC;IACA;IACA,kBAAkB,iBAAiB,SAAS;IAC5C,MAAM,SAAS,SAAS;IACxB,cAAc,gBAAgB,SAAS;;AAGzC,QAAM,UAA6B;IACjC,MAAM,QAAQ;IACd;IACA;IACA;IACA;IACA;IACA;IACA;IACA,UAAU,QAAQ;IAClB,aAAa,CAAC,MAAM,YAAY,mBAAmB,YAAY,CAAA,MAAM;AACnE,YAAM,SAAS,QAAQ,UAAU,IAAI;AACrC,UAAI,CAAC;AAAQ,cAAM,IAAI,WAAW,mBAAmB,KAAK,UAAU,IAAI,CAAC,EAAE;AAC3E,YAAM,SAAS,OAAO,SAAS,CAAA,GAAI,IAAI,CAAC,MAAM,UAC5C,OAAO,IAAI;QACT;QACA,GAAG;QACH,GAAG;QACH,QAAQ;QACR,IAAI,GAAG,UAAU,MAAM,IAAI,IAAI,OAAO,SAAS,CAAA,GAAI,SAAS,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE;OACxE,CAAC;AAEjB,UAAI,OAAO,WAAW,QAAQ,UAAU;AACtC,gBAAQ,SAAS,MAAM,WAAW;UAChC,GAAG,OAAO;UACV,GAAI,UAAU,UAAU,SAAY,EAAE,OAAO,UAAU,MAAK,IAAK,CAAA;SAClE;MACH;AACA,aAAO;IACT;IACA;IACA,YAAY,MAAM,CAAC,GAAG,gBAAgB,EAAE,KAAI;IAC5C;IACA;IACA;IACA;IACA;IACA;IACA;IACA,OAAO,CAAC,YAAY,sBAAsB,aAAa,WAAW,SAAS,CAAC;IAC5E,OAAO,OAAO,aAAY;AACxB,UAAI,UAAU;AAEd,YAAM,WAAW,YAAY,KAAK,IAAI,IAAI,QAAQ,GAAG,EAAE,QAAQ;AAC/D,UAAI,UAAU;AACZ,cAAMC,OAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAAA,KAAI,WAAW,SAAS,CAAC,KAAK;AAC9B,cAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,YAAI,CAAC,QAAQ,IAAI,gBAAgB,GAAG;AAClC,kBAAQ,IAAI,kBAAkB,mBAAmB,SAAS,CAAC,CAAW,CAAC;QACzE;AACA,cAAM,UAAU,QAAQ,WAAW,SAAS,QAAQ,WAAW;AAC/D,kBAAU,IAAI,QAAQA,MAAK;UACzB,QAAQ,QAAQ;UAChB;UACA,GAAI,UAAU,EAAE,MAAM,MAAM,QAAQ,YAAW,EAAE,IAAK,CAAA;UACtD,QAAQ,QAAQ;SACjB;MACH;AACA,UAAI,YAAY,QAAQ,YAAY,OAAO;AAC3C,UAAI,CAAC,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,QAAQ,YAAY;AAChE,cAAM,aAAa,QAAQ,WAAW,OAAO;AAC7C,cAAM,SAAS,eAAe,SAAY,YAAY,IAAI,UAAU,IAAI;AACxE,YAAI,WAAW;AAAW,sBAAY;MACxC;AACA,YAAM,iBAAiB,QAAQ,QAAQ,IAAI,aAAa,KAAK;AAC7D,YAAM,KAAK,QAAQ,QAAQ,IAAI,SAAS,KAAK;AAC7C,YAAM,QAAQ,CAACC,cAAgC;AAE7C,cAAM,QAAQ,kBAAkB,KAAK,SAAS,IAC1C,GAAG,QAAQ,IAAI,IAAI,OAAO,QAAQ,SAAS,KAC3C,GAAG,QAAQ,IAAI,IAAI,OAAO;AAC9B,YAAI;AACF,UAAAA,UAAS,QAAQ,IAAI,oBAAoB,KAAK;AAC9C,iBAAOA;QACT,QAAQ;AAEN,gBAAM,OAAO,IAAI,SAASA,UAAS,MAAMA,SAAQ;AACjD,eAAK,QAAQ,IAAI,oBAAoB,KAAK;AAC1C,iBAAO;QACT;MACF;AACA,YAAM,UAAU,MAAM,QAAQ,OAAO,OAAO;AAC5C,UAAI;AAAS,eAAO,MAAM,OAAO;AACjC,YAAM,UAAU,aAAY;AAC5B,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,YAAM,cAAc,eAAe,SAAS,IAAI,QAAQ;AAIxD,YAAM,gBAAgB,QAAQ,QAAQ,IAAI,gBAAgB;AAC1D,YAAM,WAA4B;QAChC,aAAa,QAAQ,QAAQ,IAAI,cAAc;QAC/C,WACE,kBAAkB,QAAQ,QAAQ,KAAK,aAAa,IAAI,OAAO,aAAa,IAAI;QAClF,kBAAkB,QAAQ,QAAQ,IAAI,mBAAmB;;AAE3D,YAAM,MAAM,CAAC,QAAgB,SAAkBA,cAAuB;AACpE,cAAM,QAAQA,YAAW,cAAcA,SAAQ,IAAI;AACnD,cAAM,WAAW,UAAU,OAAO,YAAY;AAC9C,cAAM,QAAoB;UACxB,SAAS,QAAQ;UACjB;UACA;UACA,QAAQ,QAAQ;UAChB,MAAM,IAAI;UACV;UACA,YAAY,KAAK,OAAO,aAAY,IAAK,WAAW,GAAG,IAAI;UAC3D,WAAW,QAAQ,aAAa,UAAa,gBAAgB;UAC7D,GAAI,YAAY,SAAY,EAAE,QAAO,IAAK,CAAA;UAC1C,GAAI,OAAO,OAAO,OAAO,KAAK,MAAM,GAAG,EAAE,SAAS,IAAI,EAAE,KAAK,MAAM,IAAG,IAAK,CAAA;UAC3E,GAAI,OAAO,UAAU,EAAE,SAAS,KAAI,IAAK,CAAA;UACzC,GAAI,WAAW,EAAE,SAAS,EAAE,GAAG,SAAQ,EAAE,IAAK,CAAA;UAC9C,GAAI,YAAY,OAAO,UAAU,MAAM,OAAO,SAAS,IACnD,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,MAAK,EAAG,EAAC,IACrD,CAAA;;AAEN,gBAAQ,OAAO,KAAK;AACpB,gBAAQ,OAAO,EAAE,GAAG,OAAO,IAAI,IAAI,KAAK,MAAM,IAAG,CAAE,EAAE,YAAW,EAAE,CAAE;AACpE,gBAAQ,QAAQ,KAAK;MACvB;AACA,UAAI,CAAC,kBAAkB,KAAK,SAAS,GAAG;AACtC,YAAI,GAAG;AACP,eAAO,MACL,IAAI,SACF,KAAK,UAAU;UACb,OAAO;YACL,MAAM;YACN,SAAS,GAAG,gBAAgB,eAAe,iBAAiB;;SAE/D,GACD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAkB,EAAE,CAAE,CACjE;MAEL;AACA,UAAI,CAACR,gBAAe,KAAK,cAAc,GAAG;AACxC,YAAI,GAAG;AACP,eAAO,MAAM,UAAU,KAAK,GAAG,aAAa,eAAeA,eAAc,EAAE,CAAC;MAC9E;AACA,UAAI;AACJ,UAAI;AACF,YACE,OAAO,UACP,mBAAmB,UACnB,CAAC,iBAAiB,IAAI,QAAQ,MAAM,GACpC;AACA,gBAAM,QAAQ,SAAS,SAAS,EAAE,IAAI,EAAE;AACxC,oBAAU,eAAe,WAAW,MAAM,EAAE,EAAE;AAC9C,cAAI,UAAU,WAAW,IAAI,OAAO;AACpC,cAAI,CAAC,SAAS;AACZ,sBAAU,UAAU,QAAQ,QAAQ,CAAC;AACrC,wBAAY,SAAS,WAAW,OAAO;UACzC;AACA,kBAAQ,SAAS,MAAM,MAAM,QAAQ;AACrC,2BAAiB,QAAQ,iBAAiB,OAAO,GAAG,MAAM,MAAM,QAAQ;AACxE,mBAAS,IAAI,SAAS,MAAM,MAAM,QAAQ;QAC5C,OAAO;AACL,oBAAU,aAAa,WAAW,gBAAgB,EAAE;QACtD;MACF,SAAS,OAAO;AACd,YAAI,GAAG;AACP,eAAO,MAAM,UAAU,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;MACrF;AACA,YAAM,OAAO,MAAM,OAAO,KAAK;QAC7B;QACA,QAAQ,QAAQ;QAChB,MAAM,IAAI;QACV;OACD;AACD,YAAM,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,QAAQ,IAAI,QAAQ;AACzD,UAAI,OAAO,MAAM;AACf,YAAI,GAAG,MAAM,EAAE;AACf,cAAM,IAAI,uBAAsB;MAClC;AACA,UAAI,OAAO,UAAU;AACnB,YAAI,MAAM,SAAS,QAAQ,MAAM,EAAE;AACnC,eAAO,MAAM,MAAM,QAAQ;MAC7B;AACA,YAAM,QAAQ,KAAK,OAAO,CAAC,QAAQ,IAAI,WAAW,MAAS;AAC3D,UAAI,MAAM,SAAS;AACjB,gBAAQ,IACN,SACA,MAAM,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;AAElC,UAAI,WAAW,MAAM,YAAY,SAAS,SAAS,EAAE,MAAM,OAAO;AAClE,UAAI,iBAAiB,IAAI,QAAQ,MAAM,KAAK,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AAC3F,cAAM,QAAQ,SAAS,SAAS,EAAE,OAAO,QAAQ,OAAO,GAAG,EAAE,QAAQ,eAAc,CAAE;AACrF,mBAAW,gBAAgB,QAAQ;AACnC,iBAAS,QAAQ,IAAI,mBAAmB,MAAM,EAAE;MAClD;AACA,UAAI,mBAAmB,QAAQ;AAC7B,mBAAW,gBAAgB,QAAQ;AACnC,iBAAS,QAAQ,IAAI,eAAe,cAAc;MACpD;AACA,UAAI,OAAO,QAAW;AACpB,mBAAW,gBAAgB,QAAQ;AACnC,iBAAS,QAAQ,IAAI,WAAW,EAAE;MACpC;AACA,UAAI,SAAS,QAAQ,MAAM,CAAC,GAAG,IAAI,QAAQ;AAC3C,aAAO,MAAM,QAAQ;IACvB;;AAGF,QAAM,UAAU,mBAAmB;IACjC,MAAM,QAAQ;IACd,WAAW,QAAO;IAClB;IACA;IACA;IACA;IACA;IACA,kBAAkB;IAClB,YAAY,QAAQ;IACpB;IACA,YAAY;MACV,YAAY,CAAC,MAAM,eAAc;AAC/B,cAAM,QAAQ,WAAW,MAAM,UAAU;AACzC,eAAO;UACL,IAAI,MAAM;UACV,QAAQ,MAAM;UACd,QAAQ,MAAM;UACd,IAAI,MAAM;UACV,SAAS,MAAM,MAAM,SAAS,QAAQ;;MAE1C;MACA,QAAQ,CAAC,YAAY,kBAAiB;AACpC,cAAM,QAAQ,OAAO,YAAY,aAAa;AAC9C,eAAO,EAAE,IAAI,MAAM,IAAI,QAAQ,MAAM,QAAQ,QAAQ,MAAM,QAAQ,IAAI,MAAM,GAAE;MACjF;MACA,UAAU,CAAC,cAAc,oBAAoB,SAAS,cAAc,eAAe;MACnF,QAAQ,CAAC,MAAM,iBAAgB;AAC7B,iBAAS,IAAI,EAAE,OAAO,YAAY;MACpC;MACA,SAAS,CAAC,MAAM,iBAAiB,SAAS,IAAI,EAAE,QAAQ,YAAY;MACpE,SAAS,CAAC,SAAQ;AAChB,cAAMM,WAAU,SAAS,IAAI;AAC7B,eAAO;UACL,UAAUA,SAAQ,SAAQ;UAC1B,aAAaA,SAAQ,YAAW,EAAG,IAAI,CAAC,EAAE,IAAI,QAAQ,YAAY,QAAQ,GAAE,OAAQ;YAClF;YACA,QAAQ;YACR;YACA;YACA;;MAEN;;IAEF,UAAU,QAAQ,aAAa,OAAO,CAAA;IACtC,GAAI,QAAQ,UACR;MACE,aAAa,CAAC,MAAc,WAAmB,cAC7C,QAAQ,YAAY,MAAM,WAAW,SAAS;QAElD,CAAA;IACJ,QAAQ;MACN,GAAG,iBAAiB,WAAW;MAC/B,GAAI,QAAQ,WAAW,mBAAmB,QAAQ,QAAQ,IAAI,CAAA;MAC9D,GAAI,QAAQ,QAAQ,OAAO,KAAK,CAAA;;;MAGhC,GAAI,QAAQ,UAAU,aAAa,QAAQ,SAAS,OAAO,IAAI,CAAA;MAC/D,GAAG,iBAAiB;QAClB,MAAM;QACN,YAAY,CAAC,cAAa;AACxB,qBAAW,WAAW,MAAM;QAC9B;OACD;MACD,GAAG,cAAc,QAAQ,MAAM,QAAQ,OAAO;;IAEhD,UAAU,QAAQ;GACnB;AAED,SAAO,WAAW,OAAO;AAC3B;AAEA,IAAM,kBAAkB,CAAC,aAAgC;AACvD,MAAI;AACF,aAAS,QAAQ,IAAI,+BAA+B,GAAG;AACvD,aAAS,QAAQ,OAAO,6BAA6B;AACrD,WAAO;EACT,QAAQ;AACN,WAAO,IAAI,SAAS,SAAS,MAAM,QAAQ;EAC7C;AACF;AAEA,IAAM,YAAY,CAAC,QAAgB,SACjC,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,SAAS,EAAE,gBAAgB,mBAAkB,EAAE,CAAE;AAEhG,IAAM,YAAY,CAAC,QAAgB,YACjC,UAAU,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,QAAO,EAAE,CAAE;AAErE,IAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAQrE,IAAM,mBAAmB,CAAC,cAA+C;EACvE,oBAAoB,MAClB,UAAU,KAAK;IACb,aAAa,SAAS,QAAO,EAAG,IAAI,CAAC,EAAE,YAAY,UAAS,OAAQ;MAClE,YAAY,eAAe,UAAU;MACrC;MACA;GACH;EACH,oBAAoB,CAAC,EAAE,MAAM,UAAS,MAAM;AAC1C,UAAM,QAA4B,CAAA;AAClC,UAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,SAAS,IAAI,IAAI,KAAK,cAAc;AAC9E,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,iBAAW,QAAQ,MAAM;AACvB,YAAI,OAAO,SAAS;AAAU,gBAAM,KAAK,CAAC,MAAM,SAAS,CAAC;iBACjD,SAAS,IAAI,KAAK,OAAO,KAAK,eAAe,UAAU;AAC9D,gBAAM,KAAK;YACT,KAAK;YACL,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY;WACvD;QACH;AAAO,iBAAO,UAAU,KAAK,8DAA8D;MAC7F;IACF,WAAW,SAAS,IAAI,GAAG;AACzB,iBAAW,CAAC,YAAY,MAAM,KAAK,OAAO,QAAQ,IAAI,GAAG;AACvD,YAAI,OAAO,WAAW;AACpB,iBAAO,UAAU,KAAK,iBAAiB,UAAU,mBAAmB;AACtE,cAAM,KAAK,CAAC,YAAY,MAAM,CAAC;MACjC;IACF,WAAW,SAAS,IAAI,KAAK,OAAO,KAAK,eAAe,UAAU;AAChE,YAAM,KAAK,CAAC,KAAK,YAAY,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY,SAAS,CAAC;IAC/F,OAAO;AACL,aAAO,UAAU,KAAK,2DAA2D;IACnF;AACA,eAAW,CAAC,YAAY,MAAM,KAAK,OAAO;AACxC,UAAI,CAAC,kBAAkB,KAAK,MAAM;AAChC,eAAO,UAAU,KAAK,iBAAiB,KAAK,UAAU,MAAM,CAAC,EAAE;AACjE,eAAS,IAAI,YAAY,MAAM;IACjC;AACA,WAAO,UAAU,KAAK,EAAE,QAAQ,MAAM,OAAM,CAAE;EAChD;EACA,uBAAuB,CAAC,EAAE,IAAG,MAAM;AACjC,UAAM,aAAa,IAAI,aAAa,IAAI,YAAY;AACpD,QAAI,eAAe;AAAM,eAAS,MAAK;;AAClC,eAAS,OAAO,UAAU;AAC/B,WAAO,UAAU,KAAK,EAAE,QAAQ,KAAI,CAAE;EACxC;;AAGF,IAAM,eAAe,CACnB,SACA,aACiB;EACjB,uBAAuB,MAAK;AAC1B,UAAM,OAAwB;MAC5B,SAAS,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,MAAM,OAAO,EAAE,MAAM,GAAG,OAAM,EAAG;;AAEhF,WAAO,UAAU,KAAK,IAAI;EAC5B;EACA,8BAA8B,CAAC,EAAE,QAAQ,MAAM,UAAS,MAAM;AAC5D,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,QAAQ,IAAI;AACf,aAAO,UAAU,KAAK,mBAAmB,IAAI,+BAA+B;AAC9E,UAAM,YAAY,SAAS,IAAI,IAAK,OAA8B,CAAA;AAClE,WAAO,UAAU,KAAK,EAAE,QAAQ,MAAM,OAAO,QAAQ,YAAY,MAAM,WAAW,SAAS,EAAC,CAAE;EAChG;;;;ACn2BK,IAAMG,YAA4B,KAAK,MAAM,+qgBAA+qgB;AAI5tgB,IAAM,eAAe,CAAC,qBAAoB,gBAAe,WAAU,qBAAoB,qBAAoB,iBAAiB;AAC5H,IAAM,wBAAwB,CAAC,qBAAoB,gBAAe,WAAU,qBAAoB,qBAAoB,iBAAiB;;;ACe5I,IAAM,MAAM,CACV,IACA,OACA,MACA,OACA,KACA,QACA,KACA,SACmB,EAAE,IAAI,OAAO,MAAM,OAAO,KAAK,QAAQ,KAAK,IAAI;AAE9D,IAAM,iBAA2C;AAAA,EACtD;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,gBAAgB,iBAAiB,aAAa,MAAM,SAAS,aAAa,QAAQ,QAAQ;AAAA,EAC9F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,aAAa,mBAAmB,UAAU,MAAM,SAAS,iBAAiB,SAAS,SAAS;AAAA,EAChG;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,cAAc,qBAAqB,WAAW,MAAM,SAAS,iBAAiB,QAAQ,MAAM;AAAA,EAChG;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,YAAY,sBAAsB,SAAS,MAAM,SAAS,cAAc,QAAQ,SAAS;AAAA,EAC7F,IAAI,cAAc,oBAAoB,WAAW,MAAM,SAAS,eAAe,SAAS,QAAQ;AAAA,EAChG;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,cAAc,iBAAiB,WAAW,MAAM,SAAS,mBAAmB,SAAS,OAAO;AAAA,EAChG;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,cAAc,kBAAkB,WAAW,MAAM,SAAS,gBAAgB,SAAS,OAAO;AAAA,EAC9F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,YAAY,kBAAkB,SAAS,MAAM,SAAS,kBAAkB,SAAS,QAAQ;AAAA,EAC7F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,cAAc,eAAe,WAAW,MAAM,SAAS,iBAAiB,SAAS,QAAQ;AAAA,EAC7F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,YAAY,gBAAgB,SAAS,MAAM,SAAS,eAAe,SAAS,QAAQ;AAAA,EACxF;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,YAAY,mBAAmB,UAAU,MAAM,SAAS,iBAAiB,SAAS,QAAQ;AAAA,EAC9F,IAAI,cAAc,gBAAgB,WAAW,MAAM,SAAS,iBAAiB,SAAS,QAAQ;AAAA,EAC9F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,IAAI,cAAc,eAAe,WAAW,MAAM,SAAS,eAAe,SAAS,SAAS;AAAA,EAC5F;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,uBAAuB,eAAe;AAAA,EACjD,CAAC,MAAM,EAAE,OAAO;AAClB;AAEO,IAAM,cAAgD;AAAA,EAC3D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;;;AC9gBA,IAAM,kBAAkB;AAEjB,IAAM,YAAY,CAAC,UACxB,MACG,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,KAAK;AAEV,IAAM,YAAY,CAAC,UACjB,SAAS,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC,EACrC,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AACtB,IAAM,gBAAgB,CAAC,UAAsC;AAC3D,MAAI;AACF,WAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE;AAAA,MAC/C,WAAW,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,CAAC;AAAA,IACxD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,IAAM,gBAAgB,CAACC,SAC5B,OAAO,YAAY,SAASA,KAAI,EAAE,IAAI,EAAE,CAAC;AAE3C,IAAM,gBAAgB,CAAC,QAAwB,OAAO,YAAY,aAAa,GAAG,IAAI,EAAE,CAAC;AAEzF,IAAM,UAAU,CAACA,UAA+B;AAAA,EAC9C,SAAS,cAAcA,IAAG;AAAA,EAC1B,MAAM;AAAA,EACN,OAAOA,KAAI;AAAA,EACX,MAAMA,KAAI;AAAA,EACV,OAAOA,KAAI;AAAA,EACX,KAAKA,KAAI;AAAA,EACT,QAAQA,KAAI;AAAA,EACZ,KAAKA,KAAI;AAAA,EACT,KAAKA,KAAI;AACX;AAGA,IAAM,SAAS,CAAC,MAAc,SAAyB;AACrD,QAAM,QAAQ,YAAY,gBAAgB,IAAI,IAAI,IAAI,IAAI,CAAC;AAC3D,MAAI,IAAI;AACR,aAAW,QAAQ,MAAO,MAAK,IAAI,KAAK,KAAK,WAAW,CAAC,KAAK;AAC9D,UAAQ,IAAI,OAAO;AACrB;AAEA,IAAM,QAAQ,CAAC,UAAkB,KAAK,MAAM,QAAQ,GAAG,IAAI;AAKpD,IAAM,aAAa,CAAC,OAAeA,SAA8B;AACtE,QAAM,UAAwB;AAAA,IAC5B,GAAG;AAAA,IACH,GAAGA,KAAI;AAAA,IACP,GAAGA,KAAI;AAAA,IACP,GAAGA,KAAI;AAAA,IACP,GAAGA,KAAI;AAAA,IACP,GAAG,MAAMA,KAAI,MAAM,OAAO,OAAO,KAAK,CAAC;AAAA,IACvC,GAAG,MAAMA,KAAI,MAAM,OAAO,OAAO,KAAK,CAAC;AAAA,EACzC;AACA,SAAO;AAAA,IACL,SAAS,KAAK,UAAU,KAAK,UAAU,OAAO,CAAC,CAAC;AAAA,IAChD,MAAM;AAAA,IACN;AAAA,IACA,MAAMA,KAAI;AAAA,IACV,OAAOA,KAAI;AAAA,IACX,KAAKA,KAAI;AAAA,IACT,QAAQA,KAAI;AAAA,IACZ,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,EACf;AACF;AAEA,IAAM,cAAc,CAACA,UAA+B;AAAA,EAClD,SAAS,cAAcA,KAAI,GAAG;AAAA,EAC9B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAMA,KAAI;AAAA,EACV,OAAOA,KAAI;AAAA,EACX,KAAKA,KAAI;AAAA,EACT,QAAQA,KAAI;AAAA,EACZ,KAAKA,KAAI;AAAA,EACT,KAAKA,KAAI;AACX;AAGO,IAAM,YAAY,CAAC,SAAiB,SAAsD;AAC/F,MAAI,QAAQ,WAAW,IAAI,GAAG;AAC5B,UAAM,UAAU,cAAc,QAAQ,MAAM,CAAC,CAAC;AAC9C,QAAI,YAAY,OAAW,QAAO;AAClC,QAAI;AACF,YAAM,IAAI,KAAK,MAAM,OAAO;AAC5B,UACE,OAAO,EAAE,MAAM,YACf,OAAO,EAAE,MAAM,YACf,OAAO,EAAE,MAAM,YACf,OAAO,EAAE,MAAM,YACf,OAAO,EAAE,MAAM,YACf,OAAO,EAAE,MAAM,UACf;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL;AAAA,QACA,MAAM;AAAA,QACN,OAAO,EAAE;AAAA,QACT,MAAM,EAAE;AAAA,QACR,OAAO,EAAE;AAAA,QACT,KAAK,EAAE;AAAA,QACP,QAAQ,OAAO,EAAE,MAAM,WAAW,EAAE,IAAI;AAAA,QACxC,KAAK,EAAE;AAAA,QACP,KAAK,EAAE;AAAA,MACT;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,aAAWA,QAAO,MAAM;AACtB,QAAI,cAAcA,IAAG,MAAM,QAAS,QAAO,QAAQA,IAAG;AACtD,QAAI,cAAcA,KAAI,GAAG,MAAM,QAAS,QAAO,YAAYA,IAAG;AAAA,EAChE;AACA,SAAO;AACT;AAEA,IAAM,gBAAgB;AAGtB,IAAM,cAAc,CAAC,UAAiE;AACpF,QAAM,QAAQ,cAAc,KAAK,MAAM,KAAK,CAAC;AAC7C,SAAO,QACH,EAAE,QAAQ,MAAM,CAAC,GAAa,OAAQ,MAAM,CAAC,EAAa,KAAK,EAAE,IACjE,EAAE,QAAQ,QAAW,OAAO,MAAM,KAAK,EAAE;AAC/C;AAEO,IAAM,oBAAoB,CAAC,UAAqC;AACrE,QAAM,MAA0B,CAAC;AACjC,MAAI,MAAM,SAAS,kBAAkB;AACnC,UAAM,EAAE,QAAQ,MAAM,IAAI,YAAY,MAAM,KAAK;AACjD,QAAI,OAAQ,KAAI,KAAK,EAAE,WAAW,QAAQ,YAAY,QAAQ,OAAO,CAAC,eAAe,EAAE,CAAC;AACxF,QAAI,KAAK,EAAE,WAAW,OAAO,YAAY,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAAA,EACpE,OAAO;AACL,QAAI,KAAK,EAAE,WAAW,MAAM,KAAK,YAAY,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC;AAAA,EAClF;AACA,MAAI,KAAK,EAAE,WAAW,MAAM,MAAM,YAAY,MAAM,MAAM,OAAO,CAAC,YAAY,WAAW,EAAE,CAAC;AAC5F,MAAI,MAAM,QAAQ;AAChB,QAAI,KAAK;AAAA,MACP,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,MAClB,OAAO,CAAC,+BAA+B,WAAW;AAAA,IACpD,CAAC;AAAA,EACH;AACA,MAAI,KAAK;AAAA,IACP,WAAW,YAAY,MAAM,KAAK,KAAK,MAAM;AAAA,IAC7C,YAAY,MAAM;AAAA,IAClB,OAAO,CAAC,+BAA+B,WAAW;AAAA,EACpD,CAAC;AACD,MAAI,KAAK,EAAE,WAAW,iBAAiB,YAAY,MAAM,OAAO,CAAC,WAAW,WAAW,EAAE,CAAC;AAC1F,MAAI,MAAM,SAAS,kBAAkB;AACnC,QAAI,KAAK,EAAE,WAAW,MAAM,KAAK,YAAY,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC;AAAA,EAClF;AACA,SAAO;AACT;AAEO,IAAM,mBAAmB,CAAC,UAC/B,MAAM,SAAS,mBACX,GAAG,MAAM,KAAK,KAAK,MAAM,IAAI,KAAK,MAAM,KAAK,IAAI,MAAM,GAAG,UAC1D,GAAG,MAAM,IAAI,KAAK,MAAM,KAAK,IAAI,MAAM,GAAG;AAEzC,IAAM,WAAW,CAAC,OAAc,WAAW,UAAU;AAC1D,QAAM,OAAO,MAAM,SAAS,mBAAmB,SAAU;AACzD,SAAO;AAAA,IACL,UAAU,EAAE,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI;AAAA,IAC3C,GAAI,WACA,EAAE,eAAe,MAAM,SAAS,mBAAmB,YAAY,cAAc,IAC7E,CAAC;AAAA,IACL,UAAU;AAAA,MACR,WAAW,EAAE,KAAK,MAAM,MAAM,MAAM,IAAI,GAAG,KAAK,MAAM,MAAM,MAAM,IAAI,EAAE;AAAA,MACxE,WAAW,EAAE,KAAK,MAAM,MAAM,MAAM,IAAI,GAAG,KAAK,MAAM,MAAM,MAAM,IAAI,EAAE;AAAA,IAC1E;AAAA,EACF;AACF;AAEA,IAAM,aAAa,CAAC,UAClB,MAAM,SAAS,mBAAmB,CAAC,gBAAgB,IAAI,CAAC,aAAa;AAGhE,IAAM,cAAc,CAAC,WAA2C;AAAA,EACrE,oBAAoB,kBAAkB,KAAK;AAAA,EAC3C,aACE,MAAM,SAAS,mBACX,gCAAgC,MAAM,KAAK,mCAAmC,MAAM,IAAI,iCAAiC,MAAM,KAAK,qCAAqC,MAAM,GAAG,mDAClL,0BAA0B,MAAM,IAAI,iCAAiC,MAAM,KAAK,qCAAqC,MAAM,GAAG;AAAA,EACpI,mBAAmB,iBAAiB,KAAK;AAAA,EACzC,UAAU,SAAS,KAAK;AAAA,EACxB,MAAM,MAAM,SAAS,mBAAmB,MAAM,QAAQ,MAAM;AAAA,EAC5D,UAAU,MAAM;AAAA,EAChB,WAAW,MAAM;AAAA,EACjB,OAAO,WAAW,KAAK;AAAA,EACvB,KAAK,8BAA8B,mBAAmB,iBAAiB,KAAK,CAAC,CAAC;AAAA,EAC9E,YAAY;AAAA,EACZ,UAAU,MAAM;AAClB;AAGA,IAAM,gBAAwC;AAAA,EAC5C,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,WAAW;AAAA,EACX,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,UAAU;AACZ;AAGO,IAAM,aAAa,CACxB,QACA,QACA,aAC4B;AAC5B,QAAM,aAAa,UAAU,IAC1B,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AACjB,MAAI,UAAU,WAAW,GAAG;AAC1B,QAAI,aAAa,MAAO,QAAO;AAC/B,WAAO,OAAO,YAAY,SAAS,IAAI,CAAC,QAAQ,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;AAAA,EACrE;AACA,MAAI,UAAU,SAAS,GAAG,EAAG,QAAO;AACpC,QAAM,OAAO,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC,CAAC;AAC3F,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,GAAG,CAAC,CAAC;AACnF;AAGO,IAAM,gBAAgB,CAAC,YAC3B,UAAU,IACR,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,KAAK,MAAM,OAAO,EAAE,KAAK,cAAc;AAE1D,IAAM,YAAY,CAAC,UAAiB,GAAG,MAAM,IAAI,KAAK,MAAM,KAAK;AAE1D,IAAM,aAAa,CAAC,OAAc,UAA8B;AACrE,QAAM,OAAO,MAAM,SAAS,mBAAmB,MAAM,QAAQ,MAAM;AACnE,QAAM,SAAS,UAAU,KAAK;AAC9B,QAAM,cAAc,GAAG,IAAI,KAAK,MAAM;AACtC,QAAM,UAAU,KAAK,IAAI,MAAM,KAAK,EAAE,QAAQ,KAAK,MAAM;AACzD,QAAM,QAA6C,CAAC;AACpD,MAAI,SAAS;AACb,aAAW,SAAS,CAAC,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK,GAAG;AAC1D,UAAM,KAAK,EAAE,QAAQ,MAAM,CAAC;AAC5B,cAAU,MAAM,SAAS;AAAA,EAC3B;AACA,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,CAAC,EAAE,QAAQ,SAAS,QAAQ,EAAE,CAAC;AAAA,IACnD,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,uBAAuB;AAAA,MACrB,WAAW;AAAA,MACX,8BAA8B,CAAC,EAAE,QAAQ,SAAS,QAAQ,EAAE,CAAC;AAAA,MAC7D,gBAAgB;AAAA,IAClB;AAAA,IACA;AAAA,IACA,OAAO,MAAM,SAAS,mBAAmB,CAAC,WAAW,SAAS,IAAI,CAAC,eAAe,SAAS;AAAA,EAC7F;AACF;AAEA,IAAM,SAAS,CAAC,UAAkB,UAAU,KAAK,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AAC5E,IAAM,UAAU,oBAAI,IAAI,CAAC,OAAO,MAAM,UAAU,QAAQ,CAAC;AAGzD,IAAM,cAAc,CAAC,OAAiB,aAAgC;AACpE,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,SAAS,OAAO;AACzB,UAAM,KAAK,SAAS,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,WAAW,KAAK,CAAC;AAC3E,QAAI,KAAK,EAAG,QAAO;AACnB,SAAK,IAAI,EAAE;AAAA,EACb;AACA,SAAO;AACT;AAEA,IAAM,cAAc,CAACA,SACnB,OAAO,GAAGA,KAAI,KAAK,IAAIA,KAAI,IAAI,IAAIA,KAAI,KAAK,IAAI,YAAYA,KAAI,KAAK,KAAK,EAAE,IAAIA,KAAI,GAAG,EAAE;AAMpF,IAAM,oBAAoB,CAC/B,OACA,SACsD;AACtD,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,kCAAkC,EAAE;AACzE,QAAM,QAAQ,cAAc,KAAK,OAAO;AACxC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,MAAM,CAAC;AACtB,QAAM,OAAQ,MAAM,CAAC,EAAa,QAAQ,MAAM,GAAG,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/E,QAAM,WAAW,UAAU,IAAI;AAE/B,QAAM,aAAa,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM;AACzE,aAAWA,QAAO,YAAY;AAC5B,UAAM,OAAO,UAAUA,KAAI,IAAI;AAC/B,UAAM,WAAW;AAAA,MACf,GAAG,IAAI,IAAIA,KAAI,MAAM,YAAY,CAAC,IAAIA,KAAI,GAAG;AAAA,MAC7C,GAAG,IAAI,IAAIA,KAAI,MAAM,YAAY,CAAC;AAAA,MAClC,GAAG,IAAI,IAAIA,KAAI,GAAG;AAAA,MAClB;AAAA,IACF;AACA,eAAW,UAAU,UAAU;AAC7B,UAAI,CAAC,SAAS,SAAS,IAAI,MAAM,EAAE,EAAG;AACtC,YAAM,aAAa,SAAS,MAAM,GAAG,SAAS,SAAS,OAAO,MAAM,EAAE,KAAK;AAC3E,UAAI,CAAC,WAAY;AAEjB,YAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,YAAM,cAAc,MAAM,MAAM,GAAG,WAAW,MAAM,GAAG,EAAE,MAAM;AAC/D,YAAM,SAAS,YAAY,KAAK,GAAG,EAAE,QAAQ,WAAW,EAAE;AAC1D,aAAO,EAAE,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,KAAAA,KAAI;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,eAAe,CAAC,OAAe,SAA4C;AACtF,QAAM,SAAS,OAAO,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAC1D,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,QAAM,MAAe,CAAC;AACtB,QAAM,QAAQ,kBAAkB,OAAO,IAAI;AAC3C,MAAI,OAAO;AACT,UAAM,QAAQ,KAAK;AAAA,MACjB,CAACA,SACC,UAAUA,KAAI,KAAK,MAAM,UAAU,MAAM,KAAK,KAC9C,UAAUA,KAAI,IAAI,MAAM,UAAU,MAAM,IAAI,IAAI;AAAA,IACpD;AACA,QAAI,KAAK,QAAQ,QAAQ,KAAK,IAAI,WAAW,MAAM,OAAO,MAAM,GAAG,CAAC;AAAA,EACtE;AACA,aAAWA,QAAO,MAAM;AACtB,QAAI,IAAI,UAAU,gBAAiB;AACnC,QAAI,IAAI,KAAK,CAAC,MAAM,EAAE,YAAY,cAAcA,IAAG,CAAC,EAAG;AACvD,QAAI,YAAY,QAAQ,YAAYA,IAAG,CAAC,EAAG,KAAI,KAAK,QAAQA,IAAG,CAAC;AAAA,EAClE;AACA,SAAO;AACT;AAMO,IAAM,UAAU,CAAC,SAAiB,SAAsD;AAC7F,QAAM,IAAI,UAAU,OAAO;AAC3B,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,QAAQ,kBAAkB,SAAS,IAAI;AAC7C,MAAI,OAAO;AACT,UAAM,QAAQ,KAAK;AAAA,MACjB,CAACA,SACC,UAAUA,KAAI,KAAK,MAAM,UAAU,MAAM,KAAK,KAC9C,UAAUA,KAAI,IAAI,MAAM,UAAU,MAAM,IAAI,IAAI;AAAA,IACpD;AACA,WAAO,QAAQ,QAAQ,KAAK,IAAI,WAAW,MAAM,OAAO,MAAM,GAAG;AAAA,EACnE;AACA,QAAM,SAAS,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAC5D,MAAI,OAAO,WAAW,KAAK,UAAU,KAAK,OAAO,CAAC,CAAW,GAAG;AAC9D,UAAMA,OAAM,KAAK,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAO,CAAC,CAAC;AAChD,WAAOA,OAAM,YAAYA,IAAG,IAAI;AAAA,EAClC;AACA,MAAI,CAAC,KAAK,KAAK,CAAC,GAAG;AACjB,UAAMA,OAAM,KAAK,KAAK,CAAC,MAAM;AAC3B,YAAM,OAAO,OAAO,EAAE,IAAI;AAC1B,aACE,OAAO,UAAU,KAAK,UACtB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KACpC,OAAO,MAAM,KAAK,MAAM,EAAE,MAAM,CAAC,MAAM,MAAM,EAAE,MAAM,YAAY,CAAC;AAAA,IAEtE,CAAC;AACD,WAAOA,OAAM,YAAYA,IAAG,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAGO,IAAM,YAAY,CAAC,OAAe,SACvC,QAAQ,OAAO,IAAI,KAAK,aAAa,OAAO,IAAI,EAAE,CAAC;;;ACparD,IAAM,QAAQ,CAAC,UAAmB,KAAK,UAAU,KAAK,EAAE,QAAQ,MAAM,SAAS;AAExE,IAAM,iBAAiB,CAC5B,YACW;AAAA;AAAA,eAEE,MAAM,QAAQ,IAAI,CAAC;AAAA,cACpB,MAAM,QAAQ,GAAG,CAAC;AAAA,sBACV,QAAQ,aAAa,SAAS,OAAO;AAAA,mBACxC,MAAM,QAAQ,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACVnC,IAAM,mBAA6B,EAAE,MAAM,CAAC,GAAG,WAAW,KAAK;AAE/D,IAAM,kBAAN,MAAsB;AAAA,EAK3B,YACE,QACA,WACiB,MACjB;AADiB;AAEjB,SAAK,SAAS,IAAI,WAAW,QAAQ,WAAW,WAAW;AAC3D,SAAK,WAAW,IAAI,WAAW,QAAQ,WAAW,UAAU;AAC5D,SAAK,aAAa;AAAA,EACpB;AAAA,EALmB;AAAA;AAAA,EANV;AAAA,EACA;AAAA,EAYT,eAAqB;AACnB,QAAI,CAAC,KAAK,SAAS,IAAI,UAAU,GAAG;AAClC,WAAK,SAAS,OAAO,YAAY,EAAE,GAAG,kBAAkB,GAAG,KAAK,KAAK,SAAS,CAAC;AAAA,IACjF;AAAA,EACF;AAAA,EAEA,UAAoB;AAClB,WAAO,KAAK,SAAS,IAAI,UAAU,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAO,OAAoC;AACzC,UAAM,OAAO,EAAE,GAAG,KAAK,QAAQ,GAAG,GAAG,MAAM;AAC3C,SAAK,SAAS,OAAO,YAAY,IAAI;AACrC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAA0B;AACxB,UAAM,SAAS,KAAK,OAAO,KAAK,EAAE,OAAO,SAAS,CAAC,EAAE,IAAI,CAACC,SAAQA,KAAI,KAAK;AAC3E,UAAM,MAAM,IAAI,IAAI,OAAO,IAAI,CAACA,SAAQA,KAAI,EAAE,CAAC;AAC/C,UAAM,OAAO,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK,KAAK,SAAS;AAC9D,WAAO,CAAC,GAAG,QAAQ,GAAG,KAAK,OAAO,CAACA,SAAQ,CAAC,IAAI,IAAIA,KAAI,EAAE,CAAC,CAAC;AAAA,EAC9D;AAAA,EAEA,cAAc,MAA6B;AACzC,eAAW,EAAE,GAAG,KAAK,KAAK,OAAO,KAAK,EAAG,MAAK,OAAO,OAAO,EAAE;AAC9D,eAAWA,QAAO,KAAM,MAAK,OAAO,OAAOA,KAAI,IAAIA,IAAG;AAAA,EACxD;AACF;;;AC9BO,IAAM,gBAAwC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,eAA8C;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,YAAwC,CAAC,KAAK,KAAK,KAAK,GAAG;AAyBjE,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAYA,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,iBAAiB,oBAAI,IAAI;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,mBAAmB;AAEzB,IAAM,oBAAoB;AAC1B,IAAM,0BAA0B;AAEhC,IAAMC,YAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,iBAAiB,CAAC,OAAgB,UAAsC;AAC5E,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,IAAI;AAAA,MACR,qBAAqB,KAAK,oBAAoB,KAAK,UAAU,KAAK,CAAC;AAAA,IACrE;AAAA,EACF;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,UAAU,UAAU;AAC7B;AAGO,IAAM,uBAAuB,CAAC,SAAmC;AACtE,MAAI,CAACA,UAAS,IAAI,EAAG,OAAM,IAAI,uBAAuB,gCAAgC;AACtF,aAAW,OAAO,OAAO,KAAK,IAAI,GAAG;AACnC,QAAI,CAAC,UAAU,IAAI,GAAG,GAAG;AACvB,YAAM,IAAI;AAAA,QACR,gDAAgD,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,KAAK;AACrB,MAAI,YAAY,UAAa,YAAY,MAAM;AAC7C,UAAM,IAAI,uBAAuB,sCAAsC;AAAA,EACzE;AACA,MAAI,CAACA,UAAS,OAAO,GAAG;AACtB,UAAM,IAAI;AAAA,MACR,+EAA+E,KAAK,UAAU,OAAO,CAAC;AAAA,IACxG;AAAA,EACF;AACA,aAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACtC,QAAI,CAAC,eAAe,IAAI,GAAG,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR,gDAAgD,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,QAAQ,gBAAgB,CAAC;AAC1C,MAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,KAAK,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AACjF,UAAM,IAAI;AAAA,MACR,2DAA2D,KAAK,UAAU,QAAQ,CAAC;AAAA,IACrF;AAAA,EACF;AAIA,MAAK,SAAsB,SAAS,mBAAmB;AACrD,UAAM,IAAI;AAAA,MACR,4EAA4E,iBAAiB;AAAA,IAC/F;AAAA,EACF;AACA,QAAM,WAAY,SAAsB,UAAU,CAAC,SAAS,KAAK,SAAS,uBAAuB;AACjG,MAAI,aAAa,IAAI;AACnB,UAAM,IAAI;AAAA,MACR,2CAA2C,QAAQ,sCAAsC,uBAAuB;AAAA,IAClH;AAAA,EACF;AACA,QAAM,eAAgB,SAAsB,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,OAAO,OAAO;AACrF,MAAI,aAAa,WAAW,GAAG;AAC7B,UAAM,IAAI,uBAAuB,6CAA6C;AAAA,EAChF;AACA,QAAM,SAAS,KAAK;AACpB,MAAI,WAAW,UAAa,WAAW,QAAQ,OAAO,WAAW,WAAW;AAC1E,UAAM,IAAI;AAAA,MACR,oDAAoD,KAAK,UAAU,MAAM,CAAC;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,QAAsB;AAAA,IAC1B,YAAY,eAAe,QAAQ,YAAY,qBAAqB,GAAG,YAAY;AAAA,IACnF;AAAA,IACA,UAAU,eAAe,QAAQ,UAAU,kBAAkB;AAAA,IAC7D,oBAAoB,eAAe,QAAQ,oBAAoB,6BAA6B;AAAA,IAC5F,YAAY,eAAe,QAAQ,YAAY,qBAAqB;AAAA,EACtE;AACA,QAAM,SAAS;AAAA,IACb,GAAG,MAAM;AAAA,IACT,MAAM,YAAY;AAAA,IAClB,MAAM,sBAAsB;AAAA,IAC5B,MAAM,cAAc;AAAA,EACtB,EAAE,KAAK,EAAE,EAAE;AACX,MAAI,SAAS,kBAAkB;AAC7B,UAAM,IAAI;AAAA,MACR,0DAA0D,gBAAgB;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,SAAS,MAAM,cAAc;AACnC,MAAI,WAAW,QAAQ,WAAW,QAAQ,WAAW,MAAM;AACzD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,SAAS,OAAO,gBAAgB,WAAW,KAAK;AAC3D;AAMA,IAAM,gBAAwC;AAAA,EAC5C,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,WAAW;AAAA,EACX,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AACR;AACA,IAAM,eAAe,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,MAAM,MAAM,IAAI,CAAC;AAGzE,IAAM,cAAsC;AAAA,EAC1C,KAAK;AAAA,EACL,WAAW;AAAA,EACX,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAEA,IAAM,cACJ;AACF,IAAM,YACJ;AACF,IAAMC,iBAAgB;AAItB,IAAM,WAAW,CAAC,SAChB,KAAK,eAAe,MAAM,IAAI,KAAK,KAAK,KAAK,GAAG,KAAK,UAAU,IAAI,KAAK,KAAK;AAE/E,IAAM,YAAY,CAAC,YAAgC,WAAyB;AAAA,EAC1E,YAAY,aAAa,cAAc,KAAK,YAAY,CAAC,KAAK;AAAA,EAC9D,OAAO,MAAM,YAAY;AAC3B;AAGA,IAAM,YAAY,CAAC,SAA6D;AAC9E,QAAM,QAAQ,YAAY,KAAK,IAAI;AACnC,MAAI,CAAC,SAAS,MAAM,UAAU,EAAG,QAAO,EAAE,QAAQ,KAAK,KAAK,GAAG,MAAM,OAAU;AAC/E,SAAO;AAAA,IACL,QAAQ,KAAK,MAAM,GAAG,MAAM,KAAK,EAAE,KAAK;AAAA,IACxC,MAAM,UAAU,MAAM,CAAC,GAAG,MAAM,CAAC,CAAW;AAAA,EAC9C;AACF;AAGO,IAAM,YAAY,CAAC,WACxB,UAAU,MAAM,EACb,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,cAAc,IAAI,KAAK,MAAM,YAAY,CAAC,EACzD,KAAK,GAAG;AAGb,IAAM,oBAAoB,CAAC,WACzB,OACG,QAAQ,SAAS,GAAG,EACpB,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAI,CAAC,SAAS;AACb,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,aAAa,IAAI,KAAK,EAAG,QAAO,MAAM,YAAY;AACtD,SAAO,cAAc,KAAK,KAAK;AACjC,CAAC,EACA,KAAK,GAAG;AAEb,IAAM,YAAY,CAAC,UAAkD;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,MAAM,KAAK,EAAE,YAAY;AACvC,MAAI,YAAY,KAAK,EAAG,QAAO;AAC/B,QAAM,SAAS,OAAO,QAAQ,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,YAAY,MAAM,KAAK;AAC1F,SAAO,SAAS,CAAC,KAAK;AACxB;AAsBA,IAAM,WAAW,CAAC,MAAgC,MAAc,UAC9D,KAAK;AAAA,EACH,CAACC,SACC,UAAUA,KAAI,IAAI,MAAM,UAAU,IAAI,MAAM,UAAU,UAAaA,KAAI,UAAU;AACrF;AAEF,IAAM,UAAU,CACd,OACA,SACwD;AACxD,QAAM,CAAC,QAAQ,IAAI,GAAG,IAAI,IAAI,MAAM;AACpC,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI,WAAW,MAAM;AACrB,MAAI,QAAQ,UAAU,MAAM,kBAAkB;AAC9C,MAAI,MAAM,MAAM,YAAY,MAAM,GAAG,CAAC;AACtC,MAAI,aAA8B,CAAC;AAEnC,MAAI,YAAY,KAAK;AAEnB,UAAM,SAAS,KAAK,KAAK,GAAG,EAAE,KAAK;AACnC,QAAI,QAAQ;AACV,YAAM,OAAO,UAAU,KAAK,MAAM;AAClC,UAAI,KAAM,QAAO,UAAU,KAAK,CAAC,GAAG,KAAK,CAAC,CAAW;AAAA,IACvD;AAAA,EACF,OAAO;AAEL,UAAM,SAAS,MAAM,aAAa,KAAK,IAAI;AAC3C,UAAM,SAAS,kBAAkB,QAAQ,IAAI;AAC7C,QAAI,QAAQ;AACV,mBAAa,OAAO;AACpB,iBAAW,OAAO,IAAI;AACtB,cAAQ,OAAO,IAAI;AACnB,YAAM,WAAW,8DAA8D,KAAK,MAAM;AAC1F,YAAM,WAAW,CAAC;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,QAAQ,UAAU,UAAU;AAClC,QAAM,SAAS,MAAM;AACrB,SAAO,QAAQ,MAAM;AACrB,QAAM,WAAWD,eAAc,KAAK,MAAM;AAE1C,MAAI,SAAU,cAAa,SAAS,MAAM,UAAU,KAAK;AACzD,MAAI,iBAAuC;AAC3C,MAAI,cAAiC;AACrC,MAAI,WAAW,WAAW,KAAK,KAAK;AAElC,iBAAa,KAAK,OAAO,CAACC,SAAQA,KAAI,QAAQ,GAAG;AACjD,QAAI,WAAW,SAAS,GAAG;AACzB,uBAAiB;AACjB,UAAI,UAAU,UAAa,WAAW,CAAC,GAAG,UAAU,MAAO,eAAc;AAAA,IAC3E;AAAA,EACF;AACA,MAAI,WAAW,WAAW,KAAK,CAAC,UAAU;AACxC,WAAO,EAAE,YAAY,EAAE,QAAQ,MAAM,WAAW,CAAC,CAAC,SAAS,EAAE;AAAA,EAC/D;AAEA,QAAM,SAAS,SAAS,CAAC;AACzB,QAAM,MAAM,UAAU,MAAM;AAC5B,QAAM,QAAQ,WAAW,KAAK,CAACA,SAAQ,UAAUA,KAAI,KAAK,MAAM,GAAG;AACnE,QAAM,OACJ,SACA,WAAW,KAAK,CAACA,SAAQ,QAAQ,UAAaA,KAAI,QAAQ,GAAG,KAC5D,WAAW,CAAC;AACf,QAAM,YAAY,QAAQ,MAAM,QAAQ,kBAAkB,MAAM;AAChE,QAAM,aAAaD,eAAc,KAAK,SAAS;AAC/C,SAAO;AAAA,IACL,UAAU;AAAA,MACR,KAAK;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,OAAO,aAAc,WAAW,CAAC,IAAe;AAAA,MAChD;AAAA,MACA,UAAU,CAAC,CAAC;AAAA,MACZ,QAAQ,QAAQ,SAAY,aAAa,QAAQ,KAAK,MAAM,cAAc;AAAA,MAC1E,UAAU;AAAA,MACV,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAMA,IAAM,MAAM,CAAC,OAAe,OAAO,eAAuB;AACxD,MAAI,OAAO,SAAS;AACpB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAQ,MAAM,WAAW,CAAC;AAC1B,WAAO,KAAK,KAAK,MAAM,QAAU,MAAM;AAAA,EACzC;AACA,SAAO;AACT;AAEA,IAAM,WAAW,CAACC,MAAoB,WACpC,OAAQ,IAAI,GAAGA,KAAI,EAAE,IAAI,UAAU,MAAM,CAAC,EAAE,IAAI,OAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAGrE,IAAM,aAAa,CAAC,SAAyB;AAClD,QAAM,MAAM,CAAC,YAAY,UAAY,YAAY,UAAU,EACxD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EACrD,KAAK,EAAE;AACV,SAAO,GAAG,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI,IAAI,MAAM,IAAI,EAAE,CAAC;AAChH;AAYA,IAAM,YAAY,CAChBC,OACA,eACA,mBACA,QAAoD,CAAC,OACtC;AAAA,EACf,eAAe,EAAE,MAAAA,OAAM,cAAc,KAAK;AAAA,EAC1C;AAAA,EACA;AAAA,EACA,GAAI,MAAM,WAAW,EAAE,UAAU,KAAc,IAAI,CAAC;AAAA,EACpD,GAAI,MAAM,WAAW,EAAE,UAAU,KAAc,IAAI,CAAC;AACtD;AAUA,IAAM,UAAU,CAAoC,UAClD,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE;AAAA,IACpB,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,UAAa,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW;AAAA,EAClF;AACF;AAEF,IAAM,OAAO,CAAC,WAAqB,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAG/C,IAAM,kBAAkB,CAC7B,SACA,MACA,UAA6C,CAAC,MACxB;AACtB,QAAM,EAAE,SAAS,OAAO,eAAe,IAAI;AAC3C,QAAM,SAAS,MAAM,cAAc;AACnC,QAAM,OAAO,WAAW,QAAQ,WAAW;AAC3C,QAAM,UAAU,WAAW,OAAO,QAAQ,OAAO,IAAI,IAAI;AAEzD,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,cAAwB,CAAC;AAC7B,MAAI,UAAoB,CAAC;AACzB,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI;AACJ,QAAM,aAA0B,CAAC;AACjC,MAAI;AACJ,MAAIC;AACJ,MAAIC;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,CAAC,WAAW,gBAAgB,SAAS;AAEvC,UAAM,SAAS,WAAW,gBAAgB,UAAU,QAAQ,aAAa;AACzE,UAAM,YAAY,QAAQ,aAAaJ,eAAc,KAAK,MAAM,aAAa,CAAC,KAAK,EAAE;AACrF,UAAM,OAAO,QAAQ;AACrB,UAAM,YACJ,MAAM,aAAa,UACnB,SAAS,MAAM,MAAM,UAAU,UAAU,MAAM,kBAAkB,CAAC,EAAE,SAAS;AAC/E,uBAAmB,OAAO,gBAAgB,YAAY,YAAY;AAClE,sBAAkB;AAClB,iBAAa;AACb,QAAI,aAAa,CAAC,WAAW;AAE3B,oBAAc;AACd,gBAAU,CAAC,eAAe;AAC1B,YAAM;AAAA,IACR,OAAO;AACL,oBAAc;AACd,YAAM,OAAO,MAAM;AAAA,IACrB;AACA,UAAM,aAAa,QAAQ,UAAU,MAAM,aAAa,CAAC,KAAK;AAC9D,UAAM,QAAQA,eAAc,KAAK,UAAU;AAC3C,UAAM,aAAgC,YAClC,8BACA;AACJ,QAAI,OAAO;AACT,iBAAW,KAAK,UAAU,MAAM,CAAC,GAAa,iBAAiB,UAAU,CAAC;AAC1E,iBAAW,KAAK,UAAU,MAAM,CAAC,GAAa,SAAS,UAAU,CAAC;AAAA,IACpE,WAAW,YAAY;AACrB,iBAAW;AAAA,QACT,UAAU,YAAY,SAAS,YAAY,cAAc,4BAA4B;AAAA,MACvF;AAAA,IACF;AACA,QAAI,KAAM,YAAW,KAAK,UAAU,SAAS,IAAI,GAAG,cAAc,UAAU,CAAC;AAC7E,QAAI,MAAM,UAAU;AAClB,iBAAW;AAAA,QACT;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA,YAAY,cAAc;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,UAAU,MAAM,kBAAkB;AAChD,QAAI,OAAO;AACT,iBAAW;AAAA,QACT;AAAA,UACE;AAAA,UACA;AAAA,UACA,YAAY,KAAK,IAAI,cAAc;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,YAAY;AACpB,YAAM,WAAW,KAAK,KAAK,CAACC,SAAQA,KAAI,QAAQ,MAAM,YAAY,MAAM,GAAG,CAAC,CAAC;AAC7E,iBAAW;AAAA,QACT;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA,WAAW,cAAc;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,MACT,UAAU,WAAW,OAAO,QAAQ,QAAQ,WAAW,aAAa;AAAA,QAClE,UAAU,MAAM,eAAe;AAAA,MACjC,CAAC;AAAA,IACH;AACA,kBAAc,MAAM,eAAe;AACnC,kBAAc,WACX,OAAO,CAAC,MAAM,EAAE,sBAAsB,WAAW,EACjD,IAAI,CAAC,MAAM,EAAE,aAAa;AAC7B,UAAM,OAAO,CAAC,YAAY,OAAO,SAAS,IAAI,IAAI,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC9E,oBAAgB,QAAQ;AAAA,MACtB,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,oBAAoB;AAAA,MACpB,UAAU,MAAM;AAAA,MAChB,cAAc,OAAO,CAAC,IAAI,IAAI;AAAA,IAChC,CAAC;AACD,IAAAE,oBAAmB;AAAA,MACjB;AAAA,MACA,MAAM;AAAA,MACN,CAAC,OAAO,MAAM,UAAU,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAClD,WAAW,OAAO,QAAQ;AAAA,IAC5B,EACG,OAAO,OAAO,EACd,KAAK,IAAI;AAAA,EACd,OAAO;AACL,UAAM,IAAI,QAAQ;AAClB,UAAMF,OAAM,EAAE;AACd,YAAQA,KAAI;AACZ,UAAM,SAAS,EAAE;AACjB,UAAM,aAAaA,KAAI,cAAc,CAAC;AACtC,UAAM,QAAQ,SAASA,MAAK,MAAM;AAClC,uBAAmB,EAAE,OAAO,gBAAgB;AAC5C,kBAAc;AACd,sBAAkB;AAClB,iBAAa;AACb,UAAM;AACN,kBAAc;AACd,QAAI,YAA+B;AAEnC,QAAI,WAAW,WAAW;AACxB,UAAI,CAAC,EAAE,MAAM;AACX,kBAAU,CAAC,YAAY;AACvB,0BAAkB;AAClB,qBAAa;AACb,cAAM;AACN,sBAAc;AAAA,MAChB,WACE,WAAW,UAAU,UACrB,WAAW,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,MAAM,EAAE,MAAM,KAAK,GAC9D;AACA,sBAAc;AAAA,MAChB,OAAO;AACL,oBAAY;AACZ,qBAAa;AACb,cAAM;AACN,sBAAc;AAAA,MAChB;AAAA,IACF,WAAW,EAAE,MAAM;AAEjB,kBAAY;AACZ,mBAAa;AACb,oBAAc;AAAA,IAChB;AAEA,QAAI,EAAE,WAAW,cAAc,EAAE,aAAa,cAAc,EAAE,UAAU,YAAY;AAClF,oBAAc;AACd,UAAI,eAAe,SAAU,cAAa;AAAA,IAC5C;AAEA,eAAW,KAAK,UAAU,EAAE,QAAkB,iBAAiB,WAAW,CAAC;AAC3E,eAAW,KAAK,UAAU,EAAE,OAAO,SAAS,WAAW,CAAC;AACxD,QAAI,EAAE,KAAM,YAAW,KAAK,UAAU,SAAS,EAAE,IAAI,GAAG,cAAc,SAAS,CAAC;AAChF,eAAW;AAAA,MACT,UAAUA,KAAI,MAAM,YAAY,aAAa,EAAE,UAAU,EAAE,aAAa,WAAW,CAAC;AAAA,IACtF;AACA,eAAW;AAAA,MACT,UAAUA,KAAI,OAAO,+BAA+B,aAAa;AAAA,QAC/D,UAAU,EAAE,UAAU;AAAA,MACxB,CAAC;AAAA,IACH;AACA,eAAW;AAAA,MACT,UAAUA,KAAI,KAAK,eAAe,aAAa;AAAA,QAC7C,UAAU,EAAE,WAAW;AAAA,QACvB,UAAU,EAAE,WAAW;AAAA,MACzB,CAAC;AAAA,IACH;AACA,eAAW,KAAK,UAAU,OAAO,sBAAsB,aAAa,EAAE,UAAU,KAAK,CAAC,CAAC;AACvF,eAAW;AAAA,MACT,UAAU,OAAO,WAAW,aAAa,EAAE,UAAU,MAAM,eAAe,OAAU,CAAC;AAAA,IACvF;AACA,kBAAc;AACd,kBAAc,WACX,OAAO,CAAC,MAAM,EAAE,sBAAsB,WAAW,EACjD,IAAI,CAAC,MAAM,EAAE,aAAa;AAE7B,QAAI,WAAW,YAAa,eAAc,WAAW;AACrD,QAAI,WAAW,oBAAoB,OAAW,mBAAkB,WAAW;AAC3E,QAAI,WAAW,mBAAoB,cAAa,WAAW;AAC3D,QAAI,WAAW,gBAAiB,OAAM,WAAW;AACjD,QAAI,WAAW;AACb,oBAAc,CAAC,GAAG,WAAW,yBAAyB;AACxD,QAAI,WAAW,iBAAkB,aAAY,WAAW;AAExD,UAAM,OAAO,CAAC,QAAQ,EAAE,OAAO,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC9E,UAAM,MAAM,GAAGA,KAAI,GAAG,IAAI,KAAK;AAC/B,oBAAgB;AAAA,MACd,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,oBAAoBA,KAAI;AAAA,MACxB,UAAUA,KAAI;AAAA,MACd,cAAc,CAAC,IAAI;AAAA,IACrB;AACA,IAAAE,oBAAmB,GAAG,IAAI,KAAKF,KAAI,IAAI,KAAKA,KAAI,KAAK,IAAI,GAAG;AAC5D,UAAM,QAAQ,EAAE,WACZ,EAAE,SAAS,cAAcA,IAAG,GAAG,KAAKA,KAAI,KAAK,KAAKA,KAAI,IAAI,IAC1D,WAAW,QAAQA,IAAG;AAC1B,IAAAG,WAAU;AAAA,MACR,UAAU,EAAE,UAAU,MAAM,KAAK,WAAW,MAAM,IAAI;AAAA,MACtD,SAAS,MAAM;AAAA,MACf,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,CAAC,SAAS;AAAA,IAClD;AACA,mBAAe;AAAA,MACb,kBAAkB,KAAK,YAAY;AAAA,MACnC,yBAAyB,GAAGH,KAAI,KAAK,YAAY,CAAC,IAAIA,KAAI,KAAK,IAAI,GAAG;AAAA,MACtE,MAAMA,KAAI,KAAK,YAAY;AAAA,MAC3B,OAAOA,KAAI;AAAA,MACX,SAASA,KAAI;AAAA,MACb,kBAAkB;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,QAAQ,YAAa,OAAM,QAAQ;AACvC,MAAI,QAAQ,IAAK,gBAAe;AAChC,MAAI,QAAQ,UAAa,gBAAgB,OAAW,eAAc,QAAQ,MAAM,SAAS;AACzF,MAAI,QAAQ,IAAK,eAAc;AAE/B,QAAM,UAAU,QAAQ;AAAA,IACtB;AAAA,IACA,uBAAuB;AAAA,IACvB,oBAAoB,gBAAgB,gBAAgB,YAAY;AAAA,IAChE;AAAA,IACA,0BAA0B,YAAY,SAAS;AAAA,IAC/C,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,IACvB,oBAAoB;AAAA,EACtB,CAAC;AACD,QAAM,UAAU,QAAQ;AAAA,IACtB,kBAAAE;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB,uBAAuB,KAAK,OAAO;AAAA,IACnC,2BAA2B,KAAK,WAAW;AAAA,EAC7C,CAAC;AACD,QAAM,WAAW,OACb,YACE,QAAQ,EAAE,cAAc,WAAW,eAAe,eAAe,CAAC,IAClE,QAAQ;AAAA,IACN,qBAAqB;AAAA,IACrB,iBAAiB;AAAA,IACjB,aAAa,MAAM,cAAc;AAAA,IACjC,gBAAgB,eAAe,aAAa,OAAO;AAAA,IACnD,iBAAiB,eAAe,aAAa,QAAQ;AAAA,IACrD,eAAe;AAAA,EACjB,CAAC,IACH;AACJ,QAAM,SAAS,QAAQ,EAAE,SAAS,SAAS,SAAAC,UAAS,SAAS,CAAC;AAC9D,QAAM,eAAe,GAAG,UAAU,IAAI,YAAY,UAAW,OAAO,GAAI;AACxE,SAAO;AAAA,IACL,MAAM,EAAE,QAAQ,YAAY,WAAW,KAAK,UAAU,EAAE,OAAO,eAAe,CAAC,CAAC,EAAE;AAAA,IAClF;AAAA,IACA;AAAA,EACF;AACF;;;AChuBA,IAAM,eAAe,CAAC,qBAAqB,gBAAgB,WAAW,mBAAmB;AAEzF,IAAM,kBAAkB,CAAC,SACvB,aAAa,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,KAAK,EAAE;AAOvD,IAAM,sBAAmD;AAAA,EAC9D,kBAAkB;AAAA,IAChB,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,QAAQ,iBAAiB,QAAQ,EAAE,QAAQ,mBAAmB,EAAE,CAAC;AAAA,EAC5F;AAAA,EACA,gBAAgB;AAAA,IACd,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,QAAQ,iBAAiB,QAAQ,EAAE,QAAQ,iBAAiB,EAAE,CAAC;AAAA,EAC1F;AAAA,EACA,eAAe;AAAA,IACb,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,QAAQ,iBAAiB,QAAQ,EAAE,QAAQ,gBAAgB,EAAE,CAAC;AAAA,EACzF;AAAA,EACA,cAAc;AAAA,IACZ,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,QAAQ,iBAAiB,QAAQ,EAAE,QAAQ,eAAe,EAAE,CAAC;AAAA,EACxF;AAAA,EACA,sBAAsB;AAAA,IACpB,aAAa;AAAA,IACb,OAAO;AAAA,MACL,EAAE,aAAa,WAAW,QAAQ,iBAAiB,QAAQ,EAAE,QAAQ,eAAe,EAAE;AAAA,IACxF;AAAA,EACF;AAAA,EACA,+BAA+B;AAAA,IAC7B,aACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,QAAQ,EAAE,QAAQ,mBAAmB;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,QAAQ,KAAK,MAAM,EAAE,OAAO,wBAAwB,EAAE,CAAC;AAAA,EAClF;AAAA,EACA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,OAAO,gBAAgB,EAAE,WAAW,IAAM,CAAC;AAAA,EAC7C;AAAA,EACA,2BAA2B;AAAA,IACzB,aACE;AAAA,IACF,OAAO;AAAA,MACL;AAAA,QACE,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SACE;AAAA,YACF,QAAQ;AAAA,YACR,SAAS;AAAA,cACP;AAAA,gBACE,SAAS;AAAA,gBACT,QAAQ;AAAA,gBACR,QAAQ;AAAA,gBACR,UAAU,EAAE,SAAS,mCAAmC;AAAA,cAC1D;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,gCAAgC;AAAA,IAC9B,aAAa;AAAA,IACb,OAAO;AAAA,MACL;AAAA,QACE,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,MAAM;AAAA,UACJ,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,YACT,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,yBAAyB;AAAA,IACvB,aAAa;AAAA,IACb,OAAO,CAAC,EAAE,aAAa,mBAAmB,WAAW,IAAM,CAAC;AAAA,EAC9D;AAAA,EACA,+BAA+B;AAAA,IAC7B,aACE;AAAA,IACF,OAAO,CAAC,EAAE,aAAa,mBAAmB,QAAQ,KAAK,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC;AAAA,EAC/E;AAAA,EACA,0BAA0B;AAAA,IACxB,aAAa;AAAA,IACb,OAAO;AAAA,MACL,EAAE,aAAa,mBAAmB,QAAQ,YAAY,QAAQ,EAAE,iBAAiB,IAAI,EAAE;AAAA,IACzF;AAAA,EACF;AAAA,EACA,oBAAoB;AAAA,IAClB,aAAa;AAAA,IACb,OAAO,CAAC,EAAE,aAAa,qBAAqB,QAAQ,KAAK,MAAM,sBAAsB,CAAC;AAAA,EACxF;AACF;AAeA,IAAMC,QAAO,CAAC,QAAgB,SAC5B,IAAI,SAAS,KAAK,UAAU,IAAI,GAAG,EAAE,QAAQ,SAAS,EAAE,gBAAgB,mBAAmB,EAAE,CAAC;AAChG,IAAMC,cAAa,CAAC,QAAgB,YAClCD,MAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,qBAAqB,QAAQ,EAAE,CAAC;AAChE,IAAME,YAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,aAAa,CAAC,UAClB,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,IAC3D,QACD;AAGN,IAAM,kBAAkB,CACtB,OACA,UAC6C;AAC7C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,QAAM,KAAK,aAAa,KAAK;AAC7B,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO,GAAG,EAAE;AAClC,QAAM,MAA2B,CAAC;AAClC,QAAM,QAAQ;AAAA,IACZ,CAAC,eAAe,aAAa;AAAA,IAC7B,CAAC,sBAAsB,YAAY;AAAA,IACnC,CAAC,mBAAmB,SAAS;AAAA,EAC/B;AACA,aAAW,CAAC,KAAK,OAAO,KAAK,OAAO;AAClC,QAAI,MAAM,GAAG,MAAM,OAAW;AAC9B,QAAI,CAAE,QAA+B,SAAS,MAAM,GAAG,CAAC,GAAG;AACzD,aAAO,GAAG,EAAE,IAAI,GAAG,mBAAmB,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC1D;AACA,WAAO,OAAO,KAAK,EAAE,CAAC,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC;AAAA,EAC1C;AACA,aAAW,OAAO,CAAC,mBAAmB,WAAW,GAAY;AAC3D,QAAI,MAAM,GAAG,MAAM,OAAW;AAC9B,QAAI,OAAO,MAAM,GAAG,MAAM,UAAW,QAAO,GAAG,EAAE,IAAI,GAAG;AACxD,QAAI,GAAG,IAAI,MAAM,GAAG;AAAA,EACtB;AACA,aAAW,OAAO,CAAC,6BAA6B,OAAO,GAAY;AACjE,QAAI,MAAM,GAAG,MAAM,OAAW;AAC9B,UAAM,OAAO,WAAW,MAAM,GAAG,CAAC;AAClC,QAAI,CAAC,KAAM,QAAO,GAAG,EAAE,IAAI,GAAG;AAC9B,QAAI,GAAG,IAAI;AAAA,EACb;AACA,MAAI,MAAM,qBAAqB,QAAW;AACxC,QAAI,OAAO,MAAM,qBAAqB,YAAY,CAAC,MAAM,kBAAkB;AACzE,aAAO,GAAG,EAAE;AAAA,IACd;AACA,QAAI,mBAAmB,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAGO,IAAM,eAAe,CAAC,OAAgB,UAA0C;AACrF,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO,aAAa,KAAK;AAC/C,aAAW,OAAO,CAAC,SAAS,QAAQ,SAAS,KAAK,GAAY;AAC5D,QAAI,OAAO,MAAM,GAAG,MAAM,YAAY,CAAE,MAAM,GAAG,EAAa,KAAK,GAAG;AACpE,aAAO,aAAa,KAAK,KAAK,GAAG;AAAA,IACnC;AAAA,EACF;AACA,QAAM,QAAQ,OAAO,MAAM,KAAK,EAAE,YAAY;AAC9C,MAAI,CAAC,aAAa,KAAK,KAAK,EAAG,QAAO,aAAa,KAAK;AACxD,QAAM,aAAa,gBAAgB,MAAM,YAAY,KAAK;AAC1D,MAAI,OAAO,eAAe,SAAU,QAAO;AAC3C,QAAM,MAAM,MAAM,QAAQ,SAAY,IAAI,OAAO,MAAM,GAAG;AAC1D,QAAM,MAAM,MAAM,QAAQ,SAAY,IAAI,OAAO,MAAM,GAAG;AAC1D,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;AAClD,WAAO,aAAa,KAAK;AAAA,EAC3B;AACA,SAAO;AAAA,IACL,IACE,OAAO,MAAM,OAAO,YAAY,MAAM,KAClC,MAAM,KACN,UAAU,OAAO,MAAM,GAAG,CAAC,IAAI,OAAO,MAAM,KAAK,EAC9C,YAAY,EACZ,QAAQ,eAAe,GAAG,CAAC;AAAA,IACpC,OAAO,OAAO,MAAM,KAAK,EAAE,KAAK;AAAA,IAChC,MAAM,OAAO,MAAM,IAAI,EAAE,KAAK;AAAA,IAC9B;AAAA,IACA,KAAK,OAAO,MAAM,GAAG,EAAE,KAAK;AAAA,IAC5B,QAAQ,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AAAA,IAC1D;AAAA,IACA;AAAA,IACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,EACrC;AACF;AAEA,IAAM,cAAc,CAAC,aAAyD;AAAA,EAC5E,eAAe,CAAC,EAAE,UAAU,MAAM;AAChC,UAAM,MAAM,QAAQ,SAAS,SAAS;AACtC,WAAOF,MAAK,KAAK;AAAA,MACf,WAAW,IAAI,OAAO;AAAA,MACtB,QAAQ,IAAI,MAAM,OAAO,MAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EACA,eAAe,CAAC,EAAE,MAAM,UAAU,MAAM;AACtC,UAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAOE,UAAS,IAAI,IAAI,KAAK,YAAY;AAC5E,QAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,aAAOD;AAAA,QACL;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,OAAwB,CAAC;AAC/B,eAAW,CAAC,OAAO,IAAI,KAAK,KAAK,QAAQ,GAAG;AAC1C,YAAM,SAAS,aAAa,MAAM,KAAK;AACvC,UAAI,OAAO,WAAW,SAAU,QAAOA,YAAW,KAAK,MAAM;AAC7D,WAAK,KAAK,MAAM;AAAA,IAClB;AACA,UAAM,MAAM,QAAQ,SAAS,SAAS;AACtC,QAAI,MAAM,cAAc,IAAI;AAC5B,WAAOD,MAAK,KAAK,EAAE,QAAQ,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,kBAAkB,CAAC,EAAE,UAAU,MAAM;AACnC,YAAQ,SAAS,SAAS,EAAE,MAAM,cAAc,CAAC,CAAC;AAClD,WAAOA,MAAK,KAAK,EAAE,QAAQ,KAAK,CAAC;AAAA,EACnC;AAAA,EACA,iBAAiB,CAAC,EAAE,UAAU,MAAMA,MAAK,KAAK,QAAQ,SAAS,SAAS,EAAE,MAAM,QAAQ,CAAC;AAAA,EACzF,iBAAiB,CAAC,EAAE,MAAM,UAAU,MAAM;AACxC,QAAI,CAACE,UAAS,IAAI,EAAG,QAAOD,YAAW,KAAK,wBAAwB;AACpE,UAAM,QAA2B,CAAC;AAClC,QAAI,KAAK,SAAS,QAAW;AAC3B,UAAI,CAAC,MAAM,QAAQ,KAAK,IAAI,EAAG,QAAOA,YAAW,KAAK,gBAAgB;AACtE,YAAM,OAAO,KAAK,KAAK,IAAI,MAAM;AAAA,IACnC;AACA,QAAI,KAAK,cAAc,QAAW;AAChC,UAAI,KAAK,cAAc,QAAQ,OAAO,KAAK,cAAc,UAAU;AACjE,eAAOA,YAAW,KAAK,0BAA0B;AAAA,MACnD;AACA,YAAM,YAAY,KAAK;AAAA,IACzB;AACA,WAAOD,MAAK,KAAK,QAAQ,SAAS,SAAS,EAAE,MAAM,OAAO,KAAK,CAAC;AAAA,EAClE;AACF;AAQO,IAAMG,iBAAgB,CAAC,UAAoC,CAAC,MACjE,cAAoC;AAAA,EAClC,MAAM;AAAA,EACN,UAAAC;AAAA,EACA,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,EACnD,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EAChD,GAAI,QAAQ,SAAS,SAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,EAC3D,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EACvE,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EAChD,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,QAAQ,CAAC,EAAE,QAAQ,WAAW,iBAAiB,MAAM,MACnD,IAAI,cAAc;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,MAAM;AAAA,IACX,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACnD,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC3D,CAAC;AAAA,EACH,UAAU,OAAO;AAAA,IACf,QAAQ,QAAQ,SACZ,WAAW,QAAQ,OAAO,MAAM,MAChC,0BAA0B,eAAe,MAAM;AAAA,EACrD;AAAA,EACA,OAAO;AACT,CAAC;;;AC5PI,IAAM,wBAAwB;AAG9B,IAAM,sBACX;AACK,IAAM,sBAAsB;AAM5B,IAAM,0BAA0B;AAChC,IAAM,0BAA0B;AAyBhC,IAAM,gBAAgB,CAAC,YAC5B,IAAI,IAAI,QAAQ,GAAG,EAAE,aAAa,IAAI,KAAK,KAAK,QAAQ,QAAQ,IAAI,gBAAgB,KAAK;AAE3F,IAAM,OAAO,EAAE,+BAA+B,IAAI;AAElD,IAAMC,QAAO,CAAC,MAAe,SAAS,QACpC,IAAI,SAAS,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG;AAAA,EAC1C;AAAA,EACA,SAAS,EAAE,gBAAgB,mCAAmC,GAAG,KAAK;AACxE,CAAC;AAGH,IAAM,QAAiD;AAAA,EACrD,mBAAmB,EAAE,aAAa,CAAC,EAAE;AAAA,EACrC,cAAc,EAAE,mBAAmB,CAAC,EAAE;AAAA,EACtC,SAAS,EAAE,SAAS,CAAC,EAAE;AAAA,EACvB,mBAAmB,EAAE,YAAY,CAAC,EAAE;AACtC;AAEA,IAAM,mBAA0D;AAAA,EAC9D,kBACE;AAAA,EACF,eAAe;AAAA,EACf,gBAAgB;AAClB;AAGA,IAAM,WAAW,CAAC,UAAoCA,MAAK,EAAE,MAAM,GAAG,MAAM,IAAI;AAGhF,IAAM,cAAc,CAAC,SAA4C;AAC/D,MAAI,KAAK,SAAS,OAAQ,QAAO,KAAK;AACtC,MAAI,KAAK,SAAS,QAAS,QAAO,CAAC;AACnC,QAAM,MACJ,KAAK,SAAS,UACV,IAAI,YAAY,EAAE,OAAO,KAAK,KAAK,IACnC,KAAK,SAAS,SACZ,KAAK,QACL,KAAK,SAAS,YACZ,KAAK,OACL;AACV,MAAI;AACF,WAAO,KAAK,MAAM,OAAO,EAAE;AAAA,EAC7B,QAAQ;AACN,UAAM,IAAI,uBAAuB,gCAAgC;AAAA,EACnE;AACF;AAEA,IAAM,OAAO,CAAC,UACZ,OAAO,UAAU,WAAW,QAAQ,MAAM,QAAQ,KAAK,IAAI,OAAO,MAAM,CAAC,CAAC,IAAI;AAMzE,IAAM,gBAAN,MAAwC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAEjB,YAAY,UAAgC,CAAC,GAAG;AAC9C,UAAM,SAAS,WAAW,QAAQ,MAAM;AACxC,UAAM,YAAY,QAAQ,aAAa;AACvC,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,QAAQ,IAAI,gBAAgB,QAAQ,WAAW;AAAA,MAClD,QAAQ,QAAQ,UAAU,CAAC;AAAA,MAC3B,UAAU,QAAQ,YAAY,CAAC;AAAA,IACjC,CAAC;AACD,UAAM,WAAW,iBAAuC;AAAA,MACtD,mBAAmB,CAAC,YAAY,KAAK,aAAa,OAAO;AAAA,MACzD,cAAc,CAAC,YAAY,KAAK,QAAQ,OAAO;AAAA,MAC/C,SAAS,CAAC,YAAY,KAAK,QAAQ,OAAO;AAAA,MAC1C,mBAAmB,CAAC,YAAY,KAAK,UAAU,OAAO;AAAA,MACtD,mBAAmB,CAAC,YAAY,KAAK,OAAO,OAAO;AAAA,MACnD,iBAAiB,CAAC,YAAY,KAAK,SAAS,OAAO;AAAA,IACrD,CAAC;AACD,SAAK,UAAU,cAAc;AAAA,MAC3B,UAAAC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,MAC1C,UAAU,MACR,IAAI,SAAS,gDAAgD;AAAA,QAC3D,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,4BAA4B,GAAG,KAAK;AAAA,MACjE,CAAC;AAAA,MACH,SAAS,CAAC,UAAU;AAClB,YAAI,iBAAiB,UAAW,QAAO,MAAM,WAAW;AACxD,cAAM;AAAA,MACR;AAAA,MACA,QAAQ,CAAC,YAAY,KAAK,KAAK,OAAO;AAAA,IACxC,CAAC;AACD,SAAK,MAAM,KAAK,QAAQ;AACxB,SAAK,SAAS,KAAK,QAAQ;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAqC;AACzC,WAAO,KAAK,QAAQ,MAAM,OAAO;AAAA,EACnC;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,QAAQ,MAAM;AACzB,SAAK,MAAM,aAAa;AAAA,EAC1B;AAAA;AAAA,EAGA,SAA0B;AACxB,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B;AAAA,EAEQ,OAAO,aAAqB,QAAsB,SAA4B;AACpF,WAAOD,MAAK;AAAA,MACV,GAAG,MAAM,WAAW;AAAA,MACpB,GAAI,UAAU,EAAE,eAAe,QAAQ,IAAI,CAAC;AAAA,MAC5C;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,KAAK,SAAiD;AAC5D,UAAM,cAAc,QAAQ,UAAU;AACtC,QAAI,gBAAgB,oBAAqB,QAAO;AAChD,QAAI,gBAAgB,kBAAmB,QAAO,KAAK,UAAU,OAAO;AACpE,UAAM,MAAM,KAAK,QAAQ,MAAM,GAAG;AAClC,QAAI,CAAC,IAAK,QAAO,KAAK,OAAO,aAAa,kBAAkB,mBAAmB;AAC/E,UAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,QAAI,KAAK,SAAS,KAAK,CAAC,KAAK,SAAS,GAAG,GAAG;AAC1C,aAAO,KAAK,OAAO,aAAa,kBAAkB,mBAAmB;AAAA,IACvE;AACA,UAAM,SAAS,YAAY,QAAQ,SAAS,eAAe;AAC3D,QAAI,WAAW,QAAW;AACxB,YAAM,SACJ,OAAO,OAAO,WAAW,WAAW,OAAO,SAAS;AAEtD,YAAM,UACJ,OAAO,OAAO,kBAAkB,WAAW,OAAO,gBAAgB,iBAAiB,MAAM;AAC3F,aAAO,KAAK,OAAO,aAAa,QAAQ,OAAO;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,UAAU,SAAiD;AACjE,UAAM,MAAM,KAAK,QAAQ,MAAM,GAAG,KAAK,QAAQ,QAAQ,QAAQ,IAAI,gBAAgB;AACnF,QAAI,CAAC,KAAK;AACR,aAAO,SAAS,EAAE,MAAM,KAAK,SAAS,yBAAyB,QAAQ,oBAAoB,CAAC;AAAA,IAC9F;AACA,UAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,QAAI,KAAK,SAAS,KAAK,CAAC,KAAK,SAAS,GAAG,GAAG;AAC1C,aAAO,SAAS;AAAA,QACd,MAAM;AAAA,QACN,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS;AAAA,UACP;AAAA,YACE,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,UAAU,EAAE,SAAS,mCAAmC;AAAA,UAC1D;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,SAAqC;AACpD,QAAI;AACJ,QAAI;AACF,gBAAU,qBAAqB,YAAY,QAAQ,IAAI,CAAC;AAAA,IAC1D,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,wBAAyB,OAAM;AACtD,aAAO,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,SAAS,QAAQ,mBAAmB,CAAC;AAAA,IACnF;AACA,UAAM,SAAS,YAAY,QAAQ,SAAS,UAAU,GAAG;AACzD,UAAM,cAAc,UAAU,SAAS,MAAyB,IAC3D,SACD;AACJ,UAAM,UAAU,gBAAgB,SAAS,KAAK,MAAM,OAAO,GAAG;AAAA,MAC5D,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACvC,CAAC;AAED,WAAO,iBAAiBA,MAAK,QAAQ,IAAI,GAAG;AAAA,MAC1C,KAAK;AAAA,QACH,GAAI,QAAQ,QAAQ,EAAE,cAAc,QAAQ,MAAM,IAAI,CAAC;AAAA,QACvD,SAAS,QAAQ;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,MAAM,UAAoB,SAA2B,OAAyB;AACpF,UAAM,UAAU,KAAK,QAAQ,MAAM,YAAY;AAC/C,UAAM,MAA8B,CAAC;AACrC,QAAI,MAAO,KAAI,UAAU,MAAM;AAE/B,QAAI,QAAS,KAAI,eAAe;AAChC,WAAO,OAAO,KAAK,GAAG,EAAE,SAAS,IAAI,iBAAiB,UAAU,EAAE,IAAI,CAAC,IAAI;AAAA,EAC7E;AAAA,EAEQ,aAAa,SAAqC;AACxD,UAAM,QAAQ,KAAK,QAAQ,MAAM,KAAK;AACtC,QAAI,CAAC,MAAO,QAAO,KAAK,OAAO,qBAAqB,iBAAiB;AACrE,UAAM,aAAa,KAAK,QAAQ,MAAM,UAAU;AAChD,QAAI,eAAe,QAAW;AAC5B,YAAM,YAAY,WACf,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,EACjC,OAAO,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC,EACtC,IAAI,CAAC,MAAM,EAAE,MAAM,WAAW,MAAM,CAAC;AACxC,UAAI,UAAU,SAAS,KAAK,CAAC,UAAU,SAAS,IAAI,GAAG;AACrD,eAAO,KAAK,MAAMA,MAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,OAAO;AAAA,MAC9E;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,QAAQ,MAAM,KAAK;AACtC,QAAI,SAAS,aAAa,OAAO,KAAK,MAAM,OAAO,CAAC;AACpD,QAAI,UAAU,UAAW,UAAS,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB;AAClF,QAAI,OAAO,WAAW,GAAG;AACvB,aAAO,KAAK,MAAMA,MAAK,EAAE,aAAa,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,OAAO;AAAA,IAC9E;AACA,WAAO,KAAK;AAAA,MACVA,MAAK,EAAE,aAAa,OAAO,IAAI,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,QAAQ,KAAK,CAAC;AAAA,MAC3E;AAAA,MACA,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,QAAQ,SAAqC;AACnD,UAAM,UAAU,KAAK,QAAQ,MAAM,QAAQ;AAC3C,QAAI,CAAC,QAAS,QAAO,KAAK,OAAO,gBAAgB,iBAAiB;AAClE,UAAM,SAAS,KAAK,QAAQ,MAAM,MAAM;AACxC,QAAI,cAAc,MAAM,EAAE,SAAS,GAAG;AACpC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,mEAAmE,cAAc,MAAM,EAAE,CAAC,CAAC;AAAA,MAC7F;AAAA,IACF;AACA,UAAM,QAAQ,UAAU,SAAS,KAAK,MAAM,OAAO,CAAC;AACpD,QAAI,CAAC,MAAO,QAAO,KAAK,MAAM,KAAK,OAAO,gBAAgB,WAAW,GAAG,OAAO;AAC/E,WAAO,KAAK;AAAA,MACVA,MAAK;AAAA,QACH,mBAAmB,CAAC;AAAA,QACpB,QAAQ,WAAW,YAAY,KAAK,GAAG,QAAQ,KAAK;AAAA,QACpD,QAAQ;AAAA,MACV,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,QAAQ,SAAqC;AACnD,UAAM,UAAU,KAAK,QAAQ,MAAM,OAAO;AAC1C,UAAM,UAAU,KAAK,QAAQ,MAAM,QAAQ;AAC3C,UAAM,aAAa,KAAK,QAAQ,MAAM,UAAU;AAChD,UAAM,MAAM,YACR,MAAM,GAAG,EACV,KAAK,CAAC,MAAM,EAAE,WAAW,cAAc,CAAC,GACvC,MAAM,eAAe,MAAM;AAC/B,QAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAK,QAAO,KAAK,OAAO,WAAW,iBAAiB;AACjF,UAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,UAAM,QAAQ,UACV,UAAU,SAAS,IAAI,IACvB,UACE,QAAQ,SAAS,IAAI,IACrB,QAAQ,KAAe,IAAI;AACjC,QAAI,CAAC,MAAO,QAAO,KAAK,MAAMA,MAAK,EAAE,SAAS,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,OAAO;AACpF,UAAM,OAAO,YAAY,KAAK;AAC9B,WAAO,KAAK;AAAA,MACVA,MAAK;AAAA,QACH,SAAS;AAAA,UACP;AAAA,YACE,oBAAoB,KAAK;AAAA,YACzB,mBAAmB,KAAK;AAAA,YACxB,UAAU,SAAS,OAAO,IAAI;AAAA,YAC9B,UAAU,MAAM;AAAA,YAChB,OAAO,KAAK;AAAA,UACd;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAU,SAAqC;AACrD,UAAM,QAAQ,KAAK,QAAQ,MAAM,KAAK;AACtC,UAAM,YAAY,KAAK,QAAQ,MAAM,SAAS;AAC9C,QAAI,CAAC,SAAU,cAAc,eAAe,cAAc,eAAgB;AACxE,aAAO,KAAK,OAAO,qBAAqB,iBAAiB;AAAA,IAC3D;AACA,UAAM,SAAS,KAAK,QAAQ,MAAM,MAAM;AACxC,QAAI,cAAc,MAAM,EAAE,SAAS,GAAG;AACpC,aAAO,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,mEAAmE,cAAc,MAAM,EAAE,CAAC,CAAC;AAAA,MAC7F;AAAA,IACF;AACA,UAAM,QAAQ,cAAc,cAAc,UAAU,OAAO,KAAK,MAAM,OAAO,CAAC,IAAI;AAClF,QAAI,CAAC,MAAO,QAAO,KAAK,MAAMA,MAAK,EAAE,YAAY,CAAC,GAAG,QAAQ,eAAe,CAAC,GAAG,OAAO;AACvF,WAAO,KAAK;AAAA,MACVA,MAAK,EAAE,YAAY,CAAC,WAAW,YAAY,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,KAAK,CAAC;AAAA,MACzF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,OAAO,SAAqC;AAClD,UAAM,MAAM,KAAK,QAAQ,MAAM,GAAG,KAAK;AACvC,UAAM,WAAW,KAAK,MAAM,QAAQ;AACpC,UAAM,UAAU,SAAS,aAAa,QAAQ,IAAI,QAAQ,QAAQ,OAAO,EAAE;AAC3E,UAAM,SACJ,KAAK,oBAAoB,YAAY,KAAK,OAAO,mBAAmB,KAAK,eAAe,CAAC;AAC3F,UAAM,WAAW,KAAK,QAAQ,MAAM,QAAQ,KAAK;AACjD,UAAM,eAAe,YAAY,sBAAsB,KAAK,QAAQ,IAAI,WAAW;AACnF,UAAM,aAAa,CAAC,OAAQ,SAAS,KAAK,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,GAAG;AACnF,WAAO,IAAI;AAAA,MACT,eAAe,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,IAAI,KAAK,YAAY,UAAU,aAAa,CAAC;AAAA,MACtF;AAAA,QACE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,kCAAkC,GAAG,KAAK;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;",
6
- "names": ["row", "text", "next", "resolve", "document", "document", "text", "text", "round", "row", "isRecord", "row", "readJson", "text", "json", "document", "isRecord", "document", "row", "isRecord", "row", "json", "adminError", "json", "adminError", "isRecord", "BRANCH_PATTERN", "row", "document", "resolve", "snapshot", "branch", "history", "url", "response", "document", "row", "row", "isRecord", "STREET_NUMBER", "row", "text", "formattedAddress", "geocode", "json", "adminError", "isRecord", "createRuntime", "document", "json", "document"]
7
- }