logquill 0.3.0 → 1.0.0

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 +1 @@
1
- {"version":3,"sources":["../src/core/levels.ts","../src/core/records.ts","../src/core/formatter.ts","../src/core/plugin.ts","../src/plugins/context-plugin.ts","../src/plugins/redact-plugin.ts","../src/plugins/pii-redact-plugin.ts","../src/plugins/sampling-plugin.ts","../src/plugins/tamper-evident-plugin.ts","../src/plugins/alerting-plugin.ts","../src/plugins/slack-alert-plugin.ts","../src/plugins/pagerduty-alert-plugin.ts","../src/plugins/email-alert-plugin.ts","../src/transports/transport.ts","../src/transports/batching-transport.ts","../src/transports/sql/base-sql-transport.ts","../src/transports/sql/sqlite-transport.ts","../src/transports/sql/postgres-transport.ts","../src/transports/sql/mysql-transport.ts","../src/transports/nosql/mongodb-transport.ts","../src/transports/nosql/dynamodb-transport.ts","../src/transports/nosql/redis-transport.ts","../src/transports/queue/base-queue-transport.ts","../src/transports/queue/kafka-transport.ts","../src/transports/queue/rabbitmq-transport.ts","../src/transports/queue/sqs-transport.ts","../src/transports/queue/pubsub-transport.ts","../src/transports/cloud/cloudwatch-transport.ts","../src/transports/cloud/cloud-logging-transport.ts","../src/transports/cloud/app-insights-transport.ts","../src/transports/cloud/datadog-transport.ts","../src/transports/cloud/elasticsearch-transport.ts","../src/transports/cloud/new-relic-transport.ts","../src/transports/console-transport.ts","../src/transports/file-transport.ts","../src/transports/http-transport.ts","../src/core/logger.ts","../src/index.ts"],"names":["Level"],"mappings":"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","file":"index.mjs","sourcesContent":["/** Log levels, shared by name and numeric weight with the logquill-python contract. */\nexport enum Level {\n TRACE = 5,\n DEBUG = 10,\n INFO = 20,\n WARN = 30,\n ERROR = 40,\n FATAL = 50,\n}\n\nconst NAME_TO_LEVEL: Readonly<Record<string, Level>> = {\n TRACE: Level.TRACE,\n DEBUG: Level.DEBUG,\n INFO: Level.INFO,\n WARN: Level.WARN,\n ERROR: Level.ERROR,\n FATAL: Level.FATAL,\n};\n\n/** A level given as a `Level`, a level name (any case), or its numeric weight. */\nexport type LevelInput = Level | number | string;\n\n/** The level's name, e.g. `levelName(Level.INFO) === \"INFO\"`. */\nexport function levelName(level: Level): string {\n return Level[level];\n}\n\n/** Normalize a level given as a `Level`, level name, or numeric weight. Throws if unknown. */\nexport function parseLevel(level: LevelInput): Level {\n if (typeof level === \"string\") {\n const parsed = NAME_TO_LEVEL[level.toUpperCase()];\n if (parsed === undefined) {\n throw new Error(`Unknown log level: ${level}`);\n }\n return parsed;\n }\n if (Level[level] === undefined) {\n throw new Error(`Unknown log level: ${String(level)}`);\n }\n return level;\n}\n","import { levelName, type Level } from \"./levels.js\";\n\n/** The cross-language record shape shared with logquill-python. */\nexport interface LogRecord {\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n}\n\n/** ISO8601 UTC timestamp with millisecond precision, matching Python's `utc_timestamp()`. */\nexport function utcTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport function createRecord(params: {\n level: Level;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n}): LogRecord {\n return {\n timestamp: utcTimestamp(),\n level: levelName(params.level),\n logger: params.logger,\n message: params.message,\n meta: params.meta,\n };\n}\n","import type { LogRecord } from \"./records.js\";\n\n/** `format(record) -> string`, per the transport contract shared with logquill-python. */\nexport interface Formatter {\n format(record: LogRecord): string;\n}\n\n/** Serializes a record to the canonical JSON line shape. */\nexport class JSONFormatter implements Formatter {\n format(record: LogRecord): string {\n return JSON.stringify(record);\n }\n}\n","import type { LogRecord } from \"./records.js\";\n\n/**\n * The plugin pipeline hooks, matching the Python hook names: `beforeLog`,\n * `afterLog`, `onError`. All hooks are optional — implement only what you need.\n * A hook that throws cannot crash logging: the pipeline catches it, routes it\n * to `onError`, and moves on.\n */\nexport interface Plugin {\n /** Return a (possibly modified) record, or `null` to drop it. */\n beforeLog?(record: LogRecord): LogRecord | null;\n /** Called after the record has been dispatched to every transport. */\n afterLog?(record: LogRecord): void;\n /** Called when one of this plugin's own hooks throws. */\n onError?(error: unknown, record: LogRecord): void;\n}\n\n/** A plain `beforeLog`-style function, as accepted by `Logger.use()` in place of a `Plugin`. */\nexport type MiddlewareFunc = (record: LogRecord) => LogRecord | null;\n\n/**\n * Wraps a plain `beforeLog`-style function as a `Plugin`. `Logger.use()`\n * builds one of these automatically when given a function instead of a\n * `Plugin` — Express/Koa-style middleware ergonomics, without needing to\n * read the `Plugin` interface first. There's no `next()` chaining: the\n * pipeline already calls hooks in sequence, so this is sugar for a\n * single-method `Plugin`, not a new execution model.\n */\nexport class FunctionPlugin implements Plugin {\n private readonly func: MiddlewareFunc;\n\n constructor(func: MiddlewareFunc) {\n this.func = func;\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n return this.func(record);\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Injects fixed key/value pairs into every record's `meta`.\n * A value already present in a record's own `meta` wins over the fixed context.\n */\nexport class ContextPlugin implements Plugin {\n readonly context: Record<string, unknown>;\n\n constructor(context: Record<string, unknown>) {\n this.context = context;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n return { ...record, meta: { ...this.context, ...record.meta } };\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nexport const DEFAULT_REDACTED_KEYS: readonly string[] = [\"password\", \"token\", \"secret\", \"api_key\", \"authorization\"];\n\nexport interface RedactPluginOptions {\n keys?: readonly string[];\n replacement?: string;\n}\n\n/** Replaces sensitive `meta` values, matched by key (case-insensitive), with a placeholder. */\nexport class RedactPlugin implements Plugin {\n private readonly keys: ReadonlySet<string>;\n readonly replacement: string;\n\n constructor(options: RedactPluginOptions = {}) {\n this.keys = new Set((options.keys ?? DEFAULT_REDACTED_KEYS).map((key) => key.toLowerCase()));\n this.replacement = options.replacement ?? \"***\";\n }\n\n beforeLog(record: LogRecord): LogRecord {\n const meta: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(record.meta)) {\n meta[key] = this.keys.has(key.toLowerCase()) ? this.replacement : value;\n }\n return { ...record, meta };\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Syntactic (not semantic) patterns — matched on shape, so both false\n * positives (a random 9-digit number) and false negatives (anything that\n * doesn't look like these shapes) are expected. Override via `patterns`\n * for anything stricter.\n */\nexport const DEFAULT_PII_PATTERNS: Readonly<Record<string, RegExp>> = {\n email: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g,\n ssn: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g,\n creditCard: /\\b(?:\\d[ -]?){13,16}\\b/g,\n phone: /\\b(?:\\+?1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\\b/g,\n};\n\nconst MAX_DEPTH = 50;\n\nexport interface PIIRedactPluginOptions {\n patterns?: Readonly<Record<string, RegExp>>;\n replacement?: string;\n}\n\n/**\n * Regex-based PII redaction over `meta` **values**, not just keys.\n *\n * Complements `RedactPlugin`, which redacts by exact key match —\n * `PIIRedactPlugin` scans string values (recursively through nested\n * objects/arrays) for emails, SSNs, credit-card numbers, and phone\n * numbers, and redacts matches wherever they appear, regardless of which\n * key holds them (a `notes` field containing a stray SSN is still caught).\n *\n * Detection is pattern-based: fast and dependency-free, but it matches on\n * syntactic shape, not meaning — a random 9-digit number can false-positive\n * as an SSN, and anything that doesn't fit these shapes (a name, a street\n * address) is a false negative. Pass your own `patterns` to extend or\n * replace the defaults.\n *\n * Recursion into nested `meta` structures is depth- and cycle-bounded, so a\n * circular reference or a pathologically deep structure can't hang or\n * crash the caller — it's left unredacted past the bound rather than\n * throwing.\n */\nexport class PIIRedactPlugin implements Plugin {\n readonly patterns: Readonly<Record<string, RegExp>>;\n readonly replacement: string;\n\n constructor(options: PIIRedactPluginOptions = {}) {\n this.patterns = options.patterns ?? DEFAULT_PII_PATTERNS;\n this.replacement = options.replacement ?? \"***\";\n }\n\n beforeLog(record: LogRecord): LogRecord {\n return { ...record, meta: this.redactValue(record.meta, new Set(), 0) as Record<string, unknown> };\n }\n\n private redactValue(value: unknown, seen: ReadonlySet<unknown>, depth: number): unknown {\n if (depth > MAX_DEPTH) {\n return value;\n }\n if (typeof value === \"string\") {\n return this.redactText(value);\n }\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n return value; // circular reference — leave as-is rather than recurse forever\n }\n const nextSeen = new Set(seen).add(value);\n return value.map((entry) => this.redactValue(entry, nextSeen, depth + 1));\n }\n if (value !== null && typeof value === \"object\") {\n if (seen.has(value)) {\n return value;\n }\n const nextSeen = new Set(seen).add(value);\n const result: Record<string, unknown> = {};\n for (const [key, entryValue] of Object.entries(value)) {\n result[key] = this.redactValue(entryValue, nextSeen, depth + 1);\n }\n return result;\n }\n return value;\n }\n\n private redactText(text: string): string {\n let redacted = text;\n for (const pattern of Object.values(this.patterns)) {\n // Custom patterns aren't guaranteed to carry the \"g\" flag, but every\n // occurrence must be replaced (matching Python's `pattern.sub`) —\n // reconstruct with \"g\" added rather than silently stopping at the\n // first match.\n const global = pattern.global ? pattern : new RegExp(pattern.source, `${pattern.flags}g`);\n redacted = redacted.replace(global, this.replacement);\n }\n return redacted;\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"../core/levels.js\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport type { Transport } from \"../transports/transport.js\";\n\nexport interface SamplingPluginOptions {\n rng?: () => number;\n /** `meta` key holding the trace/run id used to group buffered records. Default `\"traceId\"`. */\n traceKey?: string;\n /** A record at or above this level elevates its whole trace. Default `Level.ERROR`. */\n elevateAt?: LevelInput;\n /** Enables tail-based elevation, writing straight to these transports on elevation. Omit to disable and get plain rate-based sampling. */\n transports?: Transport[];\n /** Total buffered records allowed across every trace before the oldest trace is evicted. Default 1000. */\n maxBufferedRecords?: number;\n /** Distinct trace ids held at once before the oldest is evicted. Default 200. */\n maxTraces?: number;\n}\n\n/**\n * Keeps roughly `rate` of records (0.0-1.0), dropping the rest.\n *\n * With `transports` set, sampling becomes tail-based per trace: a record\n * that would otherwise be dropped is buffered under its `meta[traceKey]`\n * value instead of discarded outright. If any later record sharing that\n * trace id reaches `elevateAt` or above, the whole trace is \"elevated\" —\n * every buffered record for that trace id is flushed straight to\n * `transports`, and every subsequent record for that trace id ships\n * unconditionally. This is what lets a sampled-out request still produce a\n * complete trace once it turns out to matter (it errored).\n *\n * Flushing writes buffered records directly to `transports` — pass the\n * same array given to the `Logger`. This bypasses `beforeLog`/`afterLog`/\n * `onError` for any plugin *after* `SamplingPlugin` in the pipeline (the\n * plugins before it already ran, since that's how the buffered record was\n * built); put `SamplingPlugin` last if that matters for your pipeline.\n *\n * Without `transports`, tail-based elevation is inactive and this behaves\n * exactly like plain rate-based sampling (the original behavior) — a\n * record without `meta[traceKey]` is also just rate-sampled, since there's\n * no trace to buffer it under.\n *\n * Buffering is bounded: at most `maxBufferedRecords` records total and\n * `maxTraces` distinct trace ids are held at once. Once either limit is\n * hit, the oldest buffered trace is evicted (and its records are lost, not\n * flushed) — a deliberate bounded-memory trade-off, not a bug: an\n * unbounded per-trace buffer would let a single pathologically long-lived\n * or high-cardinality trace grow memory without limit.\n */\nexport class SamplingPlugin implements Plugin {\n readonly rate: number;\n readonly traceKey: string;\n readonly elevateAt: Level;\n readonly transports: Transport[] | undefined;\n readonly maxBufferedRecords: number;\n readonly maxTraces: number;\n private readonly rng: () => number;\n private readonly buffer = new Map<unknown, LogRecord[]>();\n private bufferedCount = 0;\n private readonly elevated = new Set<unknown>();\n\n constructor(rate: number, options: SamplingPluginOptions = {}) {\n if (rate < 0 || rate > 1) {\n throw new Error(`rate must be between 0 and 1, got ${String(rate)}`);\n }\n this.rate = rate;\n this.rng = options.rng ?? Math.random;\n this.traceKey = options.traceKey ?? \"traceId\";\n this.elevateAt = parseLevel(options.elevateAt ?? Level.ERROR);\n this.transports = options.transports;\n this.maxBufferedRecords = options.maxBufferedRecords ?? 1000;\n this.maxTraces = options.maxTraces ?? 200;\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n const transports = this.transports;\n if (transports === undefined) {\n return this.rng() < this.rate ? record : null;\n }\n\n const traceId = record.meta[this.traceKey];\n\n if (traceId !== undefined && this.elevated.has(traceId)) {\n return record;\n }\n\n const keep = this.rng() < this.rate;\n const reachedElevateLevel = parseLevel(record.level) >= this.elevateAt;\n\n if (traceId !== undefined && reachedElevateLevel) {\n this.elevate(traceId, transports);\n return record;\n }\n\n if (keep) {\n return record;\n }\n\n if (traceId !== undefined) {\n this.bufferRecord(traceId, record);\n }\n\n return null;\n }\n\n private elevate(traceId: unknown, transports: Transport[]): void {\n this.elevated.add(traceId);\n const buffered = this.buffer.get(traceId) ?? [];\n this.buffer.delete(traceId);\n this.bufferedCount -= buffered.length;\n for (const bufferedRecord of buffered) {\n for (const transport of transports) {\n transport.write(transport.format(bufferedRecord), bufferedRecord);\n }\n }\n }\n\n private bufferRecord(traceId: unknown, record: LogRecord): void {\n let records = this.buffer.get(traceId);\n if (records) {\n // move to the end, marking this trace as most-recently-touched\n this.buffer.delete(traceId);\n this.buffer.set(traceId, records);\n } else {\n if (this.buffer.size >= this.maxTraces) {\n this.evictOldestTrace();\n }\n records = [];\n this.buffer.set(traceId, records);\n }\n\n records.push(record);\n this.bufferedCount += 1;\n\n while (this.bufferedCount > this.maxBufferedRecords && this.buffer.size > 0) {\n this.evictOldestTrace();\n }\n }\n\n private evictOldestTrace(): void {\n const oldest = this.buffer.entries().next();\n if (oldest.done) {\n return;\n }\n const [oldestKey, oldestRecords] = oldest.value;\n this.buffer.delete(oldestKey);\n this.bufferedCount -= oldestRecords.length;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nexport const GENESIS_HASH = \"0\".repeat(64);\n\nexport interface TamperEvidentPluginOptions {\n genesisHash?: string;\n}\n\n/** Deterministically stringifies a value with object keys sorted, so hashing doesn't depend on key insertion order. */\nfunction canonicalStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((entry) => canonicalStringify(entry)).join(\",\")}]`;\n }\n if (value !== null && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${canonicalStringify(entryValue)}`).join(\",\")}}`;\n }\n if (value === undefined) {\n return \"null\"; // JSON has no \"undefined\" literal; fold it the way JSON.stringify does inside arrays/objects\n }\n return JSON.stringify(value);\n}\n\nfunction computeHash(record: Pick<LogRecord, \"timestamp\" | \"level\" | \"logger\" | \"message\" | \"meta\">, prevHash: string): string {\n const restMeta = Object.fromEntries(Object.entries(record.meta).filter(([key]) => key !== \"hash\" && key !== \"prevHash\"));\n const payload = canonicalStringify({\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: restMeta,\n });\n return createHash(\"sha256\").update(`${prevHash}${payload}`).digest(\"hex\");\n}\n\n/**\n * Hash-chains every record so tampering with a written log can be\n * detected after the fact.\n *\n * Each record gets `meta.hash` — a SHA-256 hex digest over the record's\n * own content plus the previous record's hash (`meta.prevHash`) — the same\n * hash-chain construction used by tamper-evident/append-only logs: editing\n * or deleting any one line breaks every hash after it in the chain, even\n * if the tamperer edits the file directly and not through this plugin.\n * Opt-in — hashing every record has a real, measurable CPU cost, so it\n * isn't part of the default pipeline.\n *\n * Verify a previously-written log with `TamperEvidentPlugin.verifyChain`,\n * which re-derives each record's hash from its content and confirms it\n * matches both the stored `meta.hash` and the chain built from the records\n * before it, in order.\n */\nexport class TamperEvidentPlugin implements Plugin {\n private readonly genesisHash: string;\n private lastHash: string;\n\n constructor(options: TamperEvidentPluginOptions = {}) {\n this.genesisHash = options.genesisHash ?? GENESIS_HASH;\n this.lastHash = this.genesisHash;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n const prevHash = this.lastHash;\n const digest = computeHash(record, prevHash);\n const next = { ...record, meta: { ...record.meta, prevHash, hash: digest } };\n this.lastHash = digest;\n return next;\n }\n\n /**\n * Returns `true` iff every record's hash matches its content plus the\n * previous record's hash, in the given order. Returns `false` at the\n * first break in the chain (an edited, removed, or reordered record).\n */\n static verifyChain(\n records: Iterable<Pick<LogRecord, \"timestamp\" | \"level\" | \"logger\" | \"message\" | \"meta\">>,\n options: TamperEvidentPluginOptions = {},\n ): boolean {\n let prevHash = options.genesisHash ?? GENESIS_HASH;\n for (const record of records) {\n const storedHash = record.meta.hash;\n const storedPrevHash = record.meta.prevHash;\n if (typeof storedHash !== \"string\" || storedPrevHash !== prevHash) {\n return false;\n }\n if (computeHash(record, prevHash) !== storedHash) {\n return false;\n }\n prevHash = storedHash;\n }\n return true;\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"../core/levels.js\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\ninterface DedupeWindow {\n record: LogRecord;\n count: number;\n timer: ReturnType<typeof setTimeout>;\n}\n\nexport interface AlertingPluginOptions {\n /** A record at or above this level fires an alert. Default `Level.ERROR`. */\n threshold?: LevelInput;\n /** How long a dedupe window stays open before a collapsed follow-up alert (if any) fires. Default 300_000 (5 minutes). */\n dedupeWindowMs?: number;\n /** Groups records into the same dedupe window. Default: `level:logger:message`. */\n dedupeKey?: (record: LogRecord) => string;\n /** Distinct concurrent dedupe keys tracked at once; beyond this, new keys are dropped rather than tracked. Default 500. */\n maxTrackedKeys?: number;\n}\n\nfunction defaultDedupeKey(record: LogRecord): string {\n return `${record.level}:${record.logger}:${record.message}`;\n}\n\n/**\n * Base class for plugins that fire an external alert on ERROR/FATAL (or any\n * configurable `threshold`).\n *\n * A concrete subclass implements only `sendAlert(record, occurrences)` —\n * everything else (thresholding, deduplication, never blocking the caller,\n * never letting a broken destination crash logging) lives here.\n *\n * The first record at or above `threshold` for a given dedupe key (by\n * default: level + logger + message) fires `sendAlert` right away, without\n * awaiting it — so the log call that triggered it is never blocked on a\n * webhook, SMTP handshake, or any other I/O, even if the destination is\n * slow or unreachable. This stands in for the shared async dispatch queue\n * a later phase will introduce; once that queue exists, `AlertingPlugin`\n * can route through it instead of firing its own unawaited call per alert.\n *\n * Any further record matching the same dedupe key within\n * `dedupeWindowMs` of the first is *not* sent again — it just increments a\n * counter. When the window closes, if more than one record matched,\n * exactly one follow-up alert is sent with the total occurrence count,\n * instead of spamming the destination once per record. Tracking is bounded\n * to `maxTrackedKeys` distinct concurrent dedupe keys; beyond that, new\n * keys are dropped rather than tracked (alerting degrades under extreme\n * cardinality, logging itself never does).\n *\n * `sendAlert` is always called without being awaited, and any rejection is\n * routed to this plugin's own `onError`, the same as any other plugin hook\n * that throws.\n */\nexport abstract class AlertingPlugin implements Plugin {\n readonly threshold: Level;\n readonly dedupeWindowMs: number;\n readonly maxTrackedKeys: number;\n private readonly dedupeKeyFn: (record: LogRecord) => string;\n private readonly windows = new Map<string, DedupeWindow>();\n\n constructor(options: AlertingPluginOptions = {}) {\n this.threshold = parseLevel(options.threshold ?? Level.ERROR);\n this.dedupeWindowMs = options.dedupeWindowMs ?? 300_000;\n this.dedupeKeyFn = options.dedupeKey ?? defaultDedupeKey;\n this.maxTrackedKeys = options.maxTrackedKeys ?? 500;\n }\n\n afterLog(record: LogRecord): void {\n if (parseLevel(record.level) < this.threshold) {\n return;\n }\n\n const key = this.dedupeKeyFn(record);\n const existing = this.windows.get(key);\n if (existing) {\n existing.count += 1;\n return;\n }\n\n if (this.windows.size >= this.maxTrackedKeys) {\n return;\n }\n\n const timer = setTimeout(() => {\n this.flush(key);\n }, this.dedupeWindowMs);\n timer.unref();\n this.windows.set(key, { record, count: 1, timer });\n\n this.safeSend(record, 1);\n }\n\n private flush(key: string): void {\n const window = this.windows.get(key);\n this.windows.delete(key);\n if (!window || window.count <= 1) {\n return;\n }\n this.safeSend(window.record, window.count);\n }\n\n private safeSend(record: LogRecord, occurrences: number): void {\n Promise.resolve()\n .then(() => this.sendAlert(record, occurrences))\n .catch((error: unknown) => {\n try {\n this.onError?.(error, record);\n } catch {\n /* swallowed */\n }\n });\n }\n\n /**\n * Send one alert for `record`, representing `occurrences` collapsed\n * duplicates (1 on first occurrence; the deduped total on a follow-up\n * flush). Override in a concrete subclass — never call this directly,\n * `AlertingPlugin` calls it without awaiting it.\n */\n protected abstract sendAlert(record: LogRecord, occurrences: number): void | Promise<void>;\n\n onError?(error: unknown, record: LogRecord): void;\n\n /** Cancel any pending dedupe-window timers. Call on logger shutdown. */\n close(): void {\n const windows = [...this.windows.values()];\n this.windows.clear();\n for (const window of windows) {\n clearTimeout(window.timer);\n }\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** Posts one alert body to a Slack incoming webhook URL. Swap in a fake for tests. */\nexport type SlackSender = (webhookUrl: string, body: string) => Promise<void> | void;\n\nasync function fetchSlackSender(webhookUrl: string, body: string): Promise<void> {\n const response = await fetch(webhookUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n });\n if (!response.ok) {\n throw new Error(\n `SlackAlertPlugin: webhook returned HTTP ${String(response.status)} — check the webhook URL is still valid in Slack's app config`,\n );\n }\n}\n\nfunction formatMessage(record: LogRecord, occurrences: number): string {\n const suffix = occurrences > 1 ? ` (x${String(occurrences)})` : \"\";\n return `[${record.level}] ${record.logger}: ${record.message}${suffix}`;\n}\n\nexport interface SlackAlertPluginOptions extends AlertingPluginOptions {\n sender?: SlackSender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts to a Slack incoming webhook.\n *\n * `webhookUrl` is the full \"Incoming Webhook\" URL from Slack's app config.\n * Uses `fetch` — no extra dependency required. Pass `sender` to swap in a\n * fake for tests or an alternate backend.\n */\nexport class SlackAlertPlugin extends AlertingPlugin {\n readonly webhookUrl: string;\n private readonly sender: SlackSender;\n\n constructor(webhookUrl: string, options: SlackAlertPluginOptions = {}) {\n super(options);\n this.webhookUrl = webhookUrl;\n this.sender = options.sender ?? fetchSlackSender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n const body = JSON.stringify({ text: formatMessage(record, occurrences) });\n await this.sender(this.webhookUrl, body);\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nconst ENDPOINT = \"https://events.pagerduty.com/v2/enqueue\";\nconst SEVERITY: Readonly<Record<string, string>> = { ERROR: \"error\", FATAL: \"critical\" };\n\n/** POSTs one PagerDuty Events API v2 payload. Swap in a fake for tests. */\nexport type PagerDutySender = (body: string) => Promise<void> | void;\n\nasync function fetchPagerDutySender(body: string): Promise<void> {\n const response = await fetch(ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n });\n if (!response.ok) {\n throw new Error(\n `PagerDutyAlertPlugin: Events API returned HTTP ${String(response.status)} — check the routing key is a valid Events API v2 integration key`,\n );\n }\n}\n\nexport interface PagerDutyAlertPluginOptions extends AlertingPluginOptions {\n sender?: PagerDutySender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts to PagerDuty via the Events\n * API v2 (`POST https://events.pagerduty.com/v2/enqueue`).\n *\n * `routingKey` is an Events API v2 integration key from a PagerDuty\n * service. Uses `fetch` — no extra dependency required. Pass `sender` to\n * swap in a fake for tests or an alternate backend.\n */\nexport class PagerDutyAlertPlugin extends AlertingPlugin {\n readonly routingKey: string;\n private readonly sender: PagerDutySender;\n\n constructor(routingKey: string, options: PagerDutyAlertPluginOptions = {}) {\n super(options);\n this.routingKey = routingKey;\n this.sender = options.sender ?? fetchPagerDutySender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n let summary = `${record.logger}: ${record.message}`;\n if (occurrences > 1) {\n summary += ` (x${String(occurrences)})`;\n }\n const body = JSON.stringify({\n routing_key: this.routingKey,\n event_action: \"trigger\",\n payload: {\n summary,\n severity: SEVERITY[record.level] ?? \"error\",\n source: record.logger,\n timestamp: record.timestamp,\n custom_details: { occurrences, ...record.meta },\n },\n });\n await this.sender(body);\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nexport interface EmailMessage {\n from: string;\n to: string[];\n subject: string;\n text: string;\n}\n\n/** Sends one email message. Swap in a fake for tests. */\nexport type EmailSender = (message: EmailMessage) => Promise<void> | void;\n\n/** The subset of a `nodemailer` transporter that `EmailAlertPlugin` needs. */\nexport interface NodemailerTransporterLike {\n sendMail(message: { from: string; to: string; subject: string; text: string }): Promise<unknown>;\n}\n\nexport interface EmailAlertPluginOptions extends AlertingPluginOptions {\n smtpHost: string;\n smtpPort: number;\n fromAddr: string;\n toAddrs: string[];\n username?: string;\n password?: string;\n /** `false` for an SMTP server that doesn't support STARTTLS (e.g. a local relay). Default `true`. */\n useTls?: boolean;\n /** Pre-built sender, e.g. for tests. Skips the `nodemailer` auto-import entirely. */\n sender?: EmailSender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts by email over SMTP.\n *\n * `nodemailer` is an optional peer dependency: install it yourself, or\n * pass `sender` to swap in a fake for tests or an alternate backend —\n * `username`/`password` are only used if both are set.\n */\nexport class EmailAlertPlugin extends AlertingPlugin {\n readonly smtpHost: string;\n readonly smtpPort: number;\n readonly fromAddr: string;\n readonly toAddrs: string[];\n private readonly username: string | undefined;\n private readonly password: string | undefined;\n private readonly useTls: boolean;\n private readonly injectedSender: EmailSender | undefined;\n private transporter: NodemailerTransporterLike | undefined;\n\n constructor(options: EmailAlertPluginOptions) {\n super(options);\n this.smtpHost = options.smtpHost;\n this.smtpPort = options.smtpPort;\n this.fromAddr = options.fromAddr;\n this.toAddrs = options.toAddrs;\n this.username = options.username;\n this.password = options.password;\n this.useTls = options.useTls ?? true;\n this.injectedSender = options.sender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n let subject = `[${record.level}] ${record.logger}`;\n if (occurrences > 1) {\n subject += ` (x${String(occurrences)})`;\n }\n const text = [\n record.message,\n \"\",\n `occurrences: ${String(occurrences)}`,\n `timestamp: ${record.timestamp}`,\n `meta: ${JSON.stringify(record.meta)}`,\n ].join(\"\\n\");\n const message: EmailMessage = { from: this.fromAddr, to: this.toAddrs, subject, text };\n\n if (this.injectedSender) {\n await this.injectedSender(message);\n return;\n }\n\n const transporter = this.transporter ?? (await this.importTransporter());\n await transporter.sendMail({ from: message.from, to: message.to.join(\", \"), subject: message.subject, text: message.text });\n }\n\n private async importTransporter(): Promise<NodemailerTransporterLike> {\n let createTransport: (options: Record<string, unknown>) => NodemailerTransporterLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"nodemailer\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { createTransport?: (options: Record<string, unknown>) => NodemailerTransporterLike };\n createTransport?: (options: Record<string, unknown>) => NodemailerTransporterLike;\n };\n const resolved = mod.default?.createTransport ?? mod.createTransport;\n if (!resolved) {\n throw new Error(\"no createTransport export found\");\n }\n createTransport = resolved;\n } catch {\n throw new Error(\n \"EmailAlertPlugin: install `nodemailer` to use this plugin without providing a `sender` — `npm install nodemailer`\",\n );\n }\n\n this.transporter = createTransport({\n host: this.smtpHost,\n port: this.smtpPort,\n secure: false,\n requireTLS: this.useTls,\n auth: this.username && this.password ? { user: this.username, pass: this.password } : undefined,\n });\n return this.transporter;\n }\n}\n","import { JSONFormatter, type Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Sink for log records, per the cross-language transport contract:\n * `format(record) -> string`, `write(formatted, record)`, `close()` on shutdown.\n */\nexport abstract class Transport {\n formatter: Formatter;\n\n constructor(formatter: Formatter = new JSONFormatter()) {\n this.formatter = formatter;\n }\n\n format(record: LogRecord): string {\n return this.formatter.format(record);\n }\n\n abstract write(formatted: string, record: LogRecord): void;\n\n /** Flush/release resources on shutdown. No-op unless a transport overrides it. */\n close(): void {}\n}\n\n/** In-memory transport for tests: collects every (formatted, record) pair written to it. */\nexport class CollectingTransport extends Transport {\n readonly formatted: string[] = [];\n readonly records: LogRecord[] = [];\n closed = false;\n\n write(formatted: string, record: LogRecord): void {\n this.formatted.push(formatted);\n this.records.push(record);\n }\n\n override close(): void {\n this.closed = true;\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\nexport interface BatchingTransportOptions {\n formatter?: Formatter;\n /** Flush once the buffer holds this many items. Default 100. */\n maxRecords?: number;\n /** Flush once the buffer's estimated byte size reaches this many bytes. Default 1_000_000 (1MB). */\n maxBytes?: number;\n}\n\n/**\n * Shared base for every batching sink transport (SQL, NoSQL, message queues,\n * batching cloud-native transports). Buffers items and flushes once either\n * `maxRecords` or `maxBytes` is reached, so no batching transport can grow\n * its buffer unboundedly under a sustained burst.\n *\n * `write()`/`close()` stay non-blocking from the caller's perspective: a\n * failed `sendBatch()` is reported via `console.error` rather than thrown,\n * matching `HTTPTransport`'s contract.\n */\nexport abstract class BatchingTransport<T = LogRecord> extends Transport {\n readonly maxRecords: number;\n readonly maxBytes: number;\n private buffer: T[] = [];\n private bufferBytes = 0;\n\n constructor(options: BatchingTransportOptions = {}) {\n super(options.formatter);\n this.maxRecords = options.maxRecords ?? 100;\n this.maxBytes = options.maxBytes ?? 1_000_000;\n }\n\n /** Converts a written record into the buffered item type. Defaults to the record itself. */\n protected toItem(formatted: string, record: LogRecord): T {\n void formatted;\n return record as unknown as T;\n }\n\n /** Estimated byte size of one buffered item, used for the `maxBytes` bound. */\n protected sizeOf(item: T): number {\n return JSON.stringify(item).length;\n }\n\n write(formatted: string, record: LogRecord): void {\n const item = this.toItem(formatted, record);\n this.buffer.push(item);\n this.bufferBytes += this.sizeOf(item);\n if (this.buffer.length >= this.maxRecords || this.bufferBytes >= this.maxBytes) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached a bound. */\n flush(): void {\n if (this.buffer.length === 0) {\n return;\n }\n const batch = this.buffer;\n this.buffer = [];\n this.bufferBytes = 0;\n\n const result = this.sendBatch(batch);\n if (result) {\n result.catch((error: unknown) => {\n console.error(`${this.constructor.name}: failed to send log batch`, error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n\n /** Deliver one batch to the backend. Always called with a non-empty batch. */\n protected abstract sendBatch(batch: readonly T[]): Promise<void> | void;\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One row of the fixed `logs` table schema shared across every SQL transport. */\nexport interface SQLLogRow {\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n /** `record.meta`, JSON-serialized — every SQL dialect can store this as TEXT/JSON/JSONB. */\n meta: string;\n runId: string | null;\n spanId: string | null;\n parentSpanId: string | null;\n traceId: string | null;\n}\n\nexport interface BaseSQLTransportOptions extends BatchingTransportOptions {\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /**\n * Dev/test convenience only: run `createTableSQL()` before the first insert.\n * Production schema/migrations are the caller's responsibility — never\n * auto-create schema unless this is explicitly set. Default `false`.\n */\n ensureSchema?: boolean;\n}\n\nfunction metaString(meta: Record<string, unknown>, key: string): string | null {\n const value = meta[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/**\n * Abstract base for every SQL transport (`SQLiteTransport`, `PostgresTransport`,\n * `MySQLTransport`, ...). Owns the fixed schema and the record → row mapping;\n * each driver-specific subclass only implements `ensureTable()`/`insertRows()`.\n * Inserts are always batched — never one query per log call.\n */\nexport abstract class BaseSQLTransport extends BatchingTransport<SQLLogRow> {\n readonly tableName: string;\n readonly ensureSchema: boolean;\n private schemaEnsured = false;\n\n constructor(options: BaseSQLTransportOptions = {}) {\n super(options);\n this.tableName = options.tableName ?? \"logs\";\n this.ensureSchema = options.ensureSchema ?? false;\n }\n\n protected override toItem(_formatted: string, record: LogRecord): SQLLogRow {\n void _formatted;\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n runId: metaString(record.meta, \"runId\"),\n spanId: metaString(record.meta, \"spanId\"),\n parentSpanId: metaString(record.meta, \"parentSpanId\"),\n traceId: metaString(record.meta, \"traceId\"),\n };\n }\n\n protected override sizeOf(row: SQLLogRow): number {\n return row.message.length + row.meta.length + 96;\n }\n\n /**\n * Minimal, dialect-generic `CREATE TABLE IF NOT EXISTS` for dev/test use via\n * `ensureSchema: true`. Production deployments should manage this table with\n * a real migration instead — override in a subclass for dialect-correct\n * column types (e.g. `JSONB` on Postgres).\n */\n createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta TEXT NOT NULL,\n runId TEXT,\n spanId TEXT,\n parentSpanId TEXT,\n traceId TEXT\n)`;\n }\n\n protected override async sendBatch(rows: readonly SQLLogRow[]): Promise<void> {\n if (this.ensureSchema && !this.schemaEnsured) {\n // Set before awaiting: a synchronous second flush (e.g. maxRecords: 1)\n // must not re-trigger ensureTable() while the first call is in flight.\n this.schemaEnsured = true;\n await this.ensureTable();\n }\n await this.insertRows(rows);\n }\n\n /** Only invoked when `ensureSchema: true` was explicitly passed. */\n protected abstract ensureTable(): Promise<void>;\n\n /** Always-batched insert of every row in `rows` — never one query per row. */\n protected abstract insertRows(rows: readonly SQLLogRow[]): Promise<void>;\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `better-sqlite3` prepared statement that `SQLiteTransport` needs. */\nexport interface SQLiteStatementLike {\n run(...params: unknown[]): unknown;\n}\n\n/** The subset of a `better-sqlite3` `Database` that `SQLiteTransport` needs. Inject a fake in tests. */\nexport interface SQLiteClientLike {\n exec(sql: string): unknown;\n prepare(sql: string): SQLiteStatementLike;\n transaction<Args extends unknown[]>(fn: (...args: Args) => void): (...args: Args) => void;\n}\n\nexport interface SQLiteTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client, e.g. for tests. Skips the `better-sqlite3` auto-import entirely. */\n client?: SQLiteClientLike;\n /** Passed to `better-sqlite3` when no `client` is injected. Default `\":memory:\"`. */\n filename?: string;\n}\n\n/**\n * Zero-setup SQL sink — no server process, just a local (or in-memory) file\n * via `better-sqlite3`. Useful for local dev and pairs with the CLI trace\n * viewer (v2.0), which can read this file directly.\n *\n * `better-sqlite3` is an optional peer dependency: install it yourself, or\n * inject a `client` (e.g. a fake, or an already-open `Database` instance).\n */\nexport class SQLiteTransport extends BaseSQLTransport {\n private readonly injectedClient: SQLiteClientLike | undefined;\n private readonly filename: string;\n private client: SQLiteClientLike | undefined;\n\n constructor(options: SQLiteTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.filename = options.filename ?? \":memory:\";\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQLiteClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQLiteClientLike> {\n let DatabaseCtor: new (filename: string) => SQLiteClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"better-sqlite3\";\n const mod = (await import(moduleName)) as unknown as {\n default: new (filename: string) => SQLiteClientLike;\n };\n DatabaseCtor = mod.default;\n } catch {\n throw new Error(\n \"SQLiteTransport: install `better-sqlite3` to use this transport without providing a client — `npm install better-sqlite3`\",\n );\n }\n\n this.client = new DatabaseCtor(this.filename);\n return this.client;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n client.exec(this.createTableSQL());\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const stmt = client.prepare(\n `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n const insertMany = client.transaction((batch: readonly SQLLogRow[]) => {\n for (const row of batch) {\n stmt.run(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n });\n insertMany(rows);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `pg` `Pool`/`Client` that `PostgresTransport` needs. Inject a fake in tests. */\nexport interface PgClientLike {\n query(text: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface PostgresTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `pg.Pool`/`pg.Client`. Skips the `pg` auto-import entirely. */\n client?: PgClientLike;\n /** Passed to `pg.Pool` when no `client` is injected, e.g. `\"postgres://user:pass@host:5432/db\"`. */\n connectionString?: string;\n /** Passed to `pg.Pool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by Postgres via `pg`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `pg` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Pool`/`Client` instance).\n */\nexport class PostgresTransport extends BaseSQLTransport {\n private readonly injectedClient: PgClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: PgClientLike | undefined;\n\n constructor(options: PostgresTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PgClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PgClientLike> {\n let PoolCtor: new (config?: Record<string, unknown>) => PgClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"pg\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { Pool?: new (config?: Record<string, unknown>) => PgClientLike };\n Pool?: new (config?: Record<string, unknown>) => PgClientLike;\n };\n const resolved = mod.default?.Pool ?? mod.Pool;\n if (!resolved) {\n throw new Error(\"no Pool export found\");\n }\n PoolCtor = resolved;\n } catch {\n throw new Error(\n \"PostgresTransport: install `pg` to use this transport without providing a client — `npm install pg`\",\n );\n }\n\n const config = this.connectionString\n ? { connectionString: this.connectionString }\n : (this.connectionConfig ?? {});\n this.client = new PoolCtor(config);\n return this.client;\n }\n\n /** Postgres-correct `CREATE TABLE IF NOT EXISTS`: `SERIAL` primary key, `JSONB` for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id SERIAL PRIMARY KEY,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta JSONB NOT NULL,\n \"runId\" TEXT,\n \"spanId\" TEXT,\n \"parentSpanId\" TEXT,\n \"traceId\" TEXT\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.query(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n rows.forEach((row, rowIndex) => {\n const base = rowIndex * columns;\n placeholders.push(\n `(${Array.from({ length: columns }, (_, col) => `$${String(base + col + 1)}`).join(\", \")})`,\n );\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n });\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, \"runId\", \"spanId\", \"parentSpanId\", \"traceId\") VALUES ${placeholders.join(\", \")}`;\n await client.query(sql, values);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `mysql2/promise` connection/pool that `MySQLTransport` needs. Inject a fake in tests. */\nexport interface MySQLClientLike {\n execute(sql: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface MySQLTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `mysql2/promise` `Pool`/`Connection`. Skips the `mysql2` auto-import entirely. */\n client?: MySQLClientLike;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected, e.g. `\"mysql://user:pass@host:3306/db\"`. */\n connectionString?: string;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by MySQL via `mysql2`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `mysql2` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open pool/connection from\n * `mysql2/promise`).\n */\nexport class MySQLTransport extends BaseSQLTransport {\n private readonly injectedClient: MySQLClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: MySQLClientLike | undefined;\n\n constructor(options: MySQLTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): MySQLClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<MySQLClientLike> {\n let createPool: (target: string | Record<string, unknown>) => MySQLClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mysql2/promise\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { createPool?: (target: string | Record<string, unknown>) => MySQLClientLike };\n createPool?: (target: string | Record<string, unknown>) => MySQLClientLike;\n };\n const resolved = mod.default?.createPool ?? mod.createPool;\n if (!resolved) {\n throw new Error(\"no createPool export found\");\n }\n createPool = resolved;\n } catch {\n throw new Error(\n \"MySQLTransport: install `mysql2` to use this transport without providing a client — `npm install mysql2`\",\n );\n }\n\n const target = this.connectionString ?? this.connectionConfig ?? {};\n this.client = createPool(target);\n return this.client;\n }\n\n /** MySQL-correct `CREATE TABLE IF NOT EXISTS`: `AUTO_INCREMENT` primary key, `JSON` column type for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INT AUTO_INCREMENT PRIMARY KEY,\n timestamp VARCHAR(64) NOT NULL,\n level VARCHAR(16) NOT NULL,\n logger VARCHAR(255) NOT NULL,\n message TEXT NOT NULL,\n meta JSON NOT NULL,\n runId VARCHAR(255),\n spanId VARCHAR(255),\n parentSpanId VARCHAR(255),\n traceId VARCHAR(255)\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.execute(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n for (const row of rows) {\n placeholders.push(`(${Array.from({ length: columns }, () => \"?\").join(\", \")})`);\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES ${placeholders.join(\", \")}`;\n await client.execute(sql, values);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `mongodb` `Collection` that `MongoDBTransport` needs. Inject a fake in tests. */\nexport interface MongoCollectionLike {\n insertMany(docs: readonly unknown[]): Promise<unknown>;\n}\n\n/** The subset of a `mongodb` `MongoClient` that `MongoDBTransport` needs to lazily connect. */\nexport interface MongoClientLike {\n connect(): Promise<unknown>;\n db(name: string): { collection(name: string): MongoCollectionLike };\n}\n\nexport interface MongoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built collection, e.g. for tests, or an already-connected app. Skips the `mongodb` auto-import entirely. */\n collection?: MongoCollectionLike;\n /** `mongodb` connection string, used when no `collection` is injected. Required in that case. */\n connectionString?: string;\n /** Database to write into when connecting via `connectionString`. Default `\"logquill\"`. */\n database?: string;\n /** Collection to write into when connecting via `connectionString`. Default `\"logs\"`. */\n collectionName?: string;\n}\n\n/**\n * Sink for MongoDB. Records map 1:1 to documents — no JSON-in-a-column\n * workaround needed, unlike the SQL transports.\n *\n * `mongodb` is an optional peer dependency: install it yourself, or inject a\n * `collection` (e.g. a fake, or a `Collection` from a client your app already\n * manages).\n */\nexport class MongoDBTransport extends BatchingTransport {\n private readonly injectedCollection: MongoCollectionLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly database: string;\n private readonly collectionName: string;\n private collection: MongoCollectionLike | undefined;\n\n constructor(options: MongoDBTransportOptions = {}) {\n super(options);\n this.injectedCollection = options.collection;\n this.connectionString = options.connectionString;\n this.database = options.database ?? \"logquill\";\n this.collectionName = options.collectionName ?? \"logs\";\n }\n\n /** Synchronously available collection, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedCollection(): MongoCollectionLike | undefined {\n return this.injectedCollection ?? this.collection;\n }\n\n private async importCollection(): Promise<MongoCollectionLike> {\n if (!this.connectionString) {\n throw new Error(\n \"MongoDBTransport: provide either a `collection` or a `connectionString` to connect with — neither was given\",\n );\n }\n\n let MongoClientCtor: new (connectionString: string) => MongoClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mongodb\";\n const mod = (await import(moduleName)) as unknown as {\n MongoClient: new (connectionString: string) => MongoClientLike;\n };\n MongoClientCtor = mod.MongoClient;\n } catch {\n throw new Error(\n \"MongoDBTransport: install `mongodb` to use this transport without providing a client — `npm install mongodb`\",\n );\n }\n\n const client = new MongoClientCtor(this.connectionString);\n await client.connect();\n this.collection = client.db(this.database).collection(this.collectionName);\n return this.collection;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const collection = this.resolvedCollection() ?? (await this.importCollection());\n // Records already match the cross-language JSON record shape, so each one\n // becomes a document as-is — spread to give Mongo a fresh plain object per doc.\n await collection.insertMany(batch.map((record) => ({ ...record })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** DynamoDB's hard cap on items per `BatchWriteItem` call — respected by chunking within `sendBatch()`. */\nconst DYNAMO_BATCH_LIMIT = 25;\n\n/** One item written to DynamoDB: `runId` is the partition key, `timestamp` is the sort key. */\nexport interface DynamoLogItem {\n runId: string;\n timestamp: string;\n level: string;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n spanId?: string;\n parentSpanId?: string;\n traceId?: string;\n}\n\n/**\n * The subset of DynamoDB write access `DynamoDBTransport` needs, deliberately\n * narrower than the AWS SDK v3 command pattern (`send(command)`): one\n * `BatchWriteItem`-equivalent call per sub-batch, already capped at\n * `DYNAMO_BATCH_LIMIT` items by the caller. This keeps fake-based tests\n * trivial — a fake just needs to record `(tableName, items)` calls, not\n * emulate a `DynamoDBClient`. Inject a fake in tests, or rely on the built-in\n * `@aws-sdk/client-dynamodb` wrapper by not injecting a `client`.\n */\nexport interface DynamoClientLike {\n batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown>;\n}\n\nexport interface DynamoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built client, e.g. for tests, or a custom wrapper. Skips the `@aws-sdk/client-dynamodb` auto-import entirely. */\n client?: DynamoClientLike;\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /** AWS region, used when no `client` is injected. Falls back to the SDK's own credential-chain resolution when omitted. */\n region?: string;\n}\n\n/** Minimal JS -> DynamoDB `AttributeValue` marshaller for the real-SDK code path, so this transport doesn't need `@aws-sdk/util-dynamodb` as a second peer dependency just to build one request shape. */\nfunction toAttributeValue(value: unknown): Record<string, unknown> {\n if (value === null || value === undefined) {\n return { NULL: true };\n }\n if (typeof value === \"string\") {\n return { S: value };\n }\n if (typeof value === \"number\") {\n return { N: String(value) };\n }\n if (typeof value === \"boolean\") {\n return { BOOL: value };\n }\n if (typeof value === \"bigint\") {\n return { N: value.toString() };\n }\n if (Array.isArray(value)) {\n return { L: value.map((entry) => toAttributeValue(entry)) };\n }\n if (typeof value === \"object\") {\n const m: Record<string, unknown> = {};\n for (const [key, entryValue] of Object.entries(value as Record<string, unknown>)) {\n m[key] = toAttributeValue(entryValue);\n }\n return { M: m };\n }\n // Functions/symbols aren't serializable log data — drop rather than stringify unpredictably.\n return { NULL: true };\n}\n\nfunction marshallItem(item: DynamoLogItem): Record<string, unknown> {\n return toAttributeValue({ ...item }).M as Record<string, unknown>;\n}\n\n/**\n * Sink for Amazon DynamoDB. Partition key is `runId`/`traceId` (whichever is\n * present on `record.meta`, `runId` taking priority), falling back to the\n * logger name when neither is set, so every record always lands under some\n * partition even before `RunPlugin`/`TraceContextPlugin` are wired up. Sort\n * key is `timestamp`.\n *\n * DynamoDB's actual `BatchWriteItem` API caps a call at 25 items, so\n * `sendBatch()` chunks a larger batch into sub-batches of 25 — matching how\n * `SQSTransport` respects `SendMessageBatch`'s 10-item cap.\n *\n * `@aws-sdk/client-dynamodb` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a custom wrapper around a\n * `DynamoDBClient` your app already manages).\n */\nexport class DynamoDBTransport extends BatchingTransport {\n private readonly injectedClient: DynamoClientLike | undefined;\n private readonly tableName: string;\n private readonly region: string | undefined;\n private client: DynamoClientLike | undefined;\n\n constructor(options: DynamoDBTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.tableName = options.tableName ?? \"logs\";\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): DynamoClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<DynamoClientLike> {\n let DynamoDBClientCtor: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n let BatchWriteItemCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-dynamodb\";\n const mod = (await import(moduleName)) as unknown as {\n DynamoDBClient: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n BatchWriteItemCommand: new (input: unknown) => unknown;\n };\n DynamoDBClientCtor = mod.DynamoDBClient;\n BatchWriteItemCommandCtor = mod.BatchWriteItemCommand;\n } catch {\n throw new Error(\n \"DynamoDBTransport: install `@aws-sdk/client-dynamodb` to use this transport without providing a client — `npm install @aws-sdk/client-dynamodb`\",\n );\n }\n\n const sdkClient = new DynamoDBClientCtor(this.region ? { region: this.region } : {});\n this.client = {\n async batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown> {\n const requestItems = {\n [tableName]: items.map((item) => ({ PutRequest: { Item: marshallItem(item) } })),\n };\n return sdkClient.send(new BatchWriteItemCommandCtor({ RequestItems: requestItems }));\n },\n };\n return this.client;\n }\n\n /** `meta.runId`, else `meta.traceId`, else the logger name — see the class doc for why. */\n private partitionKey(record: LogRecord): string {\n const runId = record.meta.runId;\n if (typeof runId === \"string\" && runId.length > 0) {\n return runId;\n }\n const traceId = record.meta.traceId;\n if (typeof traceId === \"string\" && traceId.length > 0) {\n return traceId;\n }\n return record.logger;\n }\n\n private toDynamoItem(record: LogRecord): DynamoLogItem {\n const spanId = record.meta.spanId;\n const parentSpanId = record.meta.parentSpanId;\n const traceId = record.meta.traceId;\n return {\n runId: this.partitionKey(record),\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: record.meta,\n ...(typeof spanId === \"string\" ? { spanId } : {}),\n ...(typeof parentSpanId === \"string\" ? { parentSpanId } : {}),\n ...(typeof traceId === \"string\" ? { traceId } : {}),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const items = batch.map((record) => this.toDynamoItem(record));\n const chunks: DynamoLogItem[][] = [];\n for (let offset = 0; offset < items.length; offset += DYNAMO_BATCH_LIMIT) {\n chunks.push(items.slice(offset, offset + DYNAMO_BATCH_LIMIT));\n }\n // Dispatched concurrently rather than one-at-a-time: each sub-batch is an\n // independent BatchWriteItem call, and issuing them together (instead of\n // serially awaiting each) is both higher-throughput and keeps every call\n // in a sub-batch-sized flush starting in the same tick `sendBatch` runs.\n await Promise.all(chunks.map((chunk) => client.batchWriteItems(this.tableName, chunk)));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `redis` (node-redis v4) client that `RedisTransport` needs. Inject a fake in tests. */\nexport interface RedisClientLike {\n xAdd(stream: string, id: string, fields: Record<string, string>): Promise<unknown>;\n}\n\nexport interface RedisTransportOptions extends BatchingTransportOptions {\n /** Pre-built, already-connected client, e.g. for tests. Skips the `redis` auto-import entirely. */\n client?: RedisClientLike;\n /** `redis` connection URL, used when no `client` is injected. Default `\"redis://localhost:6379\"`. */\n url?: string;\n /** Stream key to `XADD` into. Default `\"logquill:logs\"`. */\n stream?: string;\n}\n\n/**\n * Sink for Redis, via Redis Streams (`XADD`) — as CLAUDE.md's spec puts it,\n * \"a fast local buffer, a different use case from durable storage, not a\n * replacement for the others.\" Reach for this when you want a low-latency\n * local tail (e.g. feeding a `redis-cli XREAD`-based live viewer) rather than\n * a system of record.\n *\n * Streams has no true multi-entry `XADD`, so unlike the other batching\n * transports this issues one `XADD` per record within the batch rather than\n * one network call per batch — batching here still bounds memory and reduces\n * GC/buffer churn, but it is honestly not a network-call batch the way\n * `MongoDBTransport.insertMany()` or `DynamoDBTransport`'s `BatchWriteItem`\n * chunks are.\n *\n * `redis` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-connected client your app manages).\n */\nexport class RedisTransport extends BatchingTransport {\n private readonly injectedClient: RedisClientLike | undefined;\n private readonly url: string;\n private readonly stream: string;\n private client: RedisClientLike | undefined;\n\n constructor(options: RedisTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"redis://localhost:6379\";\n this.stream = options.stream ?? \"logquill:logs\";\n }\n\n /** Synchronously available client, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): RedisClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<RedisClientLike> {\n let createClient: (options: { url: string }) => RedisClientLike & { connect(): Promise<unknown> };\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"redis\";\n const mod = (await import(moduleName)) as unknown as {\n createClient: (options: { url: string }) => RedisClientLike & { connect(): Promise<unknown> };\n };\n createClient = mod.createClient;\n } catch {\n throw new Error(\n \"RedisTransport: install `redis` to use this transport without providing a client — `npm install redis`\",\n );\n }\n\n const client = createClient({ url: this.url });\n await client.connect();\n this.client = client;\n return client;\n }\n\n private toFields(record: LogRecord): Record<string, string> {\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // One XADD per record, all issued together rather than serially awaited —\n // see the class doc for why Streams can't take a single multi-entry append.\n await Promise.all(batch.map((record) => client.xAdd(this.stream, \"*\", this.toFields(record))));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\nexport interface BaseQueueTransportOptions extends BatchingTransportOptions {\n /**\n * Destination name on the backend — a Kafka topic, a RabbitMQ queue name,\n * an SQS queue URL, or a GCP Pub/Sub topic. One generic option name so the\n * base class's orchestration stays backend-agnostic; each subclass's own\n * docs use its backend's own vocabulary for what this means.\n */\n topic: string;\n}\n\n/**\n * Abstract base for every message-queue transport (`KafkaTransport`,\n * `RabbitMQTransport`, `SQSTransport`, `PubSubTransport`). Owns the \"always\n * batch, never publish one message per log call\" contract shared across\n * every queue backend — buffering itself is inherited from\n * `BatchingTransport`; each concrete subclass only implements\n * `publishBatch()` against its own driver's publish API.\n */\nexport abstract class BaseQueueTransport extends BatchingTransport {\n readonly topic: string;\n\n constructor(options: BaseQueueTransportOptions) {\n super(options);\n this.topic = options.topic;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> {\n return this.publishBatch(batch);\n }\n\n /** Deliver one batch of records to the queue backend. Always called with a non-empty batch. */\n protected abstract publishBatch(records: readonly LogRecord[]): Promise<void>;\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `kafkajs` `Producer` that `KafkaTransport` needs. Inject a fake in tests. */\nexport interface KafkaProducerLike {\n /** Optional: some injected producers (or fakes) are already connected. */\n connect?(): Promise<void>;\n send(record: { topic: string; messages: { key: string | null; value: string }[] }): Promise<unknown>;\n}\n\nexport interface KafkaTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built producer, e.g. for tests, or an already-configured kafkajs `Producer`. Skips the `kafkajs` auto-import entirely. */\n client?: KafkaProducerLike;\n /** Broker addresses passed to `kafkajs`'s `Kafka({ brokers })` when no `client` is injected. Default `[\"localhost:9092\"]`. */\n brokers?: string[];\n}\n\nfunction metaKey(meta: Record<string, unknown>, key: string): string | undefined {\n const value = meta[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Publishes batches to a Kafka topic via `kafkajs`. Each message's `key` is\n * set to `meta.runId` (falling back to `meta.traceId`, then `null`), so\n * kafkajs's default partitioner keeps every message from the same agent\n * run/trace on one partition — preserving per-trace ordering, per the\n * message-queue contract in the project spec.\n *\n * `kafkajs` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-configured `Producer`).\n */\nexport class KafkaTransport extends BaseQueueTransport {\n private readonly injectedClient: KafkaProducerLike | undefined;\n private readonly brokers: string[];\n private client: KafkaProducerLike | undefined;\n\n constructor(options: KafkaTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.brokers = options.brokers ?? [\"localhost:9092\"];\n }\n\n /** Synchronously available producer, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): KafkaProducerLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Builds the real `kafkajs` producer and connects it. Connection happens\n * here, once, as part of acquiring the driver — not on every\n * `publishBatch()` call — so an injected `client` (tests, or a caller's\n * own already-connected producer) is trusted to already be ready and is\n * never re-connected.\n */\n private async importClient(): Promise<KafkaProducerLike> {\n let producer: KafkaProducerLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"kafkajs\";\n const mod = (await import(moduleName)) as unknown as {\n Kafka: new (config: { brokers: string[] }) => { producer(): KafkaProducerLike };\n };\n producer = new mod.Kafka({ brokers: this.brokers }).producer();\n await producer.connect?.();\n } catch {\n throw new Error(\n \"KafkaTransport: install `kafkajs` to use this transport without providing a client — `npm install kafkajs`\",\n );\n }\n\n this.client = producer;\n return producer;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.send({\n topic: this.topic,\n messages: records.map((record) => ({\n key: metaKey(record.meta, \"runId\") ?? metaKey(record.meta, \"traceId\") ?? null,\n value: JSON.stringify(record),\n })),\n });\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of an `amqplib` `Channel` that `RabbitMQTransport` needs. Inject a fake in tests. */\nexport interface AmqpChannelLike {\n /** Optional: only called once, and only when provided, to ensure the queue exists. */\n assertQueue?(queue: string, options?: unknown): Promise<unknown>;\n sendToQueue(queue: string, content: Buffer, options?: unknown): boolean;\n}\n\nexport interface RabbitMQTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built channel, e.g. for tests, or an already-open amqplib `Channel`. Skips the `amqplib` auto-import entirely. */\n client?: AmqpChannelLike;\n /** Connection URL passed to `amqplib.connect()` when no `client` is injected. Default `\"amqp://localhost\"`. */\n url?: string;\n}\n\n/**\n * Publishes batches to a RabbitMQ queue via `amqplib`. RabbitMQ's core API\n * has no native multi-message batch primitive — there is no\n * `sendToQueue`-equivalent that takes an array — so `publishBatch()` loops\n * one `sendToQueue()` call per record. The \"batch\" LogQuill promises is at\n * the buffering level: `maxRecords`/`maxBytes` still governs how often that\n * loop runs, so this transport never makes one network round trip per log\n * call; it just can't make one round trip per *batch* either, honestly,\n * since RabbitMQ itself doesn't offer that primitive.\n *\n * `amqplib` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Channel`).\n */\nexport class RabbitMQTransport extends BaseQueueTransport {\n private readonly injectedClient: AmqpChannelLike | undefined;\n private readonly url: string;\n private client: AmqpChannelLike | undefined;\n\n constructor(options: RabbitMQTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"amqp://localhost\";\n }\n\n /** Synchronously available channel, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AmqpChannelLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Opens the real `amqplib` connection/channel and asserts the queue\n * exists. Both happen here, once, as part of acquiring the driver — not on\n * every `publishBatch()` call — so an injected `client` (tests, or a\n * caller's own already-open channel) is trusted to already have its queue\n * set up and is never re-asserted.\n */\n private async importClient(): Promise<AmqpChannelLike> {\n let channel: AmqpChannelLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"amqplib\";\n const mod = (await import(moduleName)) as unknown as {\n connect(url: string): Promise<{ createChannel(): Promise<AmqpChannelLike> }>;\n };\n const connection = await mod.connect(this.url);\n channel = await connection.createChannel();\n await channel.assertQueue?.(this.topic);\n } catch {\n throw new Error(\n \"RabbitMQTransport: install `amqplib` to use this transport without providing a client — `npm install amqplib`\",\n );\n }\n\n this.client = channel;\n return channel;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n for (const record of records) {\n client.sendToQueue(this.topic, Buffer.from(JSON.stringify(record)));\n }\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** AWS's own cap on a single `SendMessageBatch` request. Never exceed it. */\nconst SQS_BATCH_LIMIT = 10;\n\n/**\n * The subset of AWS SDK v3's SQS client that `SQSTransport` needs, narrowed\n * to a plain `sendMessageBatch(queueUrl, entries)` method rather than\n * modeling the full `@aws-sdk/client-sqs` command/client pattern — simpler\n * to fake in tests, and the only shape this transport actually calls. Inject\n * a fake in tests, or wrap a real `SQSClient` to match this shape.\n */\nexport interface SQSClientLike {\n sendMessageBatch(queueUrl: string, entries: { id: string; body: string }[]): Promise<unknown>;\n}\n\nexport interface SQSTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built client, e.g. for tests, or a thin wrapper around `@aws-sdk/client-sqs`'s `SQSClient`. Skips the `@aws-sdk/client-sqs` auto-import entirely. */\n client?: SQSClientLike;\n /** AWS region passed to `@aws-sdk/client-sqs` when no `client` is injected. */\n region?: string;\n}\n\n/**\n * Publishes batches to an SQS queue via `@aws-sdk/client-sqs`'s\n * `SendMessageBatch`. That API caps a single request at 10 messages, so\n * `publishBatch()` chunks any larger batch into sub-batches of 10 —\n * LogQuill's own `maxRecords`/`maxBytes` buffering can flush more than 10\n * records at once; this transport is responsible for respecting SQS's own\n * limit underneath, per the message-queue contract in the project spec.\n *\n * `@aws-sdk/client-sqs` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a wrapped `SQSClient`).\n */\nexport class SQSTransport extends BaseQueueTransport {\n private readonly injectedClient: SQSClientLike | undefined;\n private readonly region: string | undefined;\n private client: SQSClientLike | undefined;\n\n constructor(options: SQSTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQSClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQSClientLike> {\n let client: SQSClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-sqs\";\n const mod = (await import(moduleName)) as unknown as {\n SQSClient: new (config: { region?: string | undefined }) => { send(command: unknown): Promise<unknown> };\n SendMessageBatchCommand: new (input: {\n QueueUrl: string;\n Entries: { Id: string; MessageBody: string }[];\n }) => unknown;\n };\n const sdkClient = new mod.SQSClient({ region: this.region });\n const CommandCtor = mod.SendMessageBatchCommand;\n client = {\n sendMessageBatch: (queueUrl, entries) =>\n sdkClient.send(\n new CommandCtor({\n QueueUrl: queueUrl,\n Entries: entries.map((entry) => ({ Id: entry.id, MessageBody: entry.body })),\n }),\n ),\n };\n } catch {\n throw new Error(\n \"SQSTransport: install `@aws-sdk/client-sqs` to use this transport without providing a client — `npm install @aws-sdk/client-sqs`\",\n );\n }\n\n this.client = client;\n return client;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const chunks: (readonly LogRecord[])[] = [];\n for (let start = 0; start < records.length; start += SQS_BATCH_LIMIT) {\n chunks.push(records.slice(start, start + SQS_BATCH_LIMIT));\n }\n // Fire every sub-batch's request in the same tick (via `.map`) and await\n // them together, rather than one at a time — an `await` per iteration of\n // a sequential loop would otherwise force each sub-batch onto its own\n // microtask turn for no benefit, since the requests don't depend on\n // each other.\n await Promise.all(\n chunks.map((chunk) =>\n client.sendMessageBatch(\n this.topic,\n chunk.map((record, index) => ({ id: String(index), body: JSON.stringify(record) })),\n ),\n ),\n );\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/**\n * The subset of a `@google-cloud/pubsub` `Topic` that `PubSubTransport`\n * needs. Inject a fake in tests, or an already-resolved `Topic` instance.\n */\nexport interface PubSubTopicLike {\n publishMessage(message: { data: Buffer }): Promise<string>;\n}\n\nexport interface PubSubTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built topic reference, e.g. for tests, or an already-resolved `@google-cloud/pubsub` `Topic`. Skips the `@google-cloud/pubsub` auto-import entirely. */\n client?: PubSubTopicLike;\n /** GCP project ID passed to `@google-cloud/pubsub` when no `client` is injected. */\n projectId?: string;\n}\n\n/**\n * Publishes batches to a GCP Pub/Sub topic via `@google-cloud/pubsub`. The\n * real client already does its own internal batching/flow-control underneath\n * `publishMessage()` — this transport doesn't reimplement that. What it does\n * own is LogQuill's own bounded-memory contract: `publishBatch()` only runs\n * once per buffer flush (`maxRecords`/`maxBytes`), so the driver is never\n * invoked once per individual log call.\n *\n * `@google-cloud/pubsub` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a resolved `Topic`).\n */\nexport class PubSubTransport extends BaseQueueTransport {\n private readonly injectedClient: PubSubTopicLike | undefined;\n private readonly projectId: string | undefined;\n private client: PubSubTopicLike | undefined;\n\n constructor(options: PubSubTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.projectId = options.projectId;\n }\n\n /** Synchronously available topic reference, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PubSubTopicLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PubSubTopicLike> {\n let topic: PubSubTopicLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/pubsub\";\n const mod = (await import(moduleName)) as unknown as {\n PubSub: new (config: { projectId?: string | undefined }) => { topic(name: string): PubSubTopicLike };\n };\n topic = new mod.PubSub({ projectId: this.projectId }).topic(this.topic);\n } catch {\n throw new Error(\n \"PubSubTransport: install `@google-cloud/pubsub` to use this transport without providing a client — `npm install @google-cloud/pubsub`\",\n );\n }\n\n this.client = topic;\n return topic;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // Fire every `publishMessage()` call in the same tick (via `.map`) and\n // await them together, rather than one at a time — the real client\n // already does its own internal batching/flow-control, so a sequential\n // per-record `await` here would only add unnecessary microtask turns.\n await Promise.all(records.map((record) => client.publishMessage({ data: Buffer.from(JSON.stringify(record)) })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One CloudWatch Logs event: epoch-milliseconds timestamp plus a single log line. */\nexport interface CloudWatchLogEvent {\n timestamp: number;\n message: string;\n}\n\n/**\n * The subset of the AWS SDK v3 CloudWatch Logs client that `CloudWatchTransport`\n * needs. Deliberately narrower than the SDK's full command pattern (build a\n * `PutLogEventsCommand`, `.send()` it, track the deprecated sequence-token\n * dance) — modeling just this one operation keeps the injectable-fake surface\n * small for tests; `importClient()` builds the real adapter around it.\n */\nexport interface CloudWatchClientLike {\n putLogEvents(\n logGroupName: string,\n logStreamName: string,\n events: readonly CloudWatchLogEvent[],\n ): Promise<unknown>;\n}\n\nexport interface CloudWatchTransportOptions extends BatchingTransportOptions {\n /** CloudWatch Logs log group to write into. */\n logGroupName: string;\n /** CloudWatch Logs log stream, within `logGroupName`, to write into. */\n logStreamName: string;\n /** AWS region, e.g. `\"us-east-1\"`. Passed to the real SDK client; ignored when `client` is injected. */\n region?: string;\n /** Pre-built client, e.g. for tests. Skips the `@aws-sdk/client-cloudwatch-logs` auto-import entirely. */\n client?: CloudWatchClientLike;\n}\n\ninterface AWSCloudWatchLogsClientLike {\n send(command: unknown): Promise<unknown>;\n}\n\n/**\n * Ships batched records to AWS CloudWatch Logs via the AWS SDK v3\n * (`@aws-sdk/client-cloudwatch-logs`). Each buffered record becomes one log\n * event; CloudWatch requires events within a single `PutLogEvents` call to be\n * sorted by timestamp ascending, which `sendBatch()` does before sending.\n *\n * `@aws-sdk/client-cloudwatch-logs` is an optional peer dependency: install\n * it yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `CloudWatchLogsClient` wrapped to match `CloudWatchClientLike`).\n */\nexport class CloudWatchTransport extends BatchingTransport {\n readonly logGroupName: string;\n readonly logStreamName: string;\n readonly region: string | undefined;\n private readonly injectedClient: CloudWatchClientLike | undefined;\n private client: CloudWatchClientLike | undefined;\n\n constructor(options: CloudWatchTransportOptions) {\n super(options);\n this.logGroupName = options.logGroupName;\n this.logStreamName = options.logStreamName;\n this.region = options.region;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudWatchClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudWatchClientLike> {\n let ClientCtor: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n let PutLogEventsCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-cloudwatch-logs\";\n const mod = (await import(moduleName)) as unknown as {\n CloudWatchLogsClient: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n PutLogEventsCommand: new (input: unknown) => unknown;\n };\n ClientCtor = mod.CloudWatchLogsClient;\n PutLogEventsCommandCtor = mod.PutLogEventsCommand;\n } catch {\n throw new Error(\n \"CloudWatchTransport: install `@aws-sdk/client-cloudwatch-logs` to use this transport without providing a client — `npm install @aws-sdk/client-cloudwatch-logs`\",\n );\n }\n\n const sdkClient = new ClientCtor({ region: this.region });\n this.client = {\n putLogEvents: (logGroupName, logStreamName, events) =>\n sdkClient.send(\n new PutLogEventsCommandCtor({\n logGroupName,\n logStreamName,\n logEvents: events,\n }),\n ),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const events = batch\n .map((record) => ({\n timestamp: Date.parse(record.timestamp),\n message: this.format(record),\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n await client.putLogEvents(this.logGroupName, this.logStreamName, events);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One GCP Cloud Logging entry, shaped for `Log#write`. */\nexport interface CloudLoggingEntry {\n severity: string;\n timestamp: string;\n jsonPayload: Record<string, unknown>;\n}\n\n/**\n * The subset of the `@google-cloud/logging` client that `CloudLoggingTransport`\n * needs. Deliberately narrower than the SDK's full `Log`/`Entry` object model —\n * `importClient()` builds the real adapter around `logging.log(name).write(entries)`.\n */\nexport interface CloudLoggingClientLike {\n writeLogEntries(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\nexport interface CloudLoggingTransportOptions extends BatchingTransportOptions {\n /** GCP log name (the last segment of the log resource path). Default `\"logquill\"`. */\n logName?: string;\n /** GCP project ID. Passed to the real SDK client; ignored when `client` is injected — omit to use Application Default Credentials' project. */\n projectId?: string;\n /** Pre-built client, e.g. for tests. Skips the `@google-cloud/logging` auto-import entirely. */\n client?: CloudLoggingClientLike;\n}\n\ninterface GCPLogLike {\n write(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\ninterface GCPLoggingLike {\n log(name: string): GCPLogLike;\n}\n\n/** Maps LogQuill's level names onto Cloud Logging's `LogSeverity` enum values. */\nfunction gcpSeverity(levelValue: string): string {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return \"DEBUG\";\n case Level.INFO:\n return \"INFO\";\n case Level.WARN:\n return \"WARNING\";\n case Level.ERROR:\n return \"ERROR\";\n case Level.FATAL:\n return \"CRITICAL\";\n }\n}\n\n/**\n * Ships batched records to Google Cloud Logging via `@google-cloud/logging`.\n * Each record becomes one structured entry (`jsonPayload`), with `level`\n * mapped onto Cloud Logging's `severity` enum.\n *\n * `@google-cloud/logging` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `Log` wrapped to match `CloudLoggingClientLike`).\n */\nexport class CloudLoggingTransport extends BatchingTransport {\n readonly logName: string;\n readonly projectId: string | undefined;\n private readonly injectedClient: CloudLoggingClientLike | undefined;\n private client: CloudLoggingClientLike | undefined;\n\n constructor(options: CloudLoggingTransportOptions = {}) {\n super(options);\n this.logName = options.logName ?? \"logquill\";\n this.projectId = options.projectId;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudLoggingClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudLoggingClientLike> {\n let LoggingCtor: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/logging\";\n const mod = (await import(moduleName)) as unknown as {\n Logging: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n };\n LoggingCtor = mod.Logging;\n } catch {\n throw new Error(\n \"CloudLoggingTransport: install `@google-cloud/logging` to use this transport without providing a client — `npm install @google-cloud/logging`\",\n );\n }\n\n const logging = new LoggingCtor({ projectId: this.projectId });\n const log = logging.log(this.logName);\n this.client = {\n writeLogEntries: (entries) => log.write(entries),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const entries = batch.map((record) => ({\n severity: gcpSeverity(record.level),\n timestamp: record.timestamp,\n jsonPayload: JSON.parse(this.format(record)) as Record<string, unknown>,\n }));\n await client.writeLogEntries(entries);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One Application Insights trace: a message plus its `SeverityLevel`. */\nexport interface AppInsightsTrace {\n message: string;\n severity: number;\n}\n\n/**\n * The subset of Application Insights telemetry that `AppInsightsTransport`\n * needs.\n *\n * `trackTraceBatch` is LogQuill's own batching contract, not a native\n * `applicationinsights` SDK method — the real SDK only exposes a single-record\n * `trackTrace()` plus an async `flush()`. The real-client adapter built by\n * `importClient()` loops `trackTrace()` calls inside `trackTraceBatch` and\n * flushes once at the end, so batching happens at the LogQuill buffering\n * level (bounded by `maxRecords`/`maxBytes`), not as a real network-level\n * batch call — Application Insights doesn't offer one.\n */\nexport interface AppInsightsClientLike {\n trackTraceBatch(traces: readonly AppInsightsTrace[]): Promise<unknown>;\n}\n\nexport interface AppInsightsTransportOptions extends BatchingTransportOptions {\n /** Azure Application Insights connection string. Passed to the real SDK client; ignored when `client` is injected. */\n connectionString?: string;\n /** Pre-built client, e.g. for tests. Skips the `applicationinsights` auto-import entirely. */\n client?: AppInsightsClientLike;\n}\n\ninterface AzureTelemetryClientLike {\n trackTrace(telemetry: AppInsightsTrace): void;\n flush(): void;\n}\n\n/** Maps LogQuill's level names onto Application Insights' `SeverityLevel` enum values. */\nfunction appInsightsSeverity(levelValue: string): number {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return 0; // Verbose\n case Level.INFO:\n return 1; // Information\n case Level.WARN:\n return 2; // Warning\n case Level.ERROR:\n return 3; // Error\n case Level.FATAL:\n return 4; // Critical\n }\n}\n\n/**\n * Ships batched records to Azure Application Insights via `applicationinsights`,\n * as trace telemetry with `level` mapped onto Application Insights' severity\n * scale. See `AppInsightsClientLike` for why \"batch\" means LogQuill-side\n * buffering plus a loop of single `trackTrace()` calls, not one network batch\n * request — the underlying SDK has no batch-track API.\n *\n * `applicationinsights` is an optional peer dependency: install it yourself,\n * or inject a `client` (e.g. a fake, or an already-configured `TelemetryClient`\n * wrapped to match `AppInsightsClientLike`).\n */\nexport class AppInsightsTransport extends BatchingTransport {\n readonly connectionString: string | undefined;\n private readonly injectedClient: AppInsightsClientLike | undefined;\n private client: AppInsightsClientLike | undefined;\n\n constructor(options: AppInsightsTransportOptions = {}) {\n super(options);\n this.connectionString = options.connectionString;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AppInsightsClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<AppInsightsClientLike> {\n let TelemetryClientCtor: new (connectionString?: string) => AzureTelemetryClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"applicationinsights\";\n const mod = (await import(moduleName)) as unknown as {\n TelemetryClient: new (connectionString?: string) => AzureTelemetryClientLike;\n };\n TelemetryClientCtor = mod.TelemetryClient;\n } catch {\n throw new Error(\n \"AppInsightsTransport: install `applicationinsights` to use this transport without providing a client — `npm install applicationinsights`\",\n );\n }\n\n const telemetryClient = new TelemetryClientCtor(this.connectionString);\n this.client = {\n trackTraceBatch: (traces) => {\n for (const trace of traces) {\n telemetryClient.trackTrace(trace);\n }\n telemetryClient.flush();\n return Promise.resolve();\n },\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const traces = batch.map((record) => ({\n message: this.format(record),\n severity: appInsightsSeverity(record.level),\n }));\n await client.trackTraceBatch(traces);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one batch of formatted lines to Datadog's Logs intake API at `url`. Swap in a fake for tests. */\nexport type DatadogSender = (url: string, apiKey: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchDatadogSender(url: string, apiKey: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"DD-API-KEY\": apiKey },\n body: `[${batch.join(\",\")}]`,\n });\n if (!response.ok) {\n throw new Error(\n `DatadogTransport: request to ${url} failed with status ${String(response.status)} — check the API key and site region`,\n );\n }\n}\n\nexport interface DatadogTransportOptions extends BatchingTransportOptions {\n /** Datadog API key, sent in the `DD-API-KEY` header. */\n apiKey: string;\n /**\n * Datadog site (region), e.g. `\"datadoghq.com\"` (US1, default),\n * `\"datadoghq.eu\"` (EU), `\"us3.datadoghq.com\"`, `\"us5.datadoghq.com\"`,\n * `\"ap1.datadoghq.com\"`. Never hardcode this — sending to the wrong\n * region's intake host silently fails to deliver logs to your account.\n */\n site?: string;\n sender?: DatadogSender;\n}\n\n/**\n * Batches records and POSTs them as a JSON array to Datadog's Logs intake\n * API (`https://http-intake.logs.<site>/api/v2/logs`) via `fetch`. Pass\n * `sender` to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class DatadogTransport extends BatchingTransport {\n readonly url: string;\n readonly apiKey: string;\n readonly site: string;\n private readonly sender: DatadogSender;\n\n constructor(options: DatadogTransportOptions) {\n super(options);\n this.apiKey = options.apiKey;\n this.site = options.site ?? \"datadoghq.com\";\n this.url = `https://http-intake.logs.${this.site}/api/v2/logs`;\n this.sender = options.sender ?? fetchDatadogSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const formatted = batch.map((record) => this.format(record));\n return this.sender(this.url, this.apiKey, formatted);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one pre-built NDJSON `_bulk` body to `url` with the given headers. Swap in a fake for tests. */\nexport type ElasticsearchSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n) => Promise<void> | void;\n\nasync function fetchElasticsearchSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { ...headers, \"Content-Type\": \"application/x-ndjson\" },\n body,\n });\n if (!response.ok) {\n throw new Error(`ElasticsearchTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\nexport interface ElasticsearchTransportOptions extends BatchingTransportOptions {\n /** Cluster base URL, e.g. `\"https://localhost:9200\"`. */\n node: string;\n /** Index to write into. Default `\"logs\"`. */\n index?: string;\n /** Elasticsearch API key (base64 `id:api_key`), sent as `Authorization: ApiKey <apiKey>`. Omit to send no auth header (e.g. behind a proxy that adds its own). */\n apiKey?: string;\n sender?: ElasticsearchSender;\n}\n\n/**\n * Batches records and POSTs them to Elasticsearch's `_bulk` API\n * (`<node>/_bulk`) via `fetch`, as newline-delimited action+source pairs —\n * no client dependency needed, just NDJSON body construction. Pass `sender`\n * to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class ElasticsearchTransport extends BatchingTransport {\n readonly url: string;\n readonly index: string;\n private readonly apiKey: string | undefined;\n private readonly sender: ElasticsearchSender;\n\n constructor(options: ElasticsearchTransportOptions) {\n super(options);\n this.index = options.index ?? \"logs\";\n this.url = `${options.node.replace(/\\/+$/, \"\")}/_bulk`;\n this.apiKey = options.apiKey;\n this.sender = options.sender ?? fetchElasticsearchSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const lines: string[] = [];\n for (const record of batch) {\n lines.push(JSON.stringify({ index: { _index: this.index } }));\n lines.push(this.format(record));\n }\n // The bulk API requires a trailing newline after the final action/source pair.\n const body = `${lines.join(\"\\n\")}\\n`;\n const headers: Record<string, string> = {};\n if (this.apiKey !== undefined) {\n headers.Authorization = `ApiKey ${this.apiKey}`;\n }\n return this.sender(this.url, headers, body);\n }\n}\n","import { gzipSync } from \"node:zlib\";\nimport { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Which New Relic ingest region to send to — determines the Log API host. */\nexport type NewRelicRegion = \"US\" | \"EU\";\n\n/** What `NewRelicSender` reports back about one delivery attempt, so the transport can drive its own 429 backoff logic. */\nexport interface NewRelicSenderResult {\n ok: boolean;\n status: number;\n /** The raw `Retry-After` response header value, if present — either a number of seconds or an HTTP-date, per RFC 9110. */\n retryAfter: string | null;\n}\n\n/** Sends one gzip-compressed batch to New Relic's Log API at `url`. Swap in a fake for tests. */\nexport type NewRelicSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n) => Promise<NewRelicSenderResult> | NewRelicSenderResult;\n\nasync function fetchNewRelicSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n): Promise<NewRelicSenderResult> {\n const response = await fetch(url, { method: \"POST\", headers, body });\n return {\n ok: response.ok,\n status: response.status,\n retryAfter: response.headers.get(\"retry-after\"),\n };\n}\n\n/** Returns a copy of `record` with the reserved `meta.eventType` key removed, leaving the original record untouched. */\nfunction withoutEventType(record: LogRecord): LogRecord {\n const meta = { ...record.meta };\n delete meta.eventType;\n return { ...record, meta };\n}\n\n/** Resolves a `Retry-After` header value (seconds, or an HTTP-date) to an absolute epoch-ms resume time. */\nfunction resumeTimestamp(retryAfter: string | null, now: number): number {\n if (retryAfter === null) {\n // New Relic blocks further sends for the rest of that calendar minute on\n // a rate-limit breach even when the header is missing — 60s is a safe floor.\n return now + 60_000;\n }\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n return now + seconds * 1000;\n }\n const dateMs = Date.parse(retryAfter);\n return Number.isNaN(dateMs) ? now + 60_000 : dateMs;\n}\n\nexport interface NewRelicTransportOptions extends BatchingTransportOptions {\n /** New Relic license key, sent in the `Api-Key` header. */\n licenseKey: string;\n /**\n * New Relic account region — selects the ingest host\n * (`log-api.newrelic.com` for US, `log-api.eu.newrelic.com` for EU).\n * Never hardcode this: an EU-region license key sent to the US host (or\n * vice versa) is rejected. Default `\"US\"`.\n */\n region?: NewRelicRegion;\n sender?: NewRelicSender;\n /** Injectable clock for the 429 backoff window, matching `SamplingPlugin`'s injectable `rng`. Default `Date.now`. */\n clock?: () => number;\n}\n\n/**\n * Batches records and POSTs them, gzip-compressed, to New Relic's Log API\n * (`log-api.newrelic.com` / `log-api.eu.newrelic.com`, region-configurable)\n * via `fetch`. Strips the reserved `meta.eventType` key (New Relic drops\n * records carrying it) and honors 429 responses by reading `Retry-After`\n * and pausing further sends until it elapses, rather than hammering an\n * account that's already been rate-limited for the rest of the minute.\n *\n * Pass `sender` to swap in a fake for tests, and `clock` to control time in\n * backoff tests without waiting on a real clock.\n */\nexport class NewRelicTransport extends BatchingTransport {\n readonly url: string;\n readonly region: NewRelicRegion;\n private readonly licenseKey: string;\n private readonly sender: NewRelicSender;\n private readonly clock: () => number;\n private pausedUntil: number | null = null;\n\n constructor(options: NewRelicTransportOptions) {\n super(options);\n this.licenseKey = options.licenseKey;\n this.region = options.region ?? \"US\";\n this.url =\n this.region === \"EU\" ? \"https://log-api.eu.newrelic.com/log/v1\" : \"https://log-api.newrelic.com/log/v1\";\n this.sender = options.sender ?? fetchNewRelicSender;\n this.clock = options.clock ?? Date.now;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const now = this.clock();\n if (this.pausedUntil !== null && now < this.pausedUntil) {\n console.error(\n `NewRelicTransport: sends paused until ${new Date(this.pausedUntil).toISOString()} after a 429 rate-limit response — skipping this batch rather than making a doomed request`,\n );\n return;\n }\n this.pausedUntil = null;\n\n const records = batch.map((record) => withoutEventType(record));\n const body = gzipSync(Buffer.from(JSON.stringify(records)));\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n \"Api-Key\": this.licenseKey,\n };\n\n const result = await this.sender(this.url, headers, body);\n\n if (result.status === 429) {\n this.pausedUntil = resumeTimestamp(result.retryAfter, now);\n console.error(\n `NewRelicTransport: received 429 from New Relic — pausing sends until ${new Date(this.pausedUntil).toISOString()}. Reduce log volume or increase batching to stay under the rate limit.`,\n );\n return;\n }\n\n if (!result.ok) {\n throw new Error(\n `NewRelicTransport: request to ${this.url} failed with status ${String(result.status)} — check the license key and region`,\n );\n }\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Level, parseLevel } from \"../core/levels.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\nconst COLORS: Readonly<Record<Level, string>> = {\n [Level.TRACE]: \"\\x1b[90m\", // gray\n [Level.DEBUG]: \"\\x1b[36m\", // cyan\n [Level.INFO]: \"\\x1b[32m\", // green\n [Level.WARN]: \"\\x1b[33m\", // yellow\n [Level.ERROR]: \"\\x1b[31m\", // red\n [Level.FATAL]: \"\\x1b[35m\", // magenta\n};\nconst RESET = \"\\x1b[0m\";\n\n/** The subset of `console` this transport needs — swap in a fake for tests. */\nexport interface ConsoleLike {\n log(message: string): void;\n error(message: string): void;\n}\n\nexport interface ConsoleTransportOptions {\n formatter?: Formatter;\n colorize?: boolean;\n console?: ConsoleLike;\n}\n\nfunction defaultColorize(): boolean {\n // Isomorphic guard: `process` doesn't exist in a browser bundle.\n const env: NodeJS.ProcessEnv | undefined = typeof process === \"undefined\" ? undefined : process.env;\n return env?.NO_COLOR === undefined;\n}\n\n/**\n * Writes to `console.log`, routing ERROR/FATAL to `console.error`, colorized by\n * level. Uses the global `console` rather than Node's `process.stdout`/`stderr`\n * so this transport works unmodified in a browser bundle.\n */\nexport class ConsoleTransport extends Transport {\n colorize: boolean;\n private readonly out: ConsoleLike;\n\n constructor(options: ConsoleTransportOptions = {}) {\n super(options.formatter);\n this.colorize = options.colorize ?? defaultColorize();\n this.out = options.console ?? console;\n }\n\n write(formatted: string, record: LogRecord): void {\n const level = parseLevel(record.level);\n const line = this.colorize ? this.applyColor(formatted, level) : formatted;\n if (level >= Level.ERROR) {\n this.out.error(line);\n } else {\n this.out.log(line);\n }\n }\n\n private applyColor(formatted: string, level: Level): string {\n return `${COLORS[level]}${formatted}${RESET}`;\n }\n}\n","import { closeSync, existsSync, fstatSync, mkdirSync, openSync, renameSync, unlinkSync, writeSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\nexport interface FileTransportOptions {\n formatter?: Formatter;\n maxBytes?: number;\n backupCount?: number;\n}\n\n/** Appends formatted records to a file, rotating when it exceeds `maxBytes`. */\nexport class FileTransport extends Transport {\n readonly path: string;\n readonly maxBytes: number;\n readonly backupCount: number;\n private fd: number;\n\n constructor(path: string, options: FileTransportOptions = {}) {\n super(options.formatter);\n this.path = path;\n this.maxBytes = options.maxBytes ?? 10 * 1024 * 1024;\n this.backupCount = options.backupCount ?? 5;\n mkdirSync(dirname(path), { recursive: true });\n this.fd = openSync(this.path, \"a\");\n }\n\n write(formatted: string): void {\n writeSync(this.fd, formatted + \"\\n\");\n if (this.maxBytes > 0 && fstatSync(this.fd).size >= this.maxBytes) {\n this.rotate();\n }\n }\n\n private rotate(): void {\n closeSync(this.fd);\n\n if (this.backupCount > 0) {\n for (let index = this.backupCount - 1; index > 0; index--) {\n const src = `${this.path}.${String(index)}`;\n const dst = `${this.path}.${String(index + 1)}`;\n if (existsSync(src)) {\n if (existsSync(dst)) {\n unlinkSync(dst);\n }\n renameSync(src, dst);\n }\n }\n const backup = `${this.path}.1`;\n if (existsSync(backup)) {\n unlinkSync(backup);\n }\n renameSync(this.path, backup);\n } else {\n unlinkSync(this.path);\n }\n\n this.fd = openSync(this.path, \"a\");\n }\n\n override close(): void {\n closeSync(this.fd);\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Sends one batch of formatted lines to `url`. Swap in a fake for tests. */\nexport type Sender = (url: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchSender(url: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-ndjson\" },\n body: batch.join(\"\\n\"),\n });\n if (!response.ok) {\n throw new Error(`HTTPTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\nexport interface HTTPTransportOptions {\n formatter?: Formatter;\n batchSize?: number;\n sender?: Sender;\n}\n\n/**\n * Batches formatted records and POSTs them as newline-delimited JSON via `fetch`.\n * Pass `sender` to swap in a fake for tests, or a different backend.\n */\nexport class HTTPTransport extends Transport {\n readonly url: string;\n readonly batchSize: number;\n private readonly sender: Sender;\n private batch: string[] = [];\n\n constructor(url: string, options: HTTPTransportOptions = {}) {\n super(options.formatter);\n this.url = url;\n this.batchSize = options.batchSize ?? 50;\n this.sender = options.sender ?? fetchSender;\n }\n\n write(formatted: string): void {\n this.batch.push(formatted);\n if (this.batch.length >= this.batchSize) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached `batchSize`. */\n flush(): void {\n if (this.batch.length === 0) {\n return;\n }\n const batch = this.batch;\n this.batch = [];\n\n const result = this.sender(this.url, batch);\n if (result) {\n result.catch((error: unknown) => {\n // write()/close() are non-blocking by contract, so a send failure can't\n // propagate to the caller — report it the same way a broken plugin would.\n console.error(\"HTTPTransport: failed to send log batch\", error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"./levels.js\";\nimport { FunctionPlugin, type MiddlewareFunc, type Plugin } from \"./plugin.js\";\nimport { createRecord, type LogRecord } from \"./records.js\";\nimport type { Transport } from \"../transports/transport.js\";\n\nexport interface LoggerOptions {\n level?: LevelInput;\n transports?: Transport[];\n plugins?: (Plugin | MiddlewareFunc)[];\n meta?: Record<string, unknown>;\n}\n\nexport class Logger {\n readonly name: string;\n readonly transports: Transport[];\n readonly plugins: Plugin[];\n private currentLevel: Level;\n private readonly baseMeta: Record<string, unknown>;\n\n constructor(name: string, options: LoggerOptions = {}) {\n this.name = name;\n this.currentLevel = parseLevel(options.level ?? Level.INFO);\n this.transports = options.transports ? [...options.transports] : [];\n this.plugins = [];\n for (const plugin of options.plugins ?? []) {\n this.use(plugin);\n }\n this.baseMeta = options.meta ? { ...options.meta } : {};\n }\n\n get level(): Level {\n return this.currentLevel;\n }\n\n setLevel(level: LevelInput): void {\n this.currentLevel = parseLevel(level);\n }\n\n /**\n * Register a plugin, or a plain `beforeLog`-style function. A function is\n * wrapped internally as an anonymous `Plugin` (`FunctionPlugin`) — the\n * same middleware ergonomics as Express/Koa, without needing to read the\n * `Plugin` interface first. Returns `this` so calls can be chained.\n */\n use(plugin: Plugin | MiddlewareFunc): this {\n this.plugins.push(typeof plugin === \"function\" ? new FunctionPlugin(plugin) : plugin);\n return this;\n }\n\n /** Close every attached transport. Call on shutdown to flush buffered writes. */\n close(): void {\n for (const transport of this.transports) {\n transport.close();\n }\n }\n\n /** A logger scoped under this one, inheriting its level, transports, and plugins. */\n child(name: string, meta: Record<string, unknown> = {}): Logger {\n return new Logger(`${this.name}.${name}`, {\n level: this.currentLevel,\n transports: this.transports,\n plugins: this.plugins,\n meta: { ...this.baseMeta, ...meta },\n });\n }\n\n private notifyError(plugin: Plugin, error: unknown, record: LogRecord): void {\n // a broken error handler must not crash logging either\n try {\n plugin.onError?.(error, record);\n } catch {\n /* swallowed */\n }\n }\n\n private dispatch(level: Level, message: string, meta: Record<string, unknown>): LogRecord | null {\n if (level < this.currentLevel) {\n return null;\n }\n\n let record = createRecord({\n level,\n logger: this.name,\n message,\n meta: { ...this.baseMeta, ...meta },\n });\n\n for (const plugin of this.plugins) {\n let result: LogRecord | null;\n try {\n result = plugin.beforeLog ? plugin.beforeLog(record) : record;\n } catch (error) {\n this.notifyError(plugin, error, record);\n continue;\n }\n if (result === null) {\n return null;\n }\n record = result;\n }\n\n for (const transport of this.transports) {\n transport.write(transport.format(record), record);\n }\n\n for (const plugin of this.plugins) {\n try {\n plugin.afterLog?.(record);\n } catch (error) {\n this.notifyError(plugin, error, record);\n }\n }\n\n return record;\n }\n\n trace(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.TRACE, message, meta);\n }\n\n debug(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.DEBUG, message, meta);\n }\n\n info(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, meta);\n }\n\n warn(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.WARN, message, meta);\n }\n\n error(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.ERROR, message, meta);\n }\n\n fatal(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.FATAL, message, meta);\n }\n}\n","export { Level, levelName, parseLevel } from \"./core/levels.js\";\nexport type { LevelInput } from \"./core/levels.js\";\n\nexport { createRecord, utcTimestamp } from \"./core/records.js\";\nexport type { LogRecord } from \"./core/records.js\";\n\nexport { JSONFormatter } from \"./core/formatter.js\";\nexport type { Formatter } from \"./core/formatter.js\";\n\nexport type { Plugin, MiddlewareFunc } from \"./core/plugin.js\";\nexport { FunctionPlugin } from \"./core/plugin.js\";\n\nexport { ContextPlugin } from \"./plugins/context-plugin.js\";\n\nexport { DEFAULT_REDACTED_KEYS, RedactPlugin } from \"./plugins/redact-plugin.js\";\nexport type { RedactPluginOptions } from \"./plugins/redact-plugin.js\";\n\nexport { DEFAULT_PII_PATTERNS, PIIRedactPlugin } from \"./plugins/pii-redact-plugin.js\";\nexport type { PIIRedactPluginOptions } from \"./plugins/pii-redact-plugin.js\";\n\nexport { SamplingPlugin } from \"./plugins/sampling-plugin.js\";\nexport type { SamplingPluginOptions } from \"./plugins/sampling-plugin.js\";\n\nexport { GENESIS_HASH, TamperEvidentPlugin } from \"./plugins/tamper-evident-plugin.js\";\nexport type { TamperEvidentPluginOptions } from \"./plugins/tamper-evident-plugin.js\";\n\nexport { AlertingPlugin } from \"./plugins/alerting-plugin.js\";\nexport type { AlertingPluginOptions } from \"./plugins/alerting-plugin.js\";\n\nexport { SlackAlertPlugin } from \"./plugins/slack-alert-plugin.js\";\nexport type { SlackAlertPluginOptions, SlackSender } from \"./plugins/slack-alert-plugin.js\";\n\nexport { PagerDutyAlertPlugin } from \"./plugins/pagerduty-alert-plugin.js\";\nexport type { PagerDutyAlertPluginOptions, PagerDutySender } from \"./plugins/pagerduty-alert-plugin.js\";\n\nexport { EmailAlertPlugin } from \"./plugins/email-alert-plugin.js\";\nexport type {\n EmailAlertPluginOptions,\n EmailMessage,\n EmailSender,\n NodemailerTransporterLike,\n} from \"./plugins/email-alert-plugin.js\";\n\nexport { CollectingTransport, Transport } from \"./transports/transport.js\";\n\nexport { BatchingTransport } from \"./transports/batching-transport.js\";\nexport type { BatchingTransportOptions } from \"./transports/batching-transport.js\";\n\nexport { BaseSQLTransport } from \"./transports/sql/base-sql-transport.js\";\nexport type { BaseSQLTransportOptions, SQLLogRow } from \"./transports/sql/base-sql-transport.js\";\n\nexport { SQLiteTransport } from \"./transports/sql/sqlite-transport.js\";\nexport type {\n SQLiteClientLike,\n SQLiteStatementLike,\n SQLiteTransportOptions,\n} from \"./transports/sql/sqlite-transport.js\";\n\nexport { PostgresTransport } from \"./transports/sql/postgres-transport.js\";\nexport type { PgClientLike, PostgresTransportOptions } from \"./transports/sql/postgres-transport.js\";\n\nexport { MySQLTransport } from \"./transports/sql/mysql-transport.js\";\nexport type { MySQLClientLike, MySQLTransportOptions } from \"./transports/sql/mysql-transport.js\";\n\nexport { MongoDBTransport } from \"./transports/nosql/mongodb-transport.js\";\nexport type {\n MongoClientLike,\n MongoCollectionLike,\n MongoDBTransportOptions,\n} from \"./transports/nosql/mongodb-transport.js\";\n\nexport { DynamoDBTransport } from \"./transports/nosql/dynamodb-transport.js\";\nexport type {\n DynamoClientLike,\n DynamoLogItem,\n DynamoDBTransportOptions,\n} from \"./transports/nosql/dynamodb-transport.js\";\n\nexport { RedisTransport } from \"./transports/nosql/redis-transport.js\";\nexport type { RedisClientLike, RedisTransportOptions } from \"./transports/nosql/redis-transport.js\";\n\nexport { BaseQueueTransport } from \"./transports/queue/base-queue-transport.js\";\nexport type { BaseQueueTransportOptions } from \"./transports/queue/base-queue-transport.js\";\n\nexport { KafkaTransport } from \"./transports/queue/kafka-transport.js\";\nexport type { KafkaProducerLike, KafkaTransportOptions } from \"./transports/queue/kafka-transport.js\";\n\nexport { RabbitMQTransport } from \"./transports/queue/rabbitmq-transport.js\";\nexport type { AmqpChannelLike, RabbitMQTransportOptions } from \"./transports/queue/rabbitmq-transport.js\";\n\nexport { SQSTransport } from \"./transports/queue/sqs-transport.js\";\nexport type { SQSClientLike, SQSTransportOptions } from \"./transports/queue/sqs-transport.js\";\n\nexport { PubSubTransport } from \"./transports/queue/pubsub-transport.js\";\nexport type { PubSubTopicLike, PubSubTransportOptions } from \"./transports/queue/pubsub-transport.js\";\n\nexport { CloudWatchTransport } from \"./transports/cloud/cloudwatch-transport.js\";\nexport type {\n CloudWatchClientLike,\n CloudWatchLogEvent,\n CloudWatchTransportOptions,\n} from \"./transports/cloud/cloudwatch-transport.js\";\n\nexport { CloudLoggingTransport } from \"./transports/cloud/cloud-logging-transport.js\";\nexport type {\n CloudLoggingClientLike,\n CloudLoggingEntry,\n CloudLoggingTransportOptions,\n} from \"./transports/cloud/cloud-logging-transport.js\";\n\nexport { AppInsightsTransport } from \"./transports/cloud/app-insights-transport.js\";\nexport type {\n AppInsightsClientLike,\n AppInsightsTrace,\n AppInsightsTransportOptions,\n} from \"./transports/cloud/app-insights-transport.js\";\n\nexport { DatadogTransport } from \"./transports/cloud/datadog-transport.js\";\nexport type { DatadogSender, DatadogTransportOptions } from \"./transports/cloud/datadog-transport.js\";\n\nexport { ElasticsearchTransport } from \"./transports/cloud/elasticsearch-transport.js\";\nexport type {\n ElasticsearchSender,\n ElasticsearchTransportOptions,\n} from \"./transports/cloud/elasticsearch-transport.js\";\n\nexport { NewRelicTransport } from \"./transports/cloud/new-relic-transport.js\";\nexport type {\n NewRelicRegion,\n NewRelicSender,\n NewRelicSenderResult,\n NewRelicTransportOptions,\n} from \"./transports/cloud/new-relic-transport.js\";\n\nexport { ConsoleTransport } from \"./transports/console-transport.js\";\nexport type { ConsoleLike, ConsoleTransportOptions } from \"./transports/console-transport.js\";\n\nexport { FileTransport } from \"./transports/file-transport.js\";\nexport type { FileTransportOptions } from \"./transports/file-transport.js\";\n\nexport { HTTPTransport } from \"./transports/http-transport.js\";\nexport type { HTTPTransportOptions, Sender } from \"./transports/http-transport.js\";\n\nexport { Logger } from \"./core/logger.js\";\nexport type { LoggerOptions } from \"./core/logger.js\";\n\nexport const VERSION = \"0.3.0\";\n"]}
1
+ {"version":3,"sources":["../src/core/levels.ts","../src/core/records.ts","../src/core/formatter.ts","../src/core/plugin.ts","../src/plugins/context-plugin.ts","../src/core/context.ts","../src/plugins/rate-limit-plugin.ts","../src/bridges/level-dispatch.ts","../src/bridges/pino-destination.ts","../src/plugins/run-plugin.ts","../src/plugins/trace-context-plugin.ts","../src/plugins/otel-span-processor.ts","../src/plugins/redact-plugin.ts","../src/plugins/pii-redact-plugin.ts","../src/plugins/sampling-plugin.ts","../src/plugins/tamper-evident-plugin.ts","../src/plugins/alerting-plugin.ts","../src/plugins/slack-alert-plugin.ts","../src/plugins/pagerduty-alert-plugin.ts","../src/plugins/email-alert-plugin.ts","../src/transports/transport.ts","../src/transports/batching-transport.ts","../src/transports/sql/base-sql-transport.ts","../src/transports/sql/sqlite-transport.ts","../src/transports/sql/postgres-transport.ts","../src/transports/sql/mysql-transport.ts","../src/transports/nosql/mongodb-transport.ts","../src/transports/nosql/dynamodb-transport.ts","../src/transports/nosql/redis-transport.ts","../src/transports/queue/base-queue-transport.ts","../src/transports/queue/kafka-transport.ts","../src/transports/queue/rabbitmq-transport.ts","../src/transports/queue/sqs-transport.ts","../src/transports/queue/pubsub-transport.ts","../src/transports/cloud/cloudwatch-transport.ts","../src/transports/cloud/cloud-logging-transport.ts","../src/transports/cloud/app-insights-transport.ts","../src/transports/cloud/datadog-transport.ts","../src/transports/cloud/elasticsearch-transport.ts","../src/transports/cloud/new-relic-transport.ts","../src/transports/console-transport.ts","../src/transports/beacon-transport.ts","../src/transports/file-transport.ts","../src/transports/http-transport.ts","../src/core/dispatch-queue.ts","../src/core/span.ts","../src/core/logger.ts","../src/core/serverless.ts","../src/core/shutdown.ts","../src/index.ts"],"names":["Level","AsyncLocalStorage","require","randomBytes"],"mappings":";;;;;;;;AACO,IAAK,KAAA,qBAAAA,MAAAA,KAAL;AAEL,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,CAAA,CAAA,GAAR,OAAA;AAEA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AAEA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,UAAO,EAAA,CAAA,GAAP,MAAA;AAEA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,UAAO,EAAA,CAAA,GAAP,MAAA;AAEA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AAEA,EAAAA,MAAAA,CAAAA,MAAAA,CAAA,WAAQ,EAAA,CAAA,GAAR,OAAA;AAZU,EAAA,OAAAA,MAAAA;AAAA,CAAA,EAAA,KAAA,IAAA,EAAA;AAeZ,IAAM,aAAA,GAAiD;AAAA,EACrD,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO,EAAA;AAAA,EACP,IAAA,EAAM,EAAA;AAAA,EACN,IAAA,EAAM,EAAA;AAAA,EACN,KAAA,EAAO,EAAA;AAAA,EACP,KAAA,EAAO,EAAA;AACT,CAAA;AAMO,SAAS,UAAU,KAAA,EAAsB;AAC9C,EAAA,OAAO,MAAM,KAAK,CAAA;AACpB;AAGO,SAAS,WAAW,KAAA,EAA0B;AACnD,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,MAAA,GAAS,aAAA,CAAc,KAAA,CAAM,WAAA,EAAa,CAAA;AAChD,IAAA,IAAI,WAAW,MAAA,EAAW;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,KAAA,CAAM,KAAK,CAAA,KAAM,MAAA,EAAW;AAC9B,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,KAAA;AACT;;;AC7BO,SAAS,YAAA,GAAuB;AACrC,EAAA,OAAA,iBAAO,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAChC;AAGO,SAAS,aAAa,MAAA,EAKf;AACZ,EAAA,OAAO;AAAA,IACL,WAAW,YAAA,EAAa;AAAA,IACxB,KAAA,EAAO,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA;AAAA,IAC7B,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,MAAM,MAAA,CAAO;AAAA,GACf;AACF;;;AC1BO,IAAM,gBAAN,MAAyC;AAAA;AAAA,EAE9C,OAAO,MAAA,EAA2B;AAChC,IAAA,OAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAAA,EAC9B;AACF;;;ACcO,IAAM,iBAAN,MAAuC;AAAA,EAC3B,IAAA;AAAA,EAEjB,YAAY,IAAA,EAAsB;AAChC,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AAAA,EAEA,UAAU,MAAA,EAAqC;AAC7C,IAAA,OAAO,IAAA,CAAK,KAAK,MAAM,CAAA;AAAA,EACzB;AACF;;;AC/BO,IAAM,gBAAN,MAAsC;AAAA;AAAA,EAElC,OAAA;AAAA,EAET,YAAY,OAAA,EAAkC;AAC5C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAM,EAAE,GAAG,IAAA,CAAK,OAAA,EAAS,GAAG,MAAA,CAAO,IAAA,EAAK,EAAE;AAAA,EAChE;AACF;AChBA,IAAM,YAAA,GAAe,IAAI,iBAAA,EAA2C;AAS7D,SAAS,cAAA,GAA0C;AACxD,EAAA,OAAO,YAAA,CAAa,QAAA,EAAS,IAAK,EAAC;AACrC;AAqBO,SAAS,WAAA,CAAe,QAAiC,EAAA,EAAgB;AAC9E,EAAA,OAAO,YAAA,CAAa,IAAI,EAAE,GAAG,gBAAe,EAAG,GAAG,MAAA,EAAO,EAAG,EAAE,CAAA;AAChE;;;AC9BA,SAAS,WAAW,MAAA,EAA2B;AAC7C,EAAA,OAAO,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,OAAO,KAAK,CAAA,CAAA;AACzC;AAoCO,IAAM,kBAAN,MAAwC;AAAA;AAAA,EAEpC,UAAA;AAAA;AAAA,EAEA,UAAA;AAAA;AAAA,EAEA,OAAA;AAAA,EACQ,OAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA,uBAAc,GAAA,EAAqB;AAAA,EAEpD,WAAA,CAAY,UAAA,EAAoB,UAAA,EAAoB,OAAA,GAAkC,EAAC,EAAG;AACxF,IAAA,IAAI,aAAa,CAAA,EAAG;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mCAAA,EAAsC,MAAA,CAAO,UAAU,CAAC,CAAA,CAAE,CAAA;AAAA,IAC5E;AACA,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoC,MAAA,CAAO,UAAU,CAAC,CAAA,CAAE,CAAA;AAAA,IAC1E;AACA,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AAClC,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,GAAA;AAClC,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA,KAAU,MAAM,WAAA,CAAY,KAAI,GAAI,GAAA,CAAA;AAAA,EAC3D;AAAA,EAEA,UAAU,MAAA,EAAqC;AAC7C,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,EAAM;AACvB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAEnC,IAAA,IAAI,WAAW,MAAA,IAAa,GAAA,GAAM,MAAA,CAAO,KAAA,IAAS,KAAK,UAAA,EAAY;AACjE,MAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AACvB,MAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,GAAA,EAAK,EAAE,OAAO,GAAA,EAAK,KAAA,EAAO,GAAG,CAAA;AAC9C,MAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,IAAA,GAAO,IAAA,CAAK,OAAA,EAAS;AACvC,QAAA,IAAA,CAAK,WAAA,EAAY;AAAA,MACnB;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAGA,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AACvB,IAAA,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,MAAM,CAAA;AAE5B,IAAA,IAAI,MAAA,CAAO,KAAA,IAAS,IAAA,CAAK,UAAA,EAAY;AACnC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAA,CAAO,KAAA,IAAS,CAAA;AAChB,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,WAAA,GAAoB;AAC1B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,IAAA,GAAO,IAAA,EAAK;AACxC,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,MAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAAA,IAClC;AAAA,EACF;AACF;;;ACjGO,SAAS,WAAA,CACd,GAAA,EACA,KAAA,EACA,OAAA,EACA,IAAA,EACM;AACN,EAAA,QAAQ,KAAA;AAAO,IACb,KAAA,CAAA;AACE,MAAA,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AACvB,MAAA;AAAA,IACF,KAAA,EAAA;AACE,MAAA,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AACvB,MAAA;AAAA,IACF,KAAA,EAAA;AACE,MAAA,GAAA,CAAI,IAAA,CAAK,SAAS,IAAI,CAAA;AACtB,MAAA;AAAA,IACF,KAAA,EAAA;AACE,MAAA,GAAA,CAAI,IAAA,CAAK,SAAS,IAAI,CAAA;AACtB,MAAA;AAAA,IACF,KAAA,EAAA;AACE,MAAA,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AACvB,MAAA;AAAA,IACF,KAAA,EAAA;AACE,MAAA,GAAA,CAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AACvB,MAAA;AAAA;AAEN;;;ACtBO,IAAM,sBAAA,GAAuC;AAAA,EAClD,EAAA,EAAA,CAAA;AAAA,EACA,EAAA,EAAA,EAAA;AAAA,EACA,EAAA,EAAA,EAAA;AAAA,EACA,EAAA,EAAA,EAAA;AAAA,EACA,EAAA,EAAA,EAAA;AAAA,EACA,EAAA,EAAA,EAAA;AACF;AAoCO,IAAM,0BAAN,MAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS1B,QAAA,GAAW,IAAA;AAAA,EAEH,MAAA;AAAA,EACA,QAAA;AAAA,EAEjB,WAAA,CAAY,cAAA,EAAwB,OAAA,GAA0C,EAAC,EAAG;AAChF,IAAA,IAAA,CAAK,MAAA,GAAS,cAAA;AACd,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,sBAAA;AAAA,EACtC;AAAA;AAAA,EAGA,MAAM,KAAA,EAAwB;AAC5B,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,EAAG;AACpC,MAAA,IAAI,IAAA,CAAK,MAAK,EAAG;AACf,QAAA,IAAA,CAAK,UAAU,IAAI,CAAA;AAAA,MACrB;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,UAAU,IAAA,EAAoB;AACpC,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IAC1B,CAAA,CAAA,MAAQ;AACN,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,IAAA,EAAM;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,MAAA;AACd,IAAA,MAAM,YAAY,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,GAAW,MAAM,KAAA,GAAQ,EAAA;AAClE,IAAA,MAAM,UAAU,OAAO,KAAA,CAAM,GAAA,KAAQ,QAAA,GAAW,MAAM,GAAA,GAAM,EAAA;AAE5D,IAAA,MAAM,OAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAG;AACpC,MAAA,IAAI,GAAA,KAAQ,OAAA,IAAW,GAAA,KAAQ,KAAA,EAAO;AACpC,QAAA,IAAA,CAAK,GAAG,CAAA,GAAI,KAAA,CAAM,GAAG,CAAA;AAAA,MACvB;AAAA,IACF;AAEA,IAAA,WAAA,CAAY,KAAK,MAAA,EAAQ,IAAA,CAAK,SAAS,SAAS,CAAA,IAAA,EAAA,aAAiB,SAAS,IAAI,CAAA;AAAA,EAChF;AACF;AC3EO,IAAM,YAAN,MAAkC;AAAA;AAAA,EAE9B,KAAA;AAAA,EACD,IAAA,GAAO,CAAA;AAAA,EAEf,WAAA,CAAY,OAAA,GAA4B,EAAC,EAAG;AAC1C,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,UAAA,EAAW;AAAA,EAC3C;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,MAAA,CAAO,IAAA,CAAK,UAAU,IAAA,CAAK,KAAA;AAC3B,IAAA,MAAA,CAAO,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA,EAAA;AACxB,IAAA,OAAO,MAAA;AAAA,EACT;AACF;ACrCA,IAAM,gBAAA,GAAmB,IAAIC,iBAAAA,EAAsC;AAW5D,SAAS,eAAe,KAAA,EAAuC;AACpE,EAAA,MAAM,QAAA,GAAW,iBAAiB,QAAA,EAAS;AAC3C,EAAA,gBAAA,CAAiB,UAAU,KAAK,CAAA;AAChC,EAAA,OAAO,MAAM;AACX,IAAA,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AAAA,EACrC,CAAA;AACF;AAGO,SAAS,cAAA,GAAqC;AACnD,EAAA,OAAO,iBAAiB,QAAA,EAAS;AACnC;AAGO,SAAS,eAAA,GAA0B;AACxC,EAAA,OAAO,WAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA;AACvC;AAIA,IAAM,kBAAA,GAAqB,uDAAA;AAE3B,IAAM,YAAA,GAAe,qCAAA;AAErB,IAAM,YAAA,GAAe,+BAAA;AAOd,SAAS,iBAAiB,MAAA,EAAoC;AACnE,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAE5B,EAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,IAAA,CAAK,OAAO,CAAA;AAC3C,EAAA,IAAI,GAAA,GAAM,CAAC,CAAA,EAAG;AACZ,IAAA,OAAO,IAAI,CAAC,CAAA;AAAA,EACd;AAEA,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACtC,EAAA,IAAI,IAAA,GAAO,CAAC,CAAA,IAAK,IAAA,CAAK,CAAC,CAAA,EAAG;AACxB,IAAA,OAAO,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA;AAAA,EACzB;AAEA,EAAA,MAAM,GAAA,GAAM,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACrC,EAAA,IAAI,GAAA,GAAM,CAAC,CAAA,EAAG;AACZ,IAAA,OAAO,IAAI,CAAC,CAAA;AAAA,EACd;AAEA,EAAA,OAAO,MAAA;AACT;AA0BO,SAAS,+BAAA,GAAsD;AACpE,EAAA,IAAI;AACF,IAAA,MAAMC,QAAAA,GAAU,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC7C,IAAA,MAAM,IAAA,GAAOA,SAAQ,oBAAoB,CAAA;AACzC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,aAAA,EAAc;AACtC,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AACA,IAAA,MAAM,WAAA,GAAc,KAAK,WAAA,EAAY;AACrC,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,kBAAA,CAAmB,WAAW,CAAA,EAAG;AAC/C,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AACA,IAAA,OAAO,WAAA,CAAY,OAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAkCO,IAAM,qBAAN,MAA2C;AAAA;AAAA,EAEvC,QAAA;AAAA,EACQ,mBAAA;AAAA,EACA,wBAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAAqC,EAAC,EAAG;AACnD,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,SAAA;AACpC,IAAA,IAAA,CAAK,sBAAsB,OAAA,CAAQ,WAAA;AACnC,IAAA,IAAA,CAAK,wBAAA,GAA2B,QAAQ,wBAAA,IAA4B,+BAAA;AAAA,EACtE;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,KAAK,IAAA,EAAM;AACtC,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,GAAI,KAAK,cAAA,EAAe;AACjD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,cAAA,GAAyB;AAC/B,IAAA,MAAM,QAAA,GAAW,KAAK,wBAAA,EAAyB;AAC/C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,mBAAA,IAAuB,cAAA,EAAe;AAC1D,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,MAAA,GAAS,iBAAiB,MAAM,CAAA;AACtC,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAO,eAAA,EAAgB;AAAA,EACzB;AACF;;;ACzIA,IAAM,sBAAA,GAAyB,CAAA;AAuCxB,IAAM,oBAAN,MAAwB;AAAA,EACZ,GAAA;AAAA,EACA,aAAA;AAAA,EAEjB,WAAA,CAAY,GAAA,EAAa,OAAA,GAAoC,EAAC,EAAG;AAC/D,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,aAAA,GAAgB,QAAQ,aAAA,IAAiB,YAAA;AAAA,EAChD;AAAA;AAAA,EAGA,QAAQ,IAAA,EAA0B;AAChC,IAAA,IAAA,CAAK,IAAI,MAAA,CAAO,IAAA,CAAK,MAAM,IAAA,CAAK,QAAA,CAAS,IAAI,CAAC,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,IAAA,EAA0B;AAC9B,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,GAAG,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA;AAAA,MACrB,UAAA,EAAY,KAAK,QAAA,CAAS,CAAC,IAAI,GAAA,GAAO,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,GAAI;AAAA,KAC3D;AACA,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,KAAS,sBAAA,EAAwB;AAC/C,MAAA,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,IAAA,CAAK,IAAA,EAAM;AAAA,QACxB,GAAG,IAAA;AAAA,QACH,KAAA,EAAO,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW;AAAA,OAC/B,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,GAAA,CAAI,WAAA,CAAY,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AAAA,EACtC;AAAA;AAAA,EAGA,MAAM,UAAA,GAA4B;AAAA,EAAC;AAAA;AAAA,EAGnC,MAAM,QAAA,GAA0B;AAAA,EAAC;AAAA,EAEzB,SAAS,IAAA,EAA6C;AAC5D,IAAA,MAAM,OAAgC,EAAE,MAAA,EAAQ,IAAA,CAAK,WAAA,GAAc,MAAA,EAAO;AAC1E,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,iBAAA,EAAmB,MAAA,IAAU,IAAA,CAAK,YAAA;AAC5D,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AAAA,IACtB;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA,CAAE,SAAS,CAAA,EAAG;AAC3C,MAAA,IAAA,CAAK,IAAA,CAAK,aAAa,CAAA,GAAI,IAAA,CAAK,UAAA;AAAA,IAClC;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC5HO,IAAM,wBAA2C,CAAC,UAAA,EAAY,OAAA,EAAS,QAAA,EAAU,WAAW,eAAe;AAW3G,IAAM,eAAN,MAAqC;AAAA,EACzB,IAAA;AAAA;AAAA,EAER,WAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAA+B,EAAC,EAAG;AAC7C,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,GAAA,CAAA,CAAK,OAAA,CAAQ,IAAA,IAAQ,qBAAA,EAAuB,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,WAAA,EAAa,CAAC,CAAA;AAC3F,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,KAAA;AAAA,EAC5C;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,MAAM,OAAgC,EAAC;AACvC,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,CAAA,EAAG;AACtD,MAAA,IAAA,CAAK,GAAG,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,IAAI,WAAA,EAAa,CAAA,GAAI,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,IACpE;AACA,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAK;AAAA,EAC3B;AACF;;;ACvBO,IAAM,oBAAA,GAAyD;AAAA,EACpE,KAAA,EAAO,qDAAA;AAAA,EACP,GAAA,EAAK,wBAAA;AAAA,EACL,UAAA,EAAY,yBAAA;AAAA,EACZ,KAAA,EAAO;AACT;AAEA,IAAM,SAAA,GAAY,EAAA;AA8BX,IAAM,kBAAN,MAAwC;AAAA;AAAA,EAEpC,QAAA;AAAA;AAAA,EAEA,WAAA;AAAA,EAET,WAAA,CAAY,OAAA,GAAkC,EAAC,EAAG;AAChD,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,oBAAA;AACpC,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,KAAA;AAAA,EAC5C;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,IAAA,kBAAM,IAAI,GAAA,EAAI,EAAG,CAAC,CAAA,EAA6B;AAAA,EACnG;AAAA,EAEQ,WAAA,CAAY,KAAA,EAAgB,IAAA,EAA4B,KAAA,EAAwB;AACtF,IAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,OAAO,IAAA,CAAK,WAAW,KAAK,CAAA;AAAA,IAC9B;AACA,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AACnB,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,WAAW,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,IAAI,KAAK,CAAA;AACxC,MAAA,OAAO,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,IAAA,CAAK,YAAY,KAAA,EAAO,QAAA,EAAU,KAAA,GAAQ,CAAC,CAAC,CAAA;AAAA,IAC1E;AACA,IAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,EAAG;AACnB,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,MAAM,WAAW,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,IAAI,KAAK,CAAA;AACxC,MAAA,MAAM,SAAkC,EAAC;AACzC,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AACrD,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,IAAA,CAAK,YAAY,UAAA,EAAY,QAAA,EAAU,QAAQ,CAAC,CAAA;AAAA,MAChE;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,WAAW,IAAA,EAAsB;AACvC,IAAA,IAAI,QAAA,GAAW,IAAA;AACf,IAAA,KAAA,MAAW,OAAA,IAAW,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,EAAG;AAKlD,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,GAAS,OAAA,GAAU,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,EAAG,OAAA,CAAQ,KAAK,CAAA,CAAA,CAAG,CAAA;AACxF,MAAA,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,IAAA,CAAK,WAAW,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AACF;;;AClDO,IAAM,iBAAN,MAAuC;AAAA;AAAA,EAEnC,IAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,SAAA;AAAA;AAAA,EAEA,UAAA;AAAA;AAAA,EAEA,kBAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EACQ,GAAA;AAAA,EACA,MAAA,uBAAa,GAAA,EAA0B;AAAA,EAChD,aAAA,GAAgB,CAAA;AAAA,EACP,QAAA,uBAAe,GAAA,EAAa;AAAA,EAE7C,WAAA,CAAY,IAAA,EAAc,OAAA,GAAiC,EAAC,EAAG;AAC7D,IAAA,IAAI,IAAA,GAAO,CAAA,IAAK,IAAA,GAAO,CAAA,EAAG;AACxB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,MAAA,CAAO,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACrE;AACA,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,IAAA,CAAK,MAAA;AAC/B,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,SAAA;AACpC,IAAA,IAAA,CAAK,SAAA,GAAY,UAAA,CAAW,OAAA,CAAQ,SAAA,IAAA,EAAA,aAAwB;AAC5D,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,kBAAA,GAAqB,QAAQ,kBAAA,IAAsB,GAAA;AACxD,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,GAAA;AAAA,EACxC;AAAA,EAEA,UAAU,MAAA,EAAqC;AAC7C,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,IAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,MAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA,CAAK,OAAO,MAAA,GAAS,IAAA;AAAA,IAC3C;AAEA,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAEzC,IAAA,IAAI,YAAY,MAAA,IAAa,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,OAAO,CAAA,EAAG;AACvD,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA,CAAK,IAAA;AAC/B,IAAA,MAAM,mBAAA,GAAsB,UAAA,CAAW,MAAA,CAAO,KAAK,KAAK,IAAA,CAAK,SAAA;AAE7D,IAAA,IAAI,OAAA,KAAY,UAAa,mBAAA,EAAqB;AAChD,MAAA,IAAA,CAAK,OAAA,CAAQ,SAAS,UAAU,CAAA;AAChC,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,YAAY,MAAA,EAAW;AACzB,MAAA,IAAA,CAAK,YAAA,CAAa,SAAS,MAAM,CAAA;AAAA,IACnC;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEQ,OAAA,CAAQ,SAAkB,UAAA,EAA+B;AAC/D,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,OAAO,CAAA;AACzB,IAAA,MAAM,WAAW,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAO,KAAK,EAAC;AAC9C,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,OAAO,CAAA;AAC1B,IAAA,IAAA,CAAK,iBAAiB,QAAA,CAAS,MAAA;AAC/B,IAAA,KAAA,MAAW,kBAAkB,QAAA,EAAU;AACrC,MAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,QAAA,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,cAAc,GAAG,cAAc,CAAA;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAA,CAAa,SAAkB,MAAA,EAAyB;AAC9D,IAAA,IAAI,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA;AACrC,IAAA,IAAI,OAAA,EAAS;AAEX,MAAA,IAAA,CAAK,MAAA,CAAO,OAAO,OAAO,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAAA,IAClC,CAAA,MAAO;AACL,MAAA,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,IAAQ,IAAA,CAAK,SAAA,EAAW;AACtC,QAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,MACxB;AACA,MAAA,OAAA,GAAU,EAAC;AACX,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,OAAA,EAAS,OAAO,CAAA;AAAA,IAClC;AAEA,IAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AACnB,IAAA,IAAA,CAAK,aAAA,IAAiB,CAAA;AAEtB,IAAA,OAAO,KAAK,aAAA,GAAgB,IAAA,CAAK,sBAAsB,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,EAAG;AAC3E,MAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,IAAA,EAAK;AAC1C,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAC,SAAA,EAAW,aAAa,CAAA,GAAI,MAAA,CAAO,KAAA;AAC1C,IAAA,IAAA,CAAK,MAAA,CAAO,OAAO,SAAS,CAAA;AAC5B,IAAA,IAAA,CAAK,iBAAiB,aAAA,CAAc,MAAA;AAAA,EACtC;AACF;ACvJO,IAAM,YAAA,GAAe,GAAA,CAAI,MAAA,CAAO,EAAE;AASzC,SAAS,mBAAmB,KAAA,EAAwB;AAClD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,EACtE;AACA,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC/C,IAAA,MAAM,UAAU,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,CAAA,GAAI,CAAA,GAAI,KAAK,CAAA,GAAI,CAAA,GAAI,IAAI,CAAE,CAAA;AAChH,IAAA,OAAO,CAAA,CAAA,EAAI,QAAQ,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,UAAU,MAAM,CAAA,EAAG,IAAA,CAAK,UAAU,GAAG,CAAC,IAAI,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,EACrH;AACA,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAC7B;AAEA,SAAS,WAAA,CAAY,QAAgF,QAAA,EAA0B;AAC7H,EAAA,MAAM,WAAW,MAAA,CAAO,WAAA,CAAY,MAAA,CAAO,OAAA,CAAQ,OAAO,IAAI,CAAA,CAAE,MAAA,CAAO,CAAC,CAAC,GAAG,CAAA,KAAM,QAAQ,MAAA,IAAU,GAAA,KAAQ,UAAU,CAAC,CAAA;AACvH,EAAA,MAAM,UAAU,kBAAA,CAAmB;AAAA,IACjC,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,IAAA,EAAM;AAAA,GACP,CAAA;AACD,EAAA,OAAO,UAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,OAAO,CAAA,CAAE,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAC1E;AAmBO,IAAM,sBAAN,MAA4C;AAAA,EAChC,WAAA;AAAA,EACT,QAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAsC,EAAC,EAAG;AACpD,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,YAAA;AAC1C,IAAA,IAAA,CAAK,WAAW,IAAA,CAAK,WAAA;AAAA,EACvB;AAAA,EAEA,UAAU,MAAA,EAA8B;AACtC,IAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,MAAA,EAAQ,QAAQ,CAAA;AAC3C,IAAA,MAAM,IAAA,GAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAM,EAAE,GAAG,MAAA,CAAO,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,MAAA,EAAO,EAAE;AAC3E,IAAA,IAAA,CAAK,QAAA,GAAW,MAAA;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,WAAA,CACL,OAAA,EACA,OAAA,GAAsC,EAAC,EAC9B;AACT,IAAA,IAAI,QAAA,GAAW,QAAQ,WAAA,IAAe,YAAA;AACtC,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAM,UAAA,GAAa,OAAO,IAAA,CAAK,IAAA;AAC/B,MAAA,MAAM,cAAA,GAAiB,OAAO,IAAA,CAAK,QAAA;AACnC,MAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,cAAA,KAAmB,QAAA,EAAU;AACjE,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IAAI,WAAA,CAAY,MAAA,EAAQ,QAAQ,CAAA,KAAM,UAAA,EAAY;AAChD,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,QAAA,GAAW,UAAA;AAAA,IACb;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;AC3EA,SAAS,iBAAiB,MAAA,EAA2B;AACnD,EAAA,OAAO,CAAA,EAAG,OAAO,KAAK,CAAA,CAAA,EAAI,OAAO,MAAM,CAAA,CAAA,EAAI,OAAO,OAAO,CAAA,CAAA;AAC3D;AAgCO,IAAe,iBAAf,MAAgD;AAAA;AAAA,EAE5C,SAAA;AAAA;AAAA,EAEA,cAAA;AAAA;AAAA,EAEA,cAAA;AAAA,EACQ,WAAA;AAAA,EACA,OAAA,uBAAc,GAAA,EAA0B;AAAA,EAEzD,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,IAAA,CAAK,SAAA,GAAY,UAAA,CAAW,OAAA,CAAQ,SAAA,IAAA,EAAA,aAAwB;AAC5D,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAChD,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,SAAA,IAAa,gBAAA;AACxC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAAA,EAClD;AAAA,EAEA,SAAS,MAAA,EAAyB;AAChC,IAAA,IAAI,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA,GAAI,KAAK,SAAA,EAAW;AAC7C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AACnC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACrC,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,QAAA,CAAS,KAAA,IAAS,CAAA;AAClB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,IAAA,IAAQ,IAAA,CAAK,cAAA,EAAgB;AAC5C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,MAAA,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,IAChB,CAAA,EAAG,KAAK,cAAc,CAAA;AACtB,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,GAAA,EAAK,EAAE,QAAQ,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA;AAEjD,IAAA,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,EACzB;AAAA,EAEQ,MAAM,GAAA,EAAmB;AAC/B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AACnC,IAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,GAAG,CAAA;AACvB,IAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,KAAA,IAAS,CAAA,EAAG;AAChC,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,KAAK,CAAA;AAAA,EAC3C;AAAA,EAEQ,QAAA,CAAS,QAAmB,WAAA,EAA2B;AAC7D,IAAA,OAAA,CAAQ,OAAA,EAAQ,CACb,IAAA,CAAK,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,WAAW,CAAC,CAAA,CAC9C,KAAA,CAAM,CAAC,KAAA,KAAmB;AACzB,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,OAAA,GAAU,OAAO,MAAM,CAAA;AAAA,MAC9B,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA;AAAA,EACL;AAAA;AAAA,EAaA,KAAA,GAAc;AACZ,IAAA,MAAM,UAAU,CAAC,GAAG,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AACzC,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,YAAA,CAAa,OAAO,KAAK,CAAA;AAAA,IAC3B;AAAA,EACF;AACF;;;ACnIA,eAAe,gBAAA,CAAiB,YAAoB,IAAA,EAA6B;AAC/E,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,UAAA,EAAY;AAAA,IACvC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,IAC9C;AAAA,GACD,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,wCAAA,EAA2C,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,kEAAA;AAAA,KACpE;AAAA,EACF;AACF;AAEA,SAAS,aAAA,CAAc,QAAmB,WAAA,EAA6B;AACrE,EAAA,MAAM,SAAS,WAAA,GAAc,CAAA,GAAI,MAAM,MAAA,CAAO,WAAW,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AAChE,EAAA,OAAO,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,CAAA,EAAA,EAAK,MAAA,CAAO,MAAM,CAAA,EAAA,EAAK,MAAA,CAAO,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA;AACvE;AAeO,IAAM,gBAAA,GAAN,cAA+B,cAAA,CAAe;AAAA;AAAA,EAE1C,UAAA;AAAA,EACQ,MAAA;AAAA,EAEjB,WAAA,CAAY,UAAA,EAAoB,OAAA,GAAmC,EAAC,EAAG;AACrE,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,gBAAA;AAAA,EAClC;AAAA,EAEA,MAAgB,SAAA,CAAU,MAAA,EAAmB,WAAA,EAAoC;AAC/E,IAAA,MAAM,IAAA,GAAO,KAAK,SAAA,CAAU,EAAE,MAAM,aAAA,CAAc,MAAA,EAAQ,WAAW,CAAA,EAAG,CAAA;AACxE,IAAA,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,UAAA,EAAY,IAAI,CAAA;AAAA,EACzC;AACF;;;ACjDA,IAAM,QAAA,GAAW,yCAAA;AACjB,IAAM,QAAA,GAA6C,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,UAAA,EAAW;AAKvF,eAAe,qBAAqB,IAAA,EAA6B;AAC/D,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,QAAA,EAAU;AAAA,IACrC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,IAC9C;AAAA,GACD,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,+CAAA,EAAkD,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,sEAAA;AAAA,KAC3E;AAAA,EACF;AACF;AAgBO,IAAM,oBAAA,GAAN,cAAmC,cAAA,CAAe;AAAA;AAAA,EAE9C,UAAA;AAAA,EACQ,MAAA;AAAA,EAEjB,WAAA,CAAY,UAAA,EAAoB,OAAA,GAAuC,EAAC,EAAG;AACzE,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,oBAAA;AAAA,EAClC;AAAA,EAEA,MAAgB,SAAA,CAAU,MAAA,EAAmB,WAAA,EAAoC;AAC/E,IAAA,IAAI,UAAU,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA,EAAA,EAAK,OAAO,OAAO,CAAA,CAAA;AACjD,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,OAAA,IAAW,CAAA,GAAA,EAAM,MAAA,CAAO,WAAW,CAAC,CAAA,CAAA,CAAA;AAAA,IACtC;AACA,IAAA,MAAM,IAAA,GAAO,KAAK,SAAA,CAAU;AAAA,MAC1B,aAAa,IAAA,CAAK,UAAA;AAAA,MAClB,YAAA,EAAc,SAAA;AAAA,MACd,OAAA,EAAS;AAAA,QACP,OAAA;AAAA,QACA,QAAA,EAAU,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA,IAAK,OAAA;AAAA,QACpC,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,WAAW,MAAA,CAAO,SAAA;AAAA,QAClB,cAAA,EAAgB,EAAE,WAAA,EAAa,GAAG,OAAO,IAAA;AAAK;AAChD,KACD,CAAA;AACD,IAAA,MAAM,IAAA,CAAK,OAAO,IAAI,CAAA;AAAA,EACxB;AACF;;;ACdO,IAAM,gBAAA,GAAN,cAA+B,cAAA,CAAe;AAAA;AAAA,EAE1C,QAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,OAAA;AAAA,EACQ,QAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACT,WAAA;AAAA,EAER,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,OAAA;AACvB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,QAAA;AACxB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AAChC,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA,EAEA,MAAgB,SAAA,CAAU,MAAA,EAAmB,WAAA,EAAoC;AAC/E,IAAA,IAAI,UAAU,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,CAAA,EAAA,EAAK,OAAO,MAAM,CAAA,CAAA;AAChD,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,OAAA,IAAW,CAAA,GAAA,EAAM,MAAA,CAAO,WAAW,CAAC,CAAA,CAAA,CAAA;AAAA,IACtC;AACA,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,MAAA,CAAO,OAAA;AAAA,MACP,EAAA;AAAA,MACA,CAAA,aAAA,EAAgB,MAAA,CAAO,WAAW,CAAC,CAAA,CAAA;AAAA,MACnC,CAAA,WAAA,EAAc,OAAO,SAAS,CAAA,CAAA;AAAA,MAC9B,CAAA,MAAA,EAAS,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,KACtC,CAAE,KAAK,IAAI,CAAA;AACX,IAAA,MAAM,OAAA,GAAwB,EAAE,IAAA,EAAM,IAAA,CAAK,UAAU,EAAA,EAAI,IAAA,CAAK,OAAA,EAAS,OAAA,EAAS,IAAA,EAAK;AAErF,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,MAAM,IAAA,CAAK,eAAe,OAAO,CAAA;AACjC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,WAAA,GAAc,IAAA,CAAK,WAAA,IAAgB,MAAM,KAAK,iBAAA,EAAkB;AACtE,IAAA,MAAM,YAAY,QAAA,CAAS,EAAE,MAAM,OAAA,CAAQ,IAAA,EAAM,IAAI,OAAA,CAAQ,EAAA,CAAG,IAAA,CAAK,IAAI,GAAG,OAAA,EAAS,OAAA,CAAQ,SAAS,IAAA,EAAM,OAAA,CAAQ,MAAM,CAAA;AAAA,EAC5H;AAAA,EAEA,MAAc,iBAAA,GAAwD;AACpE,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,YAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,EAAS,eAAA,IAAmB,GAAA,CAAI,eAAA;AACrD,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,MACnD;AACA,MAAA,eAAA,GAAkB,QAAA;AAAA,IACpB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,cAAc,eAAA,CAAgB;AAAA,MACjC,MAAM,IAAA,CAAK,QAAA;AAAA,MACX,MAAM,IAAA,CAAK,QAAA;AAAA,MACX,MAAA,EAAQ,KAAA;AAAA,MACR,YAAY,IAAA,CAAK,MAAA;AAAA,MACjB,IAAA,EAAM,IAAA,CAAK,QAAA,IAAY,IAAA,CAAK,QAAA,GAAW,EAAE,IAAA,EAAM,IAAA,CAAK,QAAA,EAAU,IAAA,EAAM,IAAA,CAAK,QAAA,EAAS,GAAI;AAAA,KACvF,CAAA;AACD,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AACF;;;AC5HO,IAAe,YAAf,MAAyB;AAAA;AAAA,EAE9B,SAAA;AAAA,EAEA,WAAA,CAAY,SAAA,GAAuB,IAAI,aAAA,EAAc,EAAG;AACtD,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AAAA;AAAA,EAGA,OAAO,MAAA,EAA2B;AAChC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,MAAM,CAAA;AAAA,EACrC;AAAA;AAAA,EAMA,KAAA,GAAc;AAAA,EAAC;AACjB;AASO,SAAS,SAAS,SAAA,EAAmE;AAC1F,EAAA,OAAO,OAAQ,UAA0C,KAAA,KAAU,UAAA;AACrE;AAGO,IAAM,mBAAA,GAAN,cAAkC,SAAA,CAAU;AAAA;AAAA,EAExC,YAAsB,EAAC;AAAA;AAAA,EAEvB,UAAuB,EAAC;AAAA;AAAA,EAEjC,MAAA,GAAS,KAAA;AAAA,EAET,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,SAAS,CAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,EAC1B;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AAAA,EAChB;AACF;;;AC/BO,IAAe,iBAAA,GAAf,cAAwD,SAAA,CAAU;AAAA;AAAA,EAE9D,UAAA;AAAA;AAAA,EAEA,QAAA;AAAA,EACD,SAAc,EAAC;AAAA,EACf,WAAA,GAAc,CAAA;AAAA,EAEtB,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,GAAA;AACxC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,GAAA;AAAA,EACtC;AAAA;AAAA,EAGU,MAAA,CAAO,WAAmB,MAAA,EAAsB;AAExD,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA,EAGU,OAAO,IAAA,EAAiB;AAChC,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,CAAE,MAAA;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,EAAW,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,IAAI,CAAA;AACrB,IAAA,IAAA,CAAK,WAAA,IAAe,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,MAAA,IAAU,IAAA,CAAK,cAAc,IAAA,CAAK,WAAA,IAAe,KAAK,QAAA,EAAU;AAC9E,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC5B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,SAAS,EAAC;AACf,IAAA,IAAA,CAAK,WAAA,GAAc,CAAA;AAEnB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AACnC,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,KAAmB;AAC/B,QAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,IAAA,CAAK,WAAA,CAAY,IAAI,8BAA8B,KAAK,CAAA;AAAA,MAC3E,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AAIF;;;AC7CA,SAAS,UAAA,CAAW,MAA+B,GAAA,EAA4B;AAC7E,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAG,CAAA;AACtB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,IAAA;AAC7C;AAQO,IAAe,gBAAA,GAAf,cAAwC,iBAAA,CAA6B;AAAA;AAAA,EAEjE,SAAA;AAAA;AAAA,EAEA,YAAA;AAAA,EACD,aAAA,GAAgB,KAAA;AAAA,EAExB,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,MAAA;AACtC,IAAA,IAAA,CAAK,YAAA,GAAe,QAAQ,YAAA,IAAgB,KAAA;AAAA,EAC9C;AAAA,EAEmB,MAAA,CAAO,YAAoB,MAAA,EAA8B;AAE1E,IAAA,OAAO;AAAA,MACL,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AAAA,MAChC,KAAA,EAAO,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,OAAO,CAAA;AAAA,MACtC,MAAA,EAAQ,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,QAAQ,CAAA;AAAA,MACxC,YAAA,EAAc,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,cAAc,CAAA;AAAA,MACpD,OAAA,EAAS,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,SAAS;AAAA,KAC5C;AAAA,EACF;AAAA,EAEmB,OAAO,GAAA,EAAwB;AAChD,IAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAA,GAAS,GAAA,CAAI,KAAK,MAAA,GAAS,EAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAA,GAAyB;AACvB,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAyB,UAAU,IAAA,EAA2C;AAC5E,IAAA,IAAI,IAAA,CAAK,YAAA,IAAgB,CAAC,IAAA,CAAK,aAAA,EAAe;AAG5C,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,MAAA,MAAM,KAAK,WAAA,EAAY;AAAA,IACzB;AACA,IAAA,MAAM,IAAA,CAAK,WAAW,IAAI,CAAA;AAAA,EAC5B;AAOF;;;ACnFO,IAAM,eAAA,GAAN,cAA8B,gBAAA,CAAiB;AAAA,EACnC,cAAA;AAAA,EACA,QAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAkC,EAAC,EAAG;AAChD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,UAAA;AAAA,EACtC;AAAA;AAAA,EAGQ,cAAA,GAA+C;AACrD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA0C;AACtD,IAAA,IAAI,YAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,gBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,YAAA,GAAe,GAAA,CAAI,OAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,CAAa,IAAA,CAAK,QAAQ,CAAA;AAC5C,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,CAAA;AAAA,EACnC;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,MAAA,CAAO,OAAA;AAAA,MAClB,CAAA,YAAA,EAAe,KAAK,SAAS,CAAA,mHAAA;AAAA,KAC/B;AACA,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,WAAA,CAAY,CAAC,KAAA,KAAgC;AACrE,MAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,QAAA,IAAA,CAAK,GAAA;AAAA,UACH,GAAA,CAAI,SAAA;AAAA,UACJ,GAAA,CAAI,KAAA;AAAA,UACJ,GAAA,CAAI,MAAA;AAAA,UACJ,GAAA,CAAI,OAAA;AAAA,UACJ,GAAA,CAAI,IAAA;AAAA,UACJ,GAAA,CAAI,KAAA;AAAA,UACJ,GAAA,CAAI,MAAA;AAAA,UACJ,GAAA,CAAI,YAAA;AAAA,UACJ,GAAA,CAAI;AAAA,SACN;AAAA,MACF;AAAA,IACF,CAAC,CAAA;AACD,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB;AACF;;;ACvEO,IAAM,iBAAA,GAAN,cAAgC,gBAAA,CAAiB;AAAA,EACrC,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA2C;AACjD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAsC;AAClD,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,IAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,EAAS,IAAA,IAAQ,GAAA,CAAI,IAAA;AAC1C,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,sBAAsB,CAAA;AAAA,MACxC;AACA,MAAA,QAAA,GAAW,QAAA;AAAA,IACb,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,GAChB,EAAE,gBAAA,EAAkB,KAAK,gBAAA,EAAiB,GACzC,IAAA,CAAK,gBAAA,IAAoB,EAAC;AAC/B,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,QAAA,CAAS,MAAM,CAAA;AACjC,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGS,cAAA,GAAyB;AAChC,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA,CAAK,cAAA,EAAe,EAAG,EAAE,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,CAAA;AAChB,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,EAAK,QAAA,KAAa;AAC9B,MAAA,MAAM,OAAO,QAAA,GAAW,OAAA;AACxB,MAAA,YAAA,CAAa,IAAA;AAAA,QACX,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,EAAE,QAAQ,OAAA,EAAQ,EAAG,CAAC,CAAA,EAAG,GAAA,KAAQ,IAAI,MAAA,CAAO,IAAA,GAAO,MAAM,CAAC,CAAC,EAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,OAC1F;AACA,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,GAAA,CAAI,SAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,OAAA;AAAA,QACJ,GAAA,CAAI,IAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,YAAA;AAAA,QACJ,GAAA,CAAI;AAAA,OACN;AAAA,IACF,CAAC,CAAA;AAED,IAAA,MAAM,GAAA,GAAM,eAAe,IAAA,CAAK,SAAS,mGAAmG,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AACnK,IAAA,MAAM,MAAA,CAAO,KAAA,CAAM,GAAA,EAAK,MAAM,CAAA;AAAA,EAChC;AACF;;;AC5FO,IAAM,cAAA,GAAN,cAA6B,gBAAA,CAAiB;AAAA,EAClC,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,gBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,OAAA,EAAS,UAAA,IAAc,GAAA,CAAI,UAAA;AAChD,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC9C;AACA,MAAA,UAAA,GAAa,QAAA;AAAA,IACf,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,IAAoB,IAAA,CAAK,oBAAoB,EAAC;AAClE,IAAA,IAAA,CAAK,MAAA,GAAS,WAAW,MAAM,CAAA;AAC/B,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGS,cAAA,GAAyB;AAChC,IAAA,OAAO,CAAA,2BAAA,EAA8B,KAAK,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA;AAAA,EAYrD;AAAA,EAEA,MAAgB,WAAA,GAA6B;AAC3C,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,OAAA,CAAQ,IAAA,CAAK,cAAA,EAAe,EAAG,EAAE,CAAA;AAAA,EAChD;AAAA,EAEA,MAAgB,WAAW,IAAA,EAA2C;AACpE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,CAAA;AAChB,IAAA,MAAM,SAAoB,EAAC;AAC3B,IAAA,MAAM,eAAyB,EAAC;AAChC,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,YAAA,CAAa,IAAA,CAAK,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAA,EAAQ,EAAG,MAAM,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAC9E,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,GAAA,CAAI,SAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,OAAA;AAAA,QACJ,GAAA,CAAI,IAAA;AAAA,QACJ,GAAA,CAAI,KAAA;AAAA,QACJ,GAAA,CAAI,MAAA;AAAA,QACJ,GAAA,CAAI,YAAA;AAAA,QACJ,GAAA,CAAI;AAAA,OACN;AAAA,IACF;AAEA,IAAA,MAAM,GAAA,GAAM,eAAe,IAAA,CAAK,SAAS,2FAA2F,YAAA,CAAa,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAC3J,IAAA,MAAM,MAAA,CAAO,OAAA,CAAQ,GAAA,EAAK,MAAM,CAAA;AAAA,EAClC;AACF;;;AC1EO,IAAM,gBAAA,GAAN,cAA+B,iBAAA,CAAkB;AAAA,EACrC,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACT,UAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,qBAAqB,OAAA,CAAQ,UAAA;AAClC,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,UAAA;AACpC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,MAAA;AAAA,EAClD;AAAA;AAAA,EAGQ,kBAAA,GAAsD;AAC5D,IAAA,OAAO,IAAA,CAAK,sBAAsB,IAAA,CAAK,UAAA;AAAA,EACzC;AAAA,EAEA,MAAc,gBAAA,GAAiD;AAC7D,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC1B,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,eAAA,GAAkB,GAAA,CAAI,WAAA;AAAA,IACxB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,IAAA,CAAK,gBAAgB,CAAA;AACxD,IAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,OAAO,EAAA,CAAG,IAAA,CAAK,QAAQ,CAAA,CAAE,UAAA,CAAW,KAAK,cAAc,CAAA;AACzE,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,aAAa,IAAA,CAAK,kBAAA,EAAmB,IAAM,MAAM,KAAK,gBAAA,EAAiB;AAG7E,IAAA,MAAM,UAAA,CAAW,UAAA,CAAW,KAAA,CAAM,GAAA,CAAI,CAAC,YAAY,EAAE,GAAG,MAAA,EAAO,CAAE,CAAC,CAAA;AAAA,EACpE;AACF;;;AC1FA,IAAM,kBAAA,GAAqB,EAAA;AAiD3B,SAAS,iBAAiB,KAAA,EAAyC;AACjE,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AACzC,IAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AAAA,EACtB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,GAAG,KAAA,EAAM;AAAA,EACpB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,EAAE;AAAA,EAC5B;AACA,EAAA,IAAI,OAAO,UAAU,SAAA,EAAW;AAC9B,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,EAAE,CAAA,EAAG,KAAA,CAAM,QAAA,EAAS,EAAE;AAAA,EAC/B;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,IAAA,OAAO,EAAE,GAAG,KAAA,CAAM,GAAA,CAAI,CAAC,KAAA,KAAU,gBAAA,CAAiB,KAAK,CAAC,CAAA,EAAE;AAAA,EAC5D;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,IAA6B,EAAC;AACpC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,UAAU,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AAChF,MAAA,CAAA,CAAE,GAAG,CAAA,GAAI,gBAAA,CAAiB,UAAU,CAAA;AAAA,IACtC;AACA,IAAA,OAAO,EAAE,GAAG,CAAA,EAAE;AAAA,EAChB;AAEA,EAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AACtB;AAEA,SAAS,aAAa,IAAA,EAA8C;AAClE,EAAA,OAAO,gBAAA,CAAiB,EAAE,GAAG,IAAA,EAAM,CAAA,CAAE,CAAA;AACvC;AAiBO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA,EACtC,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAoC,EAAC,EAAG;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,MAAA;AACtC,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AAAA;AAAA,EAGQ,cAAA,GAA+C;AACrD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA0C;AACtD,IAAA,IAAI,kBAAA;AACJ,IAAA,IAAI,yBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,0BAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,kBAAA,GAAqB,GAAA,CAAI,cAAA;AACzB,MAAA,yBAAA,GAA4B,GAAA,CAAI,qBAAA;AAAA,IAClC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,IAAI,kBAAA,CAAmB,IAAA,CAAK,MAAA,GAAS,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO,GAAI,EAAE,CAAA;AACnF,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,MAAM,eAAA,CAAgB,SAAA,EAAmB,KAAA,EAAmD;AAC1F,QAAA,MAAM,YAAA,GAAe;AAAA,UACnB,CAAC,SAAS,GAAG,KAAA,CAAM,IAAI,CAAC,IAAA,MAAU,EAAE,UAAA,EAAY,EAAE,IAAA,EAAM,YAAA,CAAa,IAAI,CAAA,IAAI,CAAE;AAAA,SACjF;AACA,QAAA,OAAO,SAAA,CAAU,KAAK,IAAI,yBAAA,CAA0B,EAAE,YAAA,EAAc,YAAA,EAAc,CAAC,CAAA;AAAA,MACrF;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA;AAAA,EAGQ,aAAa,MAAA,EAA2B;AAC9C,IAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,CAAK,KAAA;AAC1B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,SAAS,CAAA,EAAG;AACjD,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,OAAA;AAC5B,IAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,SAAS,CAAA,EAAG;AACrD,MAAA,OAAO,OAAA;AAAA,IACT;AACA,IAAA,OAAO,MAAA,CAAO,MAAA;AAAA,EAChB;AAAA,EAEQ,aAAa,MAAA,EAAkC;AACrD,IAAA,MAAM,MAAA,GAAS,OAAO,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,YAAA,GAAe,OAAO,IAAA,CAAK,YAAA;AACjC,IAAA,MAAM,OAAA,GAAU,OAAO,IAAA,CAAK,OAAA;AAC5B,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,IAAA,CAAK,YAAA,CAAa,MAAM,CAAA;AAAA,MAC/B,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,GAAI,OAAO,MAAA,KAAW,WAAW,EAAE,MAAA,KAAW,EAAC;AAAA,MAC/C,GAAI,OAAO,YAAA,KAAiB,WAAW,EAAE,YAAA,KAAiB,EAAC;AAAA,MAC3D,GAAI,OAAO,OAAA,KAAY,WAAW,EAAE,OAAA,KAAY;AAAC,KACnD;AAAA,EACF;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,KAAA,GAAQ,MAAM,GAAA,CAAI,CAAC,WAAW,IAAA,CAAK,YAAA,CAAa,MAAM,CAAC,CAAA;AAC7D,IAAA,MAAM,SAA4B,EAAC;AACnC,IAAA,KAAA,IAAS,SAAS,CAAA,EAAG,MAAA,GAAS,KAAA,CAAM,MAAA,EAAQ,UAAU,kBAAA,EAAoB;AACxE,MAAA,MAAA,CAAO,KAAK,KAAA,CAAM,KAAA,CAAM,MAAA,EAAQ,MAAA,GAAS,kBAAkB,CAAC,CAAA;AAAA,IAC9D;AAKA,IAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU,MAAA,CAAO,eAAA,CAAgB,IAAA,CAAK,SAAA,EAAW,KAAK,CAAC,CAAC,CAAA;AAAA,EACxF;AACF;;;AC9JO,IAAM,cAAA,GAAN,cAA6B,iBAAA,CAAkB;AAAA,EACnC,cAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,GAAA,IAAO,wBAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,eAAA;AAAA,EAClC;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,YAAA;AAGJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,OAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAK1B,MAAA,YAAA,GAAe,GAAA,CAAI,YAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,SAAS,YAAA,CAAa,EAAE,GAAA,EAAK,IAAA,CAAK,KAAK,CAAA;AAC7C,IAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,SAAS,MAAA,EAA2C;AAC1D,IAAA,OAAO;AAAA,MACL,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,OAAO,MAAA,CAAO,KAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAI;AAAA,KAClC;AAAA,EACF;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AAGjE,IAAA,MAAM,QAAQ,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,WAAW,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAC,CAAC,CAAC,CAAA;AAAA,EAC/F;AACF;;;AC1EO,IAAe,kBAAA,GAAf,cAA0C,iBAAA,CAAkB;AAAA;AAAA,EAExD,KAAA;AAAA,EAET,YAAY,OAAA,EAAoC;AAC9C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AAAA,EACvB;AAAA,EAEmB,UAAU,KAAA,EAA4C;AACvE,IAAA,OAAO,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,EAChC;AAIF;;;ACnBA,SAAS,OAAA,CAAQ,MAA+B,GAAA,EAAiC;AAC/E,EAAA,MAAM,KAAA,GAAQ,KAAK,GAAG,CAAA;AACtB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAC7C;AAYO,IAAM,cAAA,GAAN,cAA6B,kBAAA,CAAmB;AAAA,EACpC,cAAA;AAAA,EACA,OAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAgC;AAC1C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,CAAC,gBAAgB,CAAA;AAAA,EACrD;AAAA;AAAA,EAGQ,cAAA,GAAgD;AACtD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,YAAA,GAA2C;AACvD,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,QAAA,GAAW,IAAI,IAAI,KAAA,CAAM,EAAE,SAAS,IAAA,CAAK,OAAA,EAAS,CAAA,CAAE,QAAA,EAAS;AAC7D,MAAA,MAAM,SAAS,OAAA,IAAU;AAAA,IAC3B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,QAAA;AACd,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAO,IAAA,CAAK;AAAA,MAChB,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,QACjC,GAAA,EAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,EAAM,OAAO,KAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,EAAM,SAAS,CAAA,IAAK,IAAA;AAAA,QACzE,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,MAAM;AAAA,OAC9B,CAAE;AAAA,KACH,CAAA;AAAA,EACH;AACF;;;ACxDO,IAAM,iBAAA,GAAN,cAAgC,kBAAA,CAAmB;AAAA,EACvC,cAAA;AAAA,EACA,GAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAmC;AAC7C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,GAAA,IAAO,kBAAA;AAAA,EAC5B;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,OAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,SAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,MAAM,UAAA,GAAa,MAAM,GAAA,CAAI,OAAA,CAAQ,KAAK,GAAG,CAAA;AAC7C,MAAA,OAAA,GAAU,MAAM,WAAW,aAAA,EAAc;AACzC,MAAA,MAAM,OAAA,CAAQ,WAAA,GAAc,IAAA,CAAK,KAAK,CAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA;AACd,IAAA,OAAO,OAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,MAAA,CAAO,WAAA,CAAY,KAAK,KAAA,EAAO,MAAA,CAAO,KAAK,IAAA,CAAK,SAAA,CAAU,MAAM,CAAC,CAAC,CAAA;AAAA,IACpE;AAAA,EACF;AACF;;;AC9EA,IAAM,eAAA,GAAkB,EAAA;AAgCjB,IAAM,YAAA,GAAN,cAA2B,kBAAA,CAAmB;AAAA,EAClC,cAAA;AAAA,EACA,MAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAA8B;AACxC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AAAA,EACxB;AAAA;AAAA,EAGQ,cAAA,GAA4C;AAClD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAuC;AACnD,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,qBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAO1B,MAAA,MAAM,SAAA,GAAY,IAAI,GAAA,CAAI,SAAA,CAAU,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AAC3D,MAAA,MAAM,cAAc,GAAA,CAAI,uBAAA;AACxB,MAAA,MAAA,GAAS;AAAA,QACP,gBAAA,EAAkB,CAAC,QAAA,EAAU,OAAA,KAC3B,SAAA,CAAU,IAAA;AAAA,UACR,IAAI,WAAA,CAAY;AAAA,YACd,QAAA,EAAU,QAAA;AAAA,YACV,OAAA,EAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,KAAA,MAAW,EAAE,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,WAAA,EAAa,KAAA,CAAM,IAAA,EAAK,CAAE;AAAA,WAC5E;AAAA;AACH,OACJ;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,SAAmC,EAAC;AAC1C,IAAA,KAAA,IAAS,QAAQ,CAAA,EAAG,KAAA,GAAQ,OAAA,CAAQ,MAAA,EAAQ,SAAS,eAAA,EAAiB;AACpE,MAAA,MAAA,CAAO,KAAK,OAAA,CAAQ,KAAA,CAAM,KAAA,EAAO,KAAA,GAAQ,eAAe,CAAC,CAAA;AAAA,IAC3D;AAMA,IAAA,MAAM,OAAA,CAAQ,GAAA;AAAA,MACZ,MAAA,CAAO,GAAA;AAAA,QAAI,CAAC,UACV,MAAA,CAAO,gBAAA;AAAA,UACL,IAAA,CAAK,KAAA;AAAA,UACL,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,EAAQ,WAAW,EAAE,EAAA,EAAI,MAAA,CAAO,KAAK,GAAG,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,MAAM,GAAE,CAAE;AAAA;AACpF;AACF,KACF;AAAA,EACF;AACF;;;AC5EO,IAAM,eAAA,GAAN,cAA8B,kBAAA,CAAmB;AAAA,EACrC,cAAA;AAAA,EACA,SAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAC9B,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AAAA,EAC3B;AAAA;AAAA,EAGQ,cAAA,GAA8C;AACpD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAyC;AACrD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,sBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,KAAA,GAAQ,IAAI,GAAA,CAAI,MAAA,CAAO,EAAE,SAAA,EAAW,IAAA,CAAK,SAAA,EAAW,CAAA,CAAE,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AAAA,IACxE,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAgB,aAAa,OAAA,EAA8C;AACzE,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AAKjE,IAAA,MAAM,QAAQ,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,MAAA,KAAW,OAAO,cAAA,CAAe,EAAE,MAAM,MAAA,CAAO,IAAA,CAAK,KAAK,SAAA,CAAU,MAAM,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,EACjH;AACF;;;ACrBO,IAAM,mBAAA,GAAN,cAAkC,iBAAA,CAAkB;AAAA;AAAA,EAEhD,YAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,YAAY,OAAA,EAAqC;AAC/C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,eAAe,OAAA,CAAQ,YAAA;AAC5B,IAAA,IAAA,CAAK,gBAAgB,OAAA,CAAQ,aAAA;AAC7B,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAmD;AACzD,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA8C;AAC1D,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,uBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,iCAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAI1B,MAAA,UAAA,GAAa,GAAA,CAAI,oBAAA;AACjB,MAAA,uBAAA,GAA0B,GAAA,CAAI,mBAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,YAAY,IAAI,UAAA,CAAW,EAAE,MAAA,EAAQ,IAAA,CAAK,QAAQ,CAAA;AACxD,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,YAAA,EAAc,CAAC,YAAA,EAAc,aAAA,EAAe,WAC1C,SAAA,CAAU,IAAA;AAAA,QACR,IAAI,uBAAA,CAAwB;AAAA,UAC1B,YAAA;AAAA,UACA,aAAA;AAAA,UACA,SAAA,EAAW;AAAA,SACZ;AAAA;AACH,KACJ;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,MAAA,GAAS,KAAA,CACZ,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MAChB,SAAA,EAAW,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,SAAS,CAAA;AAAA,MACtC,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,MAAM;AAAA,KAC7B,CAAE,EACD,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAS,CAAA;AAC3C,IAAA,MAAM,OAAO,YAAA,CAAa,IAAA,CAAK,YAAA,EAAc,IAAA,CAAK,eAAe,MAAM,CAAA;AAAA,EACzE;AACF;;;AC5EA,SAAS,YAAY,UAAA,EAA4B;AAC/C,EAAA,MAAM,KAAA,GAAQ,WAAW,UAAU,CAAA;AACnC,EAAA,QAAQ,KAAA;AAAO,IACb,KAAA,CAAA;AAAA,IACA,KAAA,EAAA;AACE,MAAA,OAAO,OAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,MAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,SAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,OAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,UAAA;AAAA;AAEb;AAWO,IAAM,qBAAA,GAAN,cAAoC,iBAAA,CAAkB;AAAA;AAAA,EAElD,OAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAwC,EAAC,EAAG;AACtD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,UAAA;AAClC,IAAA,IAAA,CAAK,YAAY,OAAA,CAAQ,SAAA;AACzB,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAqD;AAC3D,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAAgD;AAC5D,IAAA,IAAI,WAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,uBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,WAAA,GAAc,GAAA,CAAI,OAAA;AAAA,IACpB,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,UAAU,IAAI,WAAA,CAAY,EAAE,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA;AAC7D,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,OAAO,CAAA;AACpC,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,eAAA,EAAiB,CAAC,OAAA,KAAY,GAAA,CAAI,MAAM,OAAO;AAAA,KACjD;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MACrC,QAAA,EAAU,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AAAA,MAClC,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,aAAa,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC;AAAA,KAC7C,CAAE,CAAA;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,OAAO,CAAA;AAAA,EACtC;AACF;;;AC/EA,SAAS,oBAAoB,UAAA,EAA4B;AACvD,EAAA,MAAM,KAAA,GAAQ,WAAW,UAAU,CAAA;AACnC,EAAA,QAAQ,KAAA;AAAO,IACb,KAAA,CAAA;AAAA,IACA,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAAA,IACT,KAAA,EAAA;AACE,MAAA,OAAO,CAAA;AAAA;AAEb;AAaO,IAAM,oBAAA,GAAN,cAAmC,iBAAA,CAAkB;AAAA;AAAA,EAEjD,gBAAA;AAAA,EACQ,cAAA;AAAA,EACT,MAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAuC,EAAC,EAAG;AACrD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,mBAAmB,OAAA,CAAQ,gBAAA;AAChC,IAAA,IAAA,CAAK,iBAAiB,OAAA,CAAQ,MAAA;AAAA,EAChC;AAAA;AAAA,EAGQ,cAAA,GAAoD;AAC1D,IAAA,OAAO,IAAA,CAAK,kBAAkB,IAAA,CAAK,MAAA;AAAA,EACrC;AAAA,EAEA,MAAc,YAAA,GAA+C;AAC3D,IAAA,IAAI,mBAAA;AACJ,IAAA,IAAI;AAGF,MAAA,MAAM,UAAA,GAAa,qBAAA;AACnB,MAAA,MAAM,GAAA,GAAO,MAAM,OAAO,UAAA,CAAA;AAG1B,MAAA,mBAAA,GAAsB,GAAA,CAAI,eAAA;AAAA,IAC5B,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,eAAA,GAAkB,IAAI,mBAAA,CAAoB,IAAA,CAAK,gBAAgB,CAAA;AACrE,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,eAAA,EAAiB,CAAC,MAAA,KAAW;AAC3B,QAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,UAAA,eAAA,CAAgB,WAAW,KAAK,CAAA;AAAA,QAClC;AACA,QAAA,eAAA,CAAgB,KAAA,EAAM;AACtB,QAAA,OAAO,QAAQ,OAAA,EAAQ;AAAA,MACzB;AAAA,KACF;AACA,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,SAAS,IAAA,CAAK,cAAA,EAAe,IAAM,MAAM,KAAK,YAAA,EAAa;AACjE,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,MACpC,OAAA,EAAS,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,MAC3B,QAAA,EAAU,mBAAA,CAAoB,MAAA,CAAO,KAAK;AAAA,KAC5C,CAAE,CAAA;AACF,IAAA,MAAM,MAAA,CAAO,gBAAgB,MAAM,CAAA;AAAA,EACrC;AACF;;;ACvHA,eAAe,kBAAA,CAAmB,GAAA,EAAa,MAAA,EAAgB,KAAA,EAAyC;AACtG,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,cAAc,MAAA,EAAO;AAAA,IACpE,IAAA,EAAM,CAAA,CAAA,EAAI,KAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAAA,GAC1B,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,gCAAgC,GAAG,CAAA,oBAAA,EAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,yCAAA;AAAA,KACnF;AAAA,EACF;AACF;AAsBO,IAAM,gBAAA,GAAN,cAA+B,iBAAA,CAAkB;AAAA;AAAA,EAE7C,GAAA;AAAA;AAAA,EAEA,MAAA;AAAA;AAAA,EAEA,IAAA;AAAA,EACQ,MAAA;AAAA,EAEjB,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,QAAQ,IAAA,IAAQ,eAAA;AAC5B,IAAA,IAAA,CAAK,GAAA,GAAM,CAAA,yBAAA,EAA4B,IAAA,CAAK,IAAI,CAAA,YAAA,CAAA;AAChD,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,kBAAA;AAAA,EAClC;AAAA,EAEmB,UAAU,KAAA,EAAmD;AAC9E,IAAA,MAAM,SAAA,GAAY,MAAM,GAAA,CAAI,CAAC,WAAW,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAC3D,IAAA,OAAO,KAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,QAAQ,SAAS,CAAA;AAAA,EACrD;AACF;;;AClDA,eAAe,wBAAA,CACb,GAAA,EACA,OAAA,EACA,IAAA,EACe;AACf,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,GAAG,OAAA,EAAS,gBAAgB,sBAAA,EAAuB;AAAA,IAC9D;AAAA,GACD,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,MAAM,CAAA,mCAAA,EAAsC,GAAG,uBAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,EAC3G;AACF;AAoBO,IAAM,sBAAA,GAAN,cAAqC,iBAAA,CAAkB;AAAA;AAAA,EAEnD,GAAA;AAAA;AAAA,EAEA,KAAA;AAAA,EACQ,MAAA;AAAA,EACA,MAAA;AAAA,EAEjB,YAAY,OAAA,EAAwC;AAClD,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAQ,KAAA,IAAS,MAAA;AAC9B,IAAA,IAAA,CAAK,MAAM,CAAA,EAAG,OAAA,CAAQ,KAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,MAAA,CAAA;AAC9C,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,MAAA;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,wBAAA;AAAA,EAClC;AAAA,EAEmB,UAAU,KAAA,EAAmD;AAC9E,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,UAAU,KAAA,EAAO;AAC1B,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,IAAA,CAAK,KAAA,EAAM,EAAG,CAAC,CAAA;AAC5D,MAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,IAAA,GAAO,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC;AAAA,CAAA;AAChC,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAC7B,MAAA,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,IAC/C;AACA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,SAAS,IAAI,CAAA;AAAA,EAC5C;AACF;ACjDA,eAAe,mBAAA,CACb,GAAA,EACA,OAAA,EACA,IAAA,EAC+B;AAC/B,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,MAAA,EAAQ,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM,CAAA;AACnE,EAAA,OAAO;AAAA,IACL,IAAI,QAAA,CAAS,EAAA;AAAA,IACb,QAAQ,QAAA,CAAS,MAAA;AAAA,IACjB,UAAA,EAAY,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,aAAa;AAAA,GAChD;AACF;AAGA,SAAS,iBAAiB,MAAA,EAA8B;AACtD,EAAA,MAAM,IAAA,GAAO,EAAE,GAAG,MAAA,CAAO,IAAA,EAAK;AAC9B,EAAA,OAAO,IAAA,CAAK,SAAA;AACZ,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,IAAA,EAAK;AAC3B;AAGA,SAAS,eAAA,CAAgB,YAA2B,GAAA,EAAqB;AACvE,EAAA,IAAI,eAAe,IAAA,EAAM;AAGvB,IAAA,OAAO,GAAA,GAAM,GAAA;AAAA,EACf;AACA,EAAA,MAAM,OAAA,GAAU,OAAO,UAAU,CAAA;AACjC,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,EAAG;AAC5B,IAAA,OAAO,MAAM,OAAA,GAAU,GAAA;AAAA,EACzB;AACA,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AACpC,EAAA,OAAO,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA,GAAI,MAAM,GAAA,GAAS,MAAA;AAC/C;AA8BO,IAAM,iBAAA,GAAN,cAAgC,iBAAA,CAAkB;AAAA;AAAA,EAE9C,GAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EACQ,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACT,WAAA,GAA6B,IAAA;AAAA,EAErC,YAAY,OAAA,EAAmC;AAC7C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,aAAa,OAAA,CAAQ,UAAA;AAC1B,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AAChC,IAAA,IAAA,CAAK,GAAA,GACH,IAAA,CAAK,MAAA,KAAW,IAAA,GAAO,wCAAA,GAA2C,qCAAA;AACpE,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,mBAAA;AAChC,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,GAAA;AAAA,EACrC;AAAA,EAEA,MAAyB,UAAU,KAAA,EAA4C;AAC7E,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,EAAM;AACvB,IAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,IAAA,IAAQ,GAAA,GAAM,KAAK,WAAA,EAAa;AACvD,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN,yCAAyC,IAAI,IAAA,CAAK,KAAK,WAAW,CAAA,CAAE,aAAa,CAAA,+FAAA;AAAA,OACnF;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAEnB,IAAA,MAAM,UAAU,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,KAAW,gBAAA,CAAiB,MAAM,CAAC,CAAA;AAC9D,IAAA,MAAM,IAAA,GAAO,SAAS,MAAA,CAAO,IAAA,CAAK,KAAK,SAAA,CAAU,OAAO,CAAC,CAAC,CAAA;AAC1D,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB,kBAAA;AAAA,MAChB,kBAAA,EAAoB,MAAA;AAAA,MACpB,WAAW,IAAA,CAAK;AAAA,KAClB;AAEA,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,IAAA,CAAK,GAAA,EAAK,SAAS,IAAI,CAAA;AAExD,IAAA,IAAI,MAAA,CAAO,WAAW,GAAA,EAAK;AACzB,MAAA,IAAA,CAAK,WAAA,GAAc,eAAA,CAAgB,MAAA,CAAO,UAAA,EAAY,GAAG,CAAA;AACzD,MAAA,OAAA,CAAQ,KAAA;AAAA,QACN,6EAAwE,IAAI,IAAA,CAAK,KAAK,WAAW,CAAA,CAAE,aAAa,CAAA,sEAAA;AAAA,OAClH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,iCAAiC,IAAA,CAAK,GAAG,uBAAuB,MAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA,wCAAA;AAAA,OACvF;AAAA,IACF;AAAA,EACF;AACF;;;ACxIA,IAAM,MAAA,GAA0C;AAAA,EAC9C,iBAAe,UAAA;AAAA;AAAA,EACf,kBAAe,UAAA;AAAA;AAAA,EACf,iBAAc,UAAA;AAAA;AAAA,EACd,iBAAc,UAAA;AAAA;AAAA,EACd,kBAAe,UAAA;AAAA;AAAA,EACf,kBAAe;AAAA;AACjB,CAAA;AACA,IAAM,KAAA,GAAQ,SAAA;AAoBd,SAAS,eAAA,GAA2B;AAElC,EAAA,MAAM,GAAA,GAAqC,OAAO,OAAA,KAAY,WAAA,GAAc,SAAY,OAAA,CAAQ,GAAA;AAChG,EAAA,OAAO,KAAK,QAAA,KAAa,MAAA;AAC3B;AAOO,IAAM,gBAAA,GAAN,cAA+B,SAAA,CAAU;AAAA;AAAA,EAE9C,QAAA;AAAA,EACiB,GAAA;AAAA,EAEjB,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,eAAA,EAAgB;AACpD,IAAA,IAAA,CAAK,GAAA,GAAM,QAAQ,OAAA,IAAW,OAAA;AAAA,EAChC;AAAA;AAAA,EAGA,KAAA,CAAM,WAAmB,MAAA,EAAyB;AAChD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AACrC,IAAA,MAAM,OAAO,IAAA,CAAK,QAAA,GAAW,KAAK,UAAA,CAAW,SAAA,EAAW,KAAK,CAAA,GAAI,SAAA;AACjE,IAAA,IAAI,KAAA,IAAA,EAAA,cAAsB;AACxB,MAAA,IAAA,CAAK,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,IACrB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,UAAA,CAAW,WAAmB,KAAA,EAAsB;AAC1D,IAAA,OAAO,GAAG,MAAA,CAAO,KAAK,CAAC,CAAA,EAAG,SAAS,GAAG,KAAK,CAAA,CAAA;AAAA,EAC7C;AACF;;;ACtDA,SAAS,mBAAA,CAAoB,KAAa,KAAA,EAAgC;AACxE,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA;AAI5B,EAAA,MAAM,GAAA,GAAM,OAAO,SAAA,KAAc,WAAA,GAAc,MAAA,GAAa,SAAA;AAC5D,EAAA,IAAI,GAAA,IAAO,OAAO,GAAA,CAAI,UAAA,KAAe,UAAA,EAAY;AAC/C,IAAA,GAAA,CAAI,UAAA,CAAW,KAAK,IAAI,CAAA;AACxB,IAAA;AAAA,EACF;AAKA,EAAA,KAAK,KAAA,CAAM,GAAA,EAAK,EAAE,MAAA,EAAQ,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA,CAAE,KAAA,CAAM,CAAC,KAAA,KAAmB;AAGnF,IAAA,OAAA,CAAQ,KAAA,CAAM,6CAA6C,KAAK,CAAA;AAAA,EAClE,CAAC,CAAA;AACH;AAmBO,IAAM,eAAA,GAAN,cAA8B,SAAA,CAAU;AAAA;AAAA,EAEpC,GAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EACQ,MAAA;AAAA,EACT,QAAkB,EAAC;AAAA,EAE3B,WAAA,CAAY,GAAA,EAAa,OAAA,GAAkC,EAAC,EAAG;AAC7D,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,EAAA;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,mBAAA;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,SAAA,EAAyB;AAC7B,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AACzB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,SAAA,EAAW;AACvC,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,EAAC;AAEd,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,GAAA,EAAK,KAAK,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,6CAA6C,KAAK,CAAA;AAAA,IAClE;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AACF;AC9EO,IAAM,aAAA,GAAN,cAA4B,SAAA,CAAU;AAAA;AAAA,EAElC,IAAA;AAAA;AAAA,EAEA,QAAA;AAAA;AAAA,EAEA,WAAA;AAAA,EACD,EAAA;AAAA,EAER,WAAA,CAAY,IAAA,EAAc,OAAA,GAAgC,EAAC,EAAG;AAC5D,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA,CAAQ,QAAA,IAAY,EAAA,GAAK,IAAA,GAAO,IAAA;AAChD,IAAA,IAAA,CAAK,WAAA,GAAc,QAAQ,WAAA,IAAe,CAAA;AAC1C,IAAA,SAAA,CAAU,QAAQ,IAAI,CAAA,EAAG,EAAE,SAAA,EAAW,MAAM,CAAA;AAC5C,IAAA,IAAA,CAAK,EAAA,GAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,SAAA,EAAyB;AAC7B,IAAA,SAAA,CAAU,IAAA,CAAK,EAAA,EAAI,SAAA,GAAY,IAAI,CAAA;AACnC,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,IAAK,SAAA,CAAU,KAAK,EAAE,CAAA,CAAE,IAAA,IAAQ,IAAA,CAAK,QAAA,EAAU;AACjE,MAAA,IAAA,CAAK,MAAA,EAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,MAAA,GAAe;AACrB,IAAA,SAAA,CAAU,KAAK,EAAE,CAAA;AAEjB,IAAA,IAAI,IAAA,CAAK,cAAc,CAAA,EAAG;AACxB,MAAA,KAAA,IAAS,QAAQ,IAAA,CAAK,WAAA,GAAc,CAAA,EAAG,KAAA,GAAQ,GAAG,KAAA,EAAA,EAAS;AACzD,QAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA;AACzC,QAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,IAAI,IAAI,MAAA,CAAO,KAAA,GAAQ,CAAC,CAAC,CAAA,CAAA;AAC7C,QAAA,IAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACnB,UAAA,IAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AACnB,YAAA,UAAA,CAAW,GAAG,CAAA;AAAA,UAChB;AACA,UAAA,UAAA,CAAW,KAAK,GAAG,CAAA;AAAA,QACrB;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAA;AAC3B,MAAA,IAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AACtB,QAAA,UAAA,CAAW,MAAM,CAAA;AAAA,MACnB;AACA,MAAA,UAAA,CAAW,IAAA,CAAK,MAAM,MAAM,CAAA;AAAA,IAC9B,CAAA,MAAO;AACL,MAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,IACtB;AAEA,IAAA,IAAA,CAAK,EAAA,GAAK,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA;AAAA,EACnC;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,SAAA,CAAU,KAAK,EAAE,CAAA;AAAA,EACnB;AACF;;;ACjEA,eAAe,WAAA,CAAY,KAAa,KAAA,EAAyC;AAC/E,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,sBAAA,EAAuB;AAAA,IAClD,IAAA,EAAM,KAAA,CAAM,IAAA,CAAK,IAAI;AAAA,GACtB,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,MAAM,CAAA,0BAAA,EAA6B,GAAG,uBAAuB,MAAA,CAAO,QAAA,CAAS,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,EAClG;AACF;AAgBO,IAAM,aAAA,GAAN,cAA4B,SAAA,CAAU;AAAA;AAAA,EAElC,GAAA;AAAA;AAAA,EAEA,SAAA;AAAA,EACQ,MAAA;AAAA,EACT,QAAkB,EAAC;AAAA,EAE3B,WAAA,CAAY,GAAA,EAAa,OAAA,GAAgC,EAAC,EAAG;AAC3D,IAAA,KAAA,CAAM,QAAQ,SAAS,CAAA;AACvB,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,SAAA,IAAa,EAAA;AACtC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,WAAA;AAAA,EAClC;AAAA;AAAA,EAGA,MAAM,SAAA,EAAyB;AAC7B,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,SAAS,CAAA;AACzB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,IAAU,IAAA,CAAK,SAAA,EAAW;AACvC,MAAA,IAAA,CAAK,KAAA,EAAM;AAAA,IACb;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,IAAA,IAAA,CAAK,QAAQ,EAAC;AAEd,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAK,KAAK,CAAA;AAC1C,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,KAAmB;AAG/B,QAAA,OAAA,CAAQ,KAAA,CAAM,2CAA2C,KAAK,CAAA;AAAA,MAChE,CAAC,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAES,KAAA,GAAc;AACrB,IAAA,IAAA,CAAK,KAAA,EAAM;AAAA,EACb;AACF;;;ACzCA,SAAS,UAAU,KAAA,EAAqD;AACtE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,MAAM,IAAA,KAAS,UAAA;AAC5D;AAEA,SAAS,iBAAiB,GAAA,EAAuB;AAI/C,EAAA,IAAI,OAAO,iBAAiB,UAAA,EAAY;AACtC,IAAA,YAAA,CAAa,GAAG,CAAA;AAAA,EAClB,CAAA,MAAO;AACL,IAAA,cAAA,CAAe,GAAG,CAAA;AAAA,EACpB;AACF;AAEA,SAAS,aAAA,CAAc,OAAe,MAAA,EAAkC;AACtE,EAAA,OAAA,CAAQ,IAAA;AAAA,IACN,CAAA,uBAAA,EAA0B,MAAA,CAAO,KAAK,CAAC,mEAA8D,MAAM,CAAA,qBAAA;AAAA,GAC7G;AACF;AASO,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAEhB,OAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EACQ,MAAA;AAAA,EACA,cAAA;AAAA,EAEA,QAAgB,EAAC;AAAA,EAC1B,QAAA,GAAW,KAAA;AAAA,EACX,SAAA,GAAY,KAAA;AAAA,EACZ,cAA8B,EAAC;AAAA,EAC/B,mBAAA,GAAsB,CAAA;AAAA,EACtB,UAAA,GAAa,CAAA;AAAA,EAErB,WAAA,CAAY,OAAA,GAAgC,EAAC,EAAG;AAC9C,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,GAAA;AAClC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,YAAA;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS,QAAQ,MAAA,IAAU,aAAA;AAChC,IAAA,IAAA,CAAK,cAAA,GAAiB,QAAQ,cAAA,IAAkB,GAAA;AAAA,EAClD;AAAA;AAAA,EAGA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,KAAK,KAAA,CAAM,MAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,IAAA,EAAkB;AACxB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,OAAA,EAAS;AACpC,MAAA,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AACpB,MAAA,IAAA,CAAK,QAAA,EAAS;AACd,MAAA;AAAA,IACF;AAEA,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,YAAA;AACH,QAAA,IAAA,CAAK,UAAA,EAAW;AAChB,QAAA;AAAA,MACF,KAAK,OAAA;AACH,QAAA,IAAA,CAAK,UAAU,IAAI,CAAA;AACnB,QAAA;AAAA,MACF,KAAK,YAAA;AAAA,MACL;AACE,QAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,QAAA,IAAA,CAAK,UAAA,EAAW;AAChB,QAAA,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AACpB,QAAA,IAAA,CAAK,QAAA,EAAS;AACd,QAAA;AAAA;AACJ,EACF;AAAA;AAAA,EAGA,MAAM,KAAA,GAAuB;AAC3B,IAAA,IAAI,KAAK,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,CAAC,KAAK,QAAA,EAAU;AAC7C,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AACnC,MAAA,IAAA,CAAK,WAAA,CAAY,KAAK,OAAO,CAAA;AAC7B,MAAA,IAAA,CAAK,QAAA,EAAS;AAAA,IAChB,CAAC,CAAA;AAAA,EACH;AAAA,EAEQ,UAAA,GAAmB;AACzB,IAAA,IAAA,CAAK,mBAAA,IAAuB,CAAA;AAC5B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,UAAA,IAAc,IAAA,CAAK,cAAA,EAAgB;AAChD,MAAA,MAAM,QAAQ,IAAA,CAAK,mBAAA;AACnB,MAAA,IAAA,CAAK,mBAAA,GAAsB,CAAA;AAC3B,MAAA,IAAA,CAAK,UAAA,GAAa,GAAA;AAClB,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AAAA,MAChC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,UAAU,IAAA,EAAkB;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,IAAA,EAAK;AACpB,MAAA,IAAI,SAAA,CAAU,MAAM,CAAA,EAAG;AACrB,QAAA,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,KAAmB;AAC/B,UAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAAA,QAC7D,CAAC,CAAA;AAAA,MACH;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,KAAK,CAAA;AAAA,IAC7D;AAAA,EACF;AAAA,EAEQ,QAAA,GAAiB;AACvB,IAAA,IAAI,KAAK,SAAA,EAAW;AAClB,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,gBAAA,CAAiB,MAAM;AACrB,MAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AACjB,MAAA,KAAK,KAAK,QAAA,EAAS;AAAA,IACrB,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAc,QAAA,GAA0B;AACtC,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AAC5B,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,KAAA,EAAM;AAC9B,QAAA,IAAI,CAAC,IAAA,EAAM;AACT,UAAA;AAAA,QACF;AACA,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,EAAK;AAAA,QACb,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAAA,QAC5D;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAChB,MAAA,MAAM,UAAU,IAAA,CAAK,WAAA;AACrB,MAAA,IAAA,CAAK,cAAc,EAAC;AACpB,MAAA,KAAA,MAAW,WAAW,OAAA,EAAS;AAC7B,QAAA,OAAA,EAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;AC/LA,IAAM,WAAA,GAAc,IAAID,iBAAAA,EAA0B;AAS3C,SAAS,aAAA,GAAoC;AAClD,EAAA,OAAO,YAAY,QAAA,EAAS;AAC9B;AAGO,SAAS,SAAA,GAAoB;AAClC,EAAA,OAAOE,WAAAA,CAAY,CAAC,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA;AACtC;AASO,SAAS,SAAA,CAAa,QAAgB,EAAA,EAAgB;AAC3D,EAAA,OAAO,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,EAAE,CAAA;AACnC;;;ACdA,SAAS,gBAAgB,KAAA,EAAwB;AAC/C,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,MAAM,OAAO,CAAA,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AASA,SAAS,iBAAiB,IAAA,EAAwD;AAChF,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA;AACjB,EAAA,IAAI,EAAE,eAAe,KAAA,CAAA,EAAQ;AAC3B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,EAAE,GAAG,IAAA,EAAK;AACvB,EAAA,OAAO,IAAA,CAAK,GAAA;AACZ,EAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,KAAA,IAAS,CAAA,EAAG,IAAI,IAAI,CAAA,EAAA,EAAK,IAAI,OAAO,CAAA,CAAA;AACrD,EAAA,OAAO,IAAA;AACT;AAuBO,IAAM,MAAA,GAAN,MAAM,OAAA,CAAO;AAAA;AAAA,EAET,IAAA;AAAA;AAAA,EAEA,UAAA;AAAA;AAAA,EAEA,OAAA;AAAA,EACD,YAAA;AAAA,EACS,QAAA;AAAA,EACT,aAAA;AAAA,EAER,WAAA,CAAY,IAAA,EAAc,OAAA,GAAyB,EAAC,EAAG;AACrD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,UAAA,CAAW,OAAA,CAAQ,KAAA,IAAA,EAAA,YAAmB;AAC1D,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,GAAa,CAAC,GAAG,OAAA,CAAQ,UAAU,IAAI,EAAC;AAClE,IAAA,IAAA,CAAK,UAAU,EAAC;AAChB,IAAA,KAAA,MAAW,MAAA,IAAU,OAAA,CAAQ,OAAA,IAAW,EAAC,EAAG;AAC1C,MAAA,IAAA,CAAK,IAAI,MAAM,CAAA;AAAA,IACjB;AACA,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,IAAA,GAAO,EAAE,GAAG,OAAA,CAAQ,IAAA,KAAS,EAAC;AACtD,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,aAAA,CAAc,OAAA,CAAQ,KAAK,CAAA;AAAA,EACtD;AAAA;AAAA,EAGA,IAAI,KAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,YAAA;AAAA,EACd;AAAA;AAAA,EAGA,SAAS,KAAA,EAAyB;AAChC,IAAA,IAAA,CAAK,YAAA,GAAe,WAAW,KAAK,CAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,MAAA,EAAuC;AACzC,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,OAAO,MAAA,KAAW,aAAa,IAAI,cAAA,CAAe,MAAM,CAAA,GAAI,MAAM,CAAA;AACpF,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,SAAA,GAAoB;AACtB,IAAA,OAAO,KAAK,aAAA,CAAc,IAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,IAAA,CAAK,cAAc,KAAA,EAAM;AAAA,EACjC;AAAA;AAAA,EAGA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,KAAK,KAAA,EAAM;AACjB,IAAA,KAAA,MAAW,SAAA,IAAa,KAAK,UAAA,EAAY;AACvC,MAAA,SAAA,CAAU,KAAA,EAAM;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,CAAM,IAAA,EAAc,IAAA,GAAgC,EAAC,EAAW;AAC9D,IAAA,MAAM,KAAA,GAAQ,IAAI,OAAA,CAAO,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI;AAAA,MAC/C,OAAO,IAAA,CAAK,YAAA;AAAA,MACZ,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,MAAM,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,IAAA;AAAK,KACnC,CAAA;AACD,IAAA,KAAA,CAAM,gBAAgB,IAAA,CAAK,aAAA;AAC3B,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,WAAA,CAAY,MAAA,EAAgB,KAAA,EAAgB,MAAA,EAAyB;AAE3E,IAAA,IAAI;AACF,MAAA,MAAA,CAAO,OAAA,GAAU,OAAO,MAAM,CAAA;AAAA,IAChC,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,QAAA,CAAS,KAAA,EAAc,OAAA,EAAiB,IAAA,EAAiD;AAC/F,IAAA,IAAI,KAAA,GAAQ,KAAK,YAAA,EAAc;AAC7B,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,SAAS,YAAA,CAAa;AAAA,MACxB,KAAA;AAAA,MACA,QAAQ,IAAA,CAAK,IAAA;AAAA,MACb,OAAA;AAAA,MACA,IAAA,EAAM,EAAE,GAAG,IAAA,CAAK,QAAA,EAAU,GAAG,cAAA,EAAe,EAAG,GAAG,gBAAA,CAAiB,IAAI,CAAA;AAAE,KAC1E,CAAA;AAED,IAAA,MAAM,eAAe,aAAA,EAAc;AACnC,IAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,MAAA,MAAA,CAAO,KAAK,YAAA,KAAiB,YAAA;AAAA,IAC/B;AAEA,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAA,CAAO,SAAA,GAAY,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,GAAI,MAAA;AAAA,MACzD,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,MAAM,CAAA;AACtC,QAAA;AAAA,MACF;AACA,MAAA,IAAI,WAAW,IAAA,EAAM;AACnB,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAA,GAAS,MAAA;AAAA,IACX;AAMA,IAAA,IAAA,CAAK,aAAA,CAAc,QAAQ,MAAM;AAC/B,MAAA,IAAA,CAAK,eAAe,MAAM,CAAA;AAAA,IAC5B,CAAC,CAAA;AAED,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEQ,eAAe,MAAA,EAAyB;AAC9C,IAAA,KAAA,MAAW,SAAA,IAAa,KAAK,UAAA,EAAY;AACvC,MAAA,IAAI;AACF,QAAA,SAAA,CAAU,KAAA,CAAM,SAAA,CAAU,MAAA,CAAO,MAAM,GAAG,MAAM,CAAA;AAAA,MAClD,SAAS,KAAA,EAAO;AAGd,QAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,SAAA,CAAU,WAAA,CAAY,IAAI,kCAAkC,KAAK,CAAA;AAAA,MACpF;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,OAAA,EAAS;AACjC,MAAA,IAAI;AACF,QAAA,MAAA,CAAO,WAAW,MAAM,CAAA;AAAA,MAC1B,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,WAAA,CAAY,MAAA,EAAQ,KAAA,EAAO,MAAM,CAAA;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,CAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC1E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,aAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,IAAA,CAAK,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC1E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,aAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,EAChD;AAAA;AAAA,EAGA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,KAAA,CAAM,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC3E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAA,EAAA,cAAsB,OAAA,EAAS,IAAI,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,OAAA,CAAQ,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC7E,IAAA,OAAO,IAAA,CAAK,wBAAqB,OAAA,EAAS,EAAE,MAAM,SAAA,EAAW,GAAG,MAAM,CAAA;AAAA,EACxE;AAAA;AAAA,EAGA,MAAA,CAAO,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC5E,IAAA,OAAO,IAAA,CAAK,wBAAqB,OAAA,EAAS,EAAE,MAAM,QAAA,EAAU,GAAG,MAAM,CAAA;AAAA,EACvE;AAAA;AAAA,EAGA,WAAA,CAAY,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AACjF,IAAA,OAAO,IAAA,CAAK,wBAAqB,OAAA,EAAS,EAAE,MAAM,aAAA,EAAe,GAAG,MAAM,CAAA;AAAA,EAC5E;AAAA;AAAA,EAGA,QAAA,CAAS,OAAA,EAAiB,IAAA,GAAgC,EAAC,EAAqB;AAC9E,IAAA,OAAO,IAAA,CAAK,wBAAqB,OAAA,EAAS,EAAE,MAAM,UAAA,EAAY,GAAG,MAAM,CAAA;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,IAAA,CAAQ,IAAA,EAAc,EAAA,EAA0B,OAAA,GAAuB,EAAC,EAAe;AAC3F,IAAA,MAAM,EAAE,MAAA,EAAQ,cAAA,EAAgB,cAAc,oBAAA,EAAsB,GAAG,MAAK,GAAI,OAAA;AAChF,IAAA,MAAM,MAAA,GAAS,kBAAkB,SAAA,EAAU;AAC3C,IAAA,MAAM,KAAA,GAAQ,YAAY,GAAA,EAAI;AAE9B,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,MAAM,SAAA,CAAU,MAAA,EAAQ,MAAM,IAAI,CAAA;AACjD,MAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,EAAQ,oBAAA,EAAsB,YAAY,GAAA,EAAI,GAAI,OAAO,IAAI,CAAA;AACnF,MAAA,OAAO,MAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,UAAA,CAAW,MAAM,MAAA,EAAQ,oBAAA,EAAsB,YAAY,GAAA,EAAI,GAAI,KAAA,EAAO,IAAA,EAAM,KAAK,CAAA;AAC1F,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,WACN,IAAA,EACA,MAAA,EACA,oBAAA,EACA,UAAA,EACA,MACA,KAAA,EACM;AACN,IAAA,MAAM,QAAA,GAAoC;AAAA,MACxC,MAAA;AAAA,MACA,UAAA,EAAY,IAAA,CAAK,KAAA,CAAM,UAAA,GAAa,GAAI,CAAA,GAAI,GAAA;AAAA,MAC5C,GAAG;AAAA,KACL;AACA,IAAA,IAAI,yBAAyB,MAAA,EAAW;AACtC,MAAA,QAAA,CAAS,YAAA,GAAe,oBAAA;AAAA,IAC1B;AACA,IAAA,QAAA,CAAS,IAAA,KAAS,MAAA;AAClB,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,QAAA,CAAS,KAAA,GAAQ,gBAAgB,KAAK,CAAA;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,KAAA,KAAU,MAAA,GAAA,EAAA,eAAA,EAAA,aAAsC,IAAA,EAAM,QAAQ,CAAA;AAAA,EAC9E;AACF;;;AC7TA,eAAe,gBAAgB,MAAA,EAA+B;AAC5D,EAAA,MAAM,OAAO,KAAA,EAAM;AAKnB,EAAA,KAAA,MAAW,SAAA,IAAa,OAAO,UAAA,EAAY;AACzC,IAAA,IAAI,CAAC,QAAA,CAAS,SAAS,CAAA,EAAG;AACxB,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,KAAA,EAAM;AAAA,IACxB,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,MAAM,CAAA,EAAG,SAAA,CAAU,WAAA,CAAY,IAAI,qBAAqB,KAAK,CAAA;AAAA,IACvE;AAAA,EACF;AACF;AAwBO,SAAS,SAAA,CACd,QACA,EAAA,EACqC;AACrC,EAAA,OAAO,UAAU,IAAA,KAAiC;AAChD,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA;AAAA,IACzB,CAAA,SAAE;AACA,MAAA,MAAM,gBAAgB,MAAM,CAAA;AAAA,IAC9B;AAAA,EACF,CAAA;AACF;AAGO,IAAM,UAAA,GAAa;AAEnB,IAAM,iBAAA,GAAoB;AAE1B,IAAM,iBAAA,GAAoB;;;ACpC1B,SAAS,uBAAA,CAAwB,MAAA,EAAgB,OAAA,GAAkC,EAAC,EAAe;AACxG,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,CAAC,WAAW,QAAQ,CAAA;AACvD,EAAA,IAAI,MAAA,GAAS,KAAA;AAEb,EAAA,MAAM,QAAA,GAAW,CAAC,SAAA,KAA6B;AAC7C,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA;AAAA,IACF;AACA,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,MAAA,CACG,KAAA,EAAM,CACN,KAAA,CAAM,CAAC,KAAA,KAAmB;AACzB,MAAA,OAAA,CAAQ,KAAA,CAAM,kEAAkE,KAAK,CAAA;AAAA,IACvF,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,MAChB;AAAA,IACF,CAAC,CAAA;AAAA,EACL,CAAA;AAEA,EAAA,MAAM,eAAe,MAAY;AAC/B,IAAA,QAAA,CAAS,KAAK,CAAA;AAAA,EAChB,CAAA;AACA,EAAA,MAAM,WAAW,MAAY;AAC3B,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA;AAEA,EAAA,OAAA,CAAQ,IAAA,CAAK,cAAc,YAAY,CAAA;AACvC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,OAAA,CAAQ,IAAA,CAAK,QAAQ,QAAQ,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,MAAM;AACX,IAAA,OAAA,CAAQ,cAAA,CAAe,cAAc,YAAY,CAAA;AACjD,IAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,MAAA,OAAA,CAAQ,cAAA,CAAe,QAAQ,QAAQ,CAAA;AAAA,IACzC;AAAA,EACF,CAAA;AACF;;;AC8IO,IAAM,OAAA,GAAU","file":"index.mjs","sourcesContent":["/** Log levels, shared by name and numeric weight with the logquill-python contract. */\nexport enum Level {\n /** Finest-grained diagnostic detail. */\n TRACE = 5,\n /** Diagnostic detail useful in development. */\n DEBUG = 10,\n /** Notable events during normal operation. */\n INFO = 20,\n /** Something unexpected, but not (yet) an error. */\n WARN = 30,\n /** An error that didn't necessarily stop the operation. */\n ERROR = 40,\n /** An error that precedes an unrecoverable failure. */\n FATAL = 50,\n}\n\nconst NAME_TO_LEVEL: Readonly<Record<string, Level>> = {\n TRACE: Level.TRACE,\n DEBUG: Level.DEBUG,\n INFO: Level.INFO,\n WARN: Level.WARN,\n ERROR: Level.ERROR,\n FATAL: Level.FATAL,\n};\n\n/** A level given as a `Level`, a level name (any case), or its numeric weight. */\nexport type LevelInput = Level | number | string;\n\n/** The level's name, e.g. `levelName(Level.INFO) === \"INFO\"`. */\nexport function levelName(level: Level): string {\n return Level[level];\n}\n\n/** Normalize a level given as a `Level`, level name, or numeric weight. Throws if unknown. */\nexport function parseLevel(level: LevelInput): Level {\n if (typeof level === \"string\") {\n const parsed = NAME_TO_LEVEL[level.toUpperCase()];\n if (parsed === undefined) {\n throw new Error(`Unknown log level: ${level}`);\n }\n return parsed;\n }\n if (Level[level] === undefined) {\n throw new Error(`Unknown log level: ${String(level)}`);\n }\n return level;\n}\n","import { levelName, type Level } from \"./levels.js\";\n\n/** The cross-language record shape shared with logquill-python. */\nexport interface LogRecord {\n /** ISO8601 UTC timestamp with millisecond precision. */\n timestamp: string;\n /** Level name, e.g. `\"INFO\"`. */\n level: string;\n /** Name of the `Logger` that created this record. */\n logger: string;\n /** The log message. */\n message: string;\n /** Structured payload — always present, even if empty. */\n meta: Record<string, unknown>;\n}\n\n/** ISO8601 UTC timestamp with millisecond precision, matching Python's `utc_timestamp()`. */\nexport function utcTimestamp(): string {\n return new Date().toISOString();\n}\n\n/** Builds a `LogRecord` with the current UTC timestamp. Used internally by `Logger`; exported for transports/plugins that need to construct a record directly. */\nexport function createRecord(params: {\n level: Level;\n logger: string;\n message: string;\n meta: Record<string, unknown>;\n}): LogRecord {\n return {\n timestamp: utcTimestamp(),\n level: levelName(params.level),\n logger: params.logger,\n message: params.message,\n meta: params.meta,\n };\n}\n","import type { LogRecord } from \"./records.js\";\n\n/** `format(record) -> string`, per the transport contract shared with logquill-python. */\nexport interface Formatter {\n /** Turns a `LogRecord` into the string a `Transport` writes. */\n format(record: LogRecord): string;\n}\n\n/** Serializes a record to the canonical JSON line shape. */\nexport class JSONFormatter implements Formatter {\n /** Returns `JSON.stringify(record)`. */\n format(record: LogRecord): string {\n return JSON.stringify(record);\n }\n}\n","import type { LogRecord } from \"./records.js\";\n\n/**\n * The plugin pipeline hooks, matching the Python hook names: `beforeLog`,\n * `afterLog`, `onError`. All hooks are optional — implement only what you need.\n * A hook that throws cannot crash logging: the pipeline catches it, routes it\n * to `onError`, and moves on.\n */\nexport interface Plugin {\n /** Return a (possibly modified) record, or `null` to drop it. */\n beforeLog?(record: LogRecord): LogRecord | null;\n /** Called after the record has been dispatched to every transport. */\n afterLog?(record: LogRecord): void;\n /** Called when one of this plugin's own hooks throws. */\n onError?(error: unknown, record: LogRecord): void;\n}\n\n/** A plain `beforeLog`-style function, as accepted by `Logger.use()` in place of a `Plugin`. */\nexport type MiddlewareFunc = (record: LogRecord) => LogRecord | null;\n\n/**\n * Wraps a plain `beforeLog`-style function as a `Plugin`. `Logger.use()`\n * builds one of these automatically when given a function instead of a\n * `Plugin` — Express/Koa-style middleware ergonomics, without needing to\n * read the `Plugin` interface first. There's no `next()` chaining: the\n * pipeline already calls hooks in sequence, so this is sugar for a\n * single-method `Plugin`, not a new execution model.\n */\nexport class FunctionPlugin implements Plugin {\n private readonly func: MiddlewareFunc;\n\n constructor(func: MiddlewareFunc) {\n this.func = func;\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n return this.func(record);\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Injects fixed key/value pairs into every record's `meta`.\n * A value already present in a record's own `meta` wins over the fixed context.\n */\nexport class ContextPlugin implements Plugin {\n /** Fixed key/value pairs merged into every record's `meta`. */\n readonly context: Record<string, unknown>;\n\n constructor(context: Record<string, unknown>) {\n this.context = context;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n return { ...record, meta: { ...this.context, ...record.meta } };\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nconst contextStore = new AsyncLocalStorage<Record<string, unknown>>();\n\n/**\n * The merged key/value pairs bound by every `bindContext()` block currently\n * active in this execution context, or `{}` outside any block. Backed by\n * `AsyncLocalStorage` (not a plain module variable) so concurrent async\n * operations sharing one `Logger` don't see each other's bound context —\n * the Node equivalent of Python's `contextvars`-based `current_context()`.\n */\nexport function currentContext(): Record<string, unknown> {\n return contextStore.getStore() ?? {};\n}\n\n/**\n * Runs `fn` with `values` merged into the request-scoped context for the\n * rest of its execution — every `Logger` call underneath it, through any\n * number of function calls and `await`s deep, picks them up in `meta`\n * automatically, without threading them through every signature by hand:\n *\n * ```ts\n * await bindContext({ requestId: \"abc123\" }, async () => {\n * await handleRequest(); // any logging in here, or in what it calls,\n * // gets meta.requestId = \"abc123\" for free\n * });\n * ```\n *\n * Calls nest by merging: an inner `bindContext`'s value wins over an outer\n * one on key collision, the same way an explicit call-site `meta` value\n * always wins over anything bound here. `fn`'s return value (including a\n * `Promise`, whose continuations stay inside the bound context across any\n * `await`) is returned unchanged.\n */\nexport function bindContext<T>(values: Record<string, unknown>, fn: () => T): T {\n return contextStore.run({ ...currentContext(), ...values }, fn);\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** Derives the key a record is rate-limited under. Any hashable value works — it's used as a `Map` key. */\nexport type RateLimitKeyFunc = (record: LogRecord) => unknown;\n\nfunction defaultKey(record: LogRecord): string {\n return `${record.logger}:${record.level}`;\n}\n\n/** Options for {@link RateLimitPlugin}. */\nexport interface RateLimitPluginOptions {\n /** Groups records into independent windows. Default: `(logger, level)`. */\n keyFunc?: RateLimitKeyFunc;\n /** Distinct keys tracked at once before the least-recently-seen one is evicted. Default 1000. */\n maxKeys?: number;\n /** Injectable clock (seconds), for deterministic window-rollover tests. Defaults to `performance.now() / 1000` — monotonic, so a wall-clock adjustment can't shrink or extend a window. */\n clock?: () => number;\n}\n\ninterface Window {\n start: number;\n count: number;\n}\n\n/**\n * Drops records once a key — by default `(logger, level)` — exceeds\n * `maxRecords` within a rolling `perSeconds` window, capping a noisy loop\n * (a retry that logs the same error every iteration, a hot path that logs\n * once per request) without silencing the logger's other messages.\n *\n * Each key gets its own fixed window: the count for a key resets\n * `perSeconds` after that *key's own* first record in the current window,\n * not a shared global clock, so unrelated keys never reset in lockstep.\n *\n * Pass `keyFunc` to rate-limit on something other than `(logger, level)` —\n * e.g. per error message, or per a `meta` field identifying the caller.\n *\n * Bounded by `maxKeys` distinct keys tracked at once; past that, the\n * least-recently-seen key's window is evicted to make room for a new one —\n * the same bounded-memory trade-off `SamplingPlugin` makes for trace\n * buffering, since an unbounded key space (e.g. rate-limiting per user id)\n * would otherwise grow memory without limit.\n */\nexport class RateLimitPlugin implements Plugin {\n /** Records allowed per key within a `perSeconds` window before further records for that key are dropped. */\n readonly maxRecords: number;\n /** Length, in seconds, of each key's rolling window. */\n readonly perSeconds: number;\n /** Distinct keys tracked at once before the least-recently-seen one is evicted. */\n readonly maxKeys: number;\n private readonly keyFunc: RateLimitKeyFunc;\n private readonly clock: () => number;\n private readonly windows = new Map<unknown, Window>();\n\n constructor(maxRecords: number, perSeconds: number, options: RateLimitPluginOptions = {}) {\n if (maxRecords < 1) {\n throw new Error(`maxRecords must be at least 1, got ${String(maxRecords)}`);\n }\n if (perSeconds <= 0) {\n throw new Error(`perSeconds must be positive, got ${String(perSeconds)}`);\n }\n this.maxRecords = maxRecords;\n this.perSeconds = perSeconds;\n this.keyFunc = options.keyFunc ?? defaultKey;\n this.maxKeys = options.maxKeys ?? 1000;\n this.clock = options.clock ?? (() => performance.now() / 1000);\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n const key = this.keyFunc(record);\n const now = this.clock();\n const window = this.windows.get(key);\n\n if (window === undefined || now - window.start >= this.perSeconds) {\n this.windows.delete(key);\n this.windows.set(key, { start: now, count: 1 });\n while (this.windows.size > this.maxKeys) {\n this.evictOldest();\n }\n return record;\n }\n\n // move to the end, marking this key as most-recently-touched\n this.windows.delete(key);\n this.windows.set(key, window);\n\n if (window.count >= this.maxRecords) {\n return null;\n }\n\n window.count += 1;\n return record;\n }\n\n private evictOldest(): void {\n const oldest = this.windows.keys().next();\n if (!oldest.done) {\n this.windows.delete(oldest.value);\n }\n }\n}\n","import { Level } from \"../core/levels.js\";\nimport type { Logger } from \"../core/logger.js\";\n\n/** Calls the `Logger` method matching `level` — shared by every bridge that maps another library's numeric/string level onto ours. */\nexport function callAtLevel(\n log: Logger,\n level: Level,\n message: string,\n meta: Record<string, unknown>,\n): void {\n switch (level) {\n case Level.TRACE:\n log.trace(message, meta);\n return;\n case Level.DEBUG:\n log.debug(message, meta);\n return;\n case Level.INFO:\n log.info(message, meta);\n return;\n case Level.WARN:\n log.warn(message, meta);\n return;\n case Level.ERROR:\n log.error(message, meta);\n return;\n case Level.FATAL:\n log.fatal(message, meta);\n return;\n }\n}\n","import { Level } from \"../core/levels.js\";\nimport type { Logger } from \"../core/logger.js\";\nimport { callAtLevel } from \"./level-dispatch.js\";\n\n/** Maps a pino numeric level to a LogQuill level. */\nexport type PinoLevelMap = Readonly<Record<number, Level>>;\n\n/** pino's default numeric levels (`trace`=10 … `fatal`=60), mapped onto the matching LogQuill level. */\nexport const DEFAULT_PINO_LEVEL_MAP: PinoLevelMap = {\n 10: Level.TRACE,\n 20: Level.DEBUG,\n 30: Level.INFO,\n 40: Level.WARN,\n 50: Level.ERROR,\n 60: Level.FATAL,\n};\n\n/** Options for {@link LogQuillPinoDestination}. */\nexport interface LogQuillPinoDestinationOptions {\n /** Overrides `DEFAULT_PINO_LEVEL_MAP` — useful for a pino instance configured with custom levels. An unmapped level falls back to `INFO`. */\n levelMap?: PinoLevelMap;\n}\n\n/**\n * A pino `destination` — pass an instance directly as `pino(destination)`\n * to have pino's own NDJSON output parsed back into LogQuill calls, so an\n * existing `pino()` call site keeps working exactly as it does today while\n * its records also flow through every LogQuill `Transport`/`Plugin`\n * attached to the given `Logger` — handy for migrating incrementally\n * rather than in one PR.\n *\n * ```ts\n * import pino from \"pino\";\n * import { Logger, LogQuillPinoDestination } from \"logquill\";\n *\n * const logquill = new Logger(\"app\");\n * const log = pino(new LogQuillPinoDestination(logquill));\n *\n * log.info({ userId: 42 }, \"still works exactly as before\");\n * ```\n *\n * No `pino` import needed here — a destination only has to be duck-type\n * compatible with a Node `Writable`'s `.write(chunk)`, so unlike the\n * `winston-transport`-based bridge, this needs no dependency on `pino`\n * itself and ships from the main entry point.\n *\n * pino batches writes over a fast, buffered stream, so a single `write()`\n * call can carry more than one NDJSON line; each complete line is parsed\n * and dispatched independently, and a line that fails to parse as JSON is\n * skipped rather than crashing the destination.\n */\nexport class LogQuillPinoDestination {\n /**\n * Pino only recognizes a bare object passed as its sole argument\n * (`pino(destination)`, without a separate options argument) as a\n * destination stream, rather than an options object, if it looks\n * stream-like — checking for `.writable`/`._writableState`, the same\n * duck-typing `stream.Writable` itself satisfies. Without this, `pino()`\n * would silently fall back to writing to `process.stdout` instead.\n */\n readonly writable = true;\n\n private readonly target: Logger;\n private readonly levelMap: PinoLevelMap;\n\n constructor(logquillLogger: Logger, options: LogQuillPinoDestinationOptions = {}) {\n this.target = logquillLogger;\n this.levelMap = options.levelMap ?? DEFAULT_PINO_LEVEL_MAP;\n }\n\n /** Node `Writable`-compatible write hook — splits `chunk` into NDJSON lines and dispatches each as a `Logger` call. */\n write(chunk: string): boolean {\n for (const line of chunk.split(\"\\n\")) {\n if (line.trim()) {\n this.writeLine(line);\n }\n }\n return true;\n }\n\n private writeLine(line: string): void {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n return;\n }\n if (typeof parsed !== \"object\" || parsed === null) {\n return;\n }\n\n const entry = parsed as Record<string, unknown>;\n const pinoLevel = typeof entry.level === \"number\" ? entry.level : 30;\n const message = typeof entry.msg === \"string\" ? entry.msg : \"\";\n\n const meta: Record<string, unknown> = {};\n for (const key of Object.keys(entry)) {\n if (key !== \"level\" && key !== \"msg\") {\n meta[key] = entry[key];\n }\n }\n\n callAtLevel(this.target, this.levelMap[pinoLevel] ?? Level.INFO, message, meta);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** Options for {@link RunPlugin}. */\nexport interface RunPluginOptions {\n /** Adopt an id handed in from elsewhere (e.g. an upstream call) instead of generating a fresh `randomUUID()`. */\n runId?: string;\n}\n\n/**\n * Stamps `meta.runId` — a stable id grouping every record from one agent\n * run — plus an incrementing `meta.step` counter, one per record processed\n * through this plugin instance.\n *\n * Distinct from `TraceContextPlugin`'s `traceId`: `runId` scopes one agent\n * run, `traceId` follows one request across services. A run can span\n * multiple traces (e.g. an agent that calls several downstream services);\n * the two ids are independent.\n *\n * One instance is one run: attach a fresh `RunPlugin()` per run (typically\n * via `logger.child(\"agent\").use(new RunPlugin())`), never a process-wide\n * singleton shared across runs — otherwise concurrent runs would share both\n * the run id and the step counter.\n *\n * A record that already carries `meta.runId` (e.g. propagated from an\n * upstream call) keeps its existing value; `meta.step` is always set from\n * this instance's own counter.\n */\nexport class RunPlugin implements Plugin {\n /** Id stamped onto `meta.runId` for every record this instance processes. */\n readonly runId: string;\n private step = 0;\n\n constructor(options: RunPluginOptions = {}) {\n this.runId = options.runId ?? randomUUID();\n }\n\n beforeLog(record: LogRecord): LogRecord {\n record.meta.runId ??= this.runId;\n record.meta.step = this.step++;\n return record;\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomBytes } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nconst traceparentStore = new AsyncLocalStorage<string | undefined>();\n\n/**\n * Sets the inbound trace header for the current execution context (e.g.\n * request-scoped HTTP middleware, before the handler runs) — the\n * propagation mechanism framework middleware uses to hand `TraceContextPlugin`\n * an inbound header without threading it through every log call. Backed by\n * `AsyncLocalStorage`, so it's isolated per concurrent request. Returns a\n * function that restores the previous value; call it (typically in a\n * `finally` block) once the request is done.\n */\nexport function setTraceparent(value: string | undefined): () => void {\n const previous = traceparentStore.getStore();\n traceparentStore.enterWith(value);\n return () => {\n traceparentStore.enterWith(previous);\n };\n}\n\n/** The header most recently set via `setTraceparent()` for this execution context. */\nexport function getTraceparent(): string | undefined {\n return traceparentStore.getStore();\n}\n\n/** A fresh 32-hex-char id, matching the shape of an OTel/W3C trace id. */\nexport function generateTraceId(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n// W3C Trace Context: \"{version}-{trace-id}-{parent-id}-{trace-flags}\",\n// https://www.w3.org/TR/trace-context/#traceparent-header\nconst W3C_TRACEPARENT_RE = /^[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}$/;\n// AWS X-Ray: \"Root=1-{8 hex}-{24 hex}[;Parent=...;Sampled=...]\"\nconst XRAY_ROOT_RE = /Root=1-([0-9a-f]{8})-([0-9a-f]{24})/;\n// GCP Cloud Trace: \"{32 hex trace id}/{decimal span id}[;o=TRACE_TRUE]\"\nconst GCP_TRACE_RE = /^([0-9a-f]{32})\\/\\d+(;o=\\d)?$/;\n\n/**\n * Extracts a 32-hex-char trace id from a W3C `traceparent`, AWS X-Ray\n * `X-Amzn-Trace-Id`, or GCP `X-Cloud-Trace-Context` header value. Returns\n * `undefined` if `header` doesn't match any of the three shapes.\n */\nexport function parseTraceHeader(header: string): string | undefined {\n const trimmed = header.trim();\n\n const w3c = W3C_TRACEPARENT_RE.exec(trimmed);\n if (w3c?.[1]) {\n return w3c[1];\n }\n\n const xray = XRAY_ROOT_RE.exec(trimmed);\n if (xray?.[1] && xray[2]) {\n return xray[1] + xray[2];\n }\n\n const gcp = GCP_TRACE_RE.exec(trimmed);\n if (gcp?.[1]) {\n return gcp[1];\n }\n\n return undefined;\n}\n\ninterface OtelSpanContextLike {\n traceId: string;\n}\ninterface OtelSpanLike {\n spanContext(): OtelSpanContextLike;\n}\ninterface OtelTraceApiLike {\n getActiveSpan(): OtelSpanLike | undefined;\n isSpanContextValid(spanContext: OtelSpanContextLike): boolean;\n}\ninterface OtelApiLike {\n trace: OtelTraceApiLike;\n}\n\n/**\n * Best-effort, synchronous lookup of the active OpenTelemetry span's trace\n * id via a plain `require(\"@opentelemetry/api\")` — `@opentelemetry/api` is\n * never a declared dependency of this package (matching `logquill-python`'s\n * lazy `import opentelemetry`); this returns `undefined` whenever it isn't\n * installed, or no span is currently active, rather than throwing.\n *\n * A `require()` (via `createRequire`) rather than a dynamic `import()` is\n * deliberate: `Plugin.beforeLog` is synchronous, so this has to be too.\n */\nexport function defaultResolveActiveOtelTraceId(): string | undefined {\n try {\n const require = createRequire(import.meta.url);\n const otel = require(\"@opentelemetry/api\") as OtelApiLike;\n const span = otel.trace.getActiveSpan();\n if (!span) {\n return undefined;\n }\n const spanContext = span.spanContext();\n if (!otel.trace.isSpanContextValid(spanContext)) {\n return undefined;\n }\n return spanContext.traceId;\n } catch {\n return undefined;\n }\n}\n\n/** Options for {@link TraceContextPlugin}. */\nexport interface TraceContextPluginOptions {\n /** `meta` key the trace id is written to. Default `\"traceId\"`. */\n traceKey?: string;\n /** An inbound trace header to resolve on every record, bypassing `setTraceparent()`. */\n traceparent?: string;\n /** Override for testing, or to plug in a non-Node OTel API surface. Defaults to `defaultResolveActiveOtelTraceId`. */\n resolveActiveOtelTraceId?: () => string | undefined;\n}\n\n/**\n * Stamps `meta.traceId` for cross-service correlation — distinct from\n * `RunPlugin`'s `runId`: `traceId` follows one request across services,\n * `runId` scopes one agent run.\n *\n * A record that already carries `meta[traceKey]` (e.g. because\n * `SamplingPlugin`'s tail-based elevation, or an upstream plugin, already\n * set one) is left alone. Otherwise resolves a trace id in priority order:\n *\n * 1. An active OpenTelemetry span's trace id, if `@opentelemetry/api` is\n * installed and a span is current — read directly, not just inbound\n * headers.\n * 2. The `traceparent` constructor option, if given.\n * 3. Whatever `setTraceparent()` most recently set for the current\n * execution context.\n * 4. A freshly generated trace id, if none of the above produced one.\n *\n * Header parsing understands W3C `traceparent`, AWS X-Ray\n * `X-Amzn-Trace-Id`, and GCP `X-Cloud-Trace-Context` — see\n * `parseTraceHeader`. A header that doesn't parse is treated the same as no\n * header: falls through to generating a new trace id.\n */\nexport class TraceContextPlugin implements Plugin {\n /** `meta` key the trace id is written to. */\n readonly traceKey: string;\n private readonly explicitTraceparent: string | undefined;\n private readonly resolveActiveOtelTraceId: () => string | undefined;\n\n constructor(options: TraceContextPluginOptions = {}) {\n this.traceKey = options.traceKey ?? \"traceId\";\n this.explicitTraceparent = options.traceparent;\n this.resolveActiveOtelTraceId = options.resolveActiveOtelTraceId ?? defaultResolveActiveOtelTraceId;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n if (record.meta[this.traceKey] != null) {\n return record;\n }\n record.meta[this.traceKey] = this.resolveTraceId();\n return record;\n }\n\n private resolveTraceId(): string {\n const fromOtel = this.resolveActiveOtelTraceId();\n if (fromOtel) {\n return fromOtel;\n }\n\n const header = this.explicitTraceparent ?? getTraceparent();\n if (header) {\n const parsed = parseTraceHeader(header);\n if (parsed) {\n return parsed;\n }\n }\n\n return generateTraceId();\n }\n}\n","import type { Logger } from \"../core/logger.js\";\n\n/** The subset of an OTel `SpanContext` this processor reads. */\nexport interface OtelSpanContextLike {\n /** 16-hex-char span id. */\n spanId: string;\n}\n\n/** The subset of an OTel `SpanStatus` this processor reads. */\nexport interface OtelStatusLike {\n /** Numeric status code — compared against OTel's `SpanStatusCode.ERROR` (`2`). */\n code: number;\n /** Present when the span ended with an error status; used as the `.error()` message. */\n message?: string;\n}\n\n/**\n * The subset of an OTel `Span`/`ReadableSpan`'s shape this processor reads,\n * duck-typed so this package never declares a real dependency on\n * `@opentelemetry/api`/`@opentelemetry/sdk-trace-base` — the same approach\n * `TraceContextPlugin` uses for its own OTel lookup. Matches what any\n * standard `@opentelemetry/sdk-trace-base`-backed tracer provider actually\n * passes to a registered `SpanProcessor`.\n */\nexport interface OtelSpanLike {\n /** Span name — becomes the `.action()`/`.observation()`/`.error()` message. */\n name: string;\n /** Returns this span's own id (and trace id), matching an OTel `Span`'s `spanContext()`. */\n spanContext(): OtelSpanContextLike;\n /** Present on `@opentelemetry/sdk-trace-base` >=1.9's `Span`. */\n parentSpanContext?: OtelSpanContextLike;\n /** Pre-1.9 `@opentelemetry/sdk-trace-base` shape (superseded by `parentSpanContext`) — read as a fallback when that isn't present. */\n parentSpanId?: string;\n /** Span attributes, copied verbatim onto `meta[attributesKey]` when non-empty. */\n attributes: Record<string, unknown>;\n /** This span's OTel status — an error status routes the end record through `.error()` instead of `.observation()`. */\n status: OtelStatusLike;\n /** Wall-clock duration as an OTel `HrTime` tuple, only meaningful once the span has ended. */\n duration: readonly [seconds: number, nanoseconds: number];\n}\n\n/** OTel's `SpanStatusCode.ERROR`, duck-typed to avoid a real dependency on `@opentelemetry/api`. */\nconst OTEL_STATUS_CODE_ERROR = 2;\n\n/** Options for {@link OtelSpanProcessor}. */\nexport interface OtelSpanProcessorOptions {\n /** `meta` key non-empty span attributes are copied onto. Default `\"attributes\"`. */\n attributesKey?: string;\n}\n\n/**\n * Bridges an OpenTelemetry-native integration — the Vercel AI SDK's\n * `experimental_telemetry` is the main JS example — into LogQuill without\n * forcing it through the callback-handler-object model `LangChainAdapter`\n * uses. Register an instance the same way any other span processor is\n * registered:\n *\n * ```ts\n * import { BasicTracerProvider } from \"@opentelemetry/sdk-trace-base\";\n * import { OtelSpanProcessor } from \"logquill\";\n *\n * const provider = new BasicTracerProvider();\n * provider.addSpanProcessor(new OtelSpanProcessor(log.child(\"agent\")));\n * ```\n *\n * Every span the SDK creates becomes one `.action()` call on start and one\n * `.observation()` (or `.error()`, if the span ended with an error status)\n * call on end — the same two-call shape `LangChainAdapter` uses for\n * `handleToolStart`/`handleToolEnd`. Both carry the span's own `spanId`/\n * `parentSpanId` — OTel span ids are already the same 16-hex-char shape\n * LogQuill's own `spanId` uses, so no translation is needed — and the end\n * call additionally carries `meta.durationMs`. Non-empty span attributes are\n * copied onto `meta[attributesKey]` verbatim, unrenamed — mapping onto the\n * OTel `gen_ai.*` semantic conventions is deliberately out of scope here\n * (see the v2.0 `OTLPTransport`/`gen_ai.*` plan).\n *\n * Never imports `@opentelemetry/api` or `@opentelemetry/sdk-trace-base` —\n * duck-typed against the shape a `Span`/`ReadableSpan` actually has, so\n * `import { Logger } from \"logquill\"` still never requires either package\n * to be installed.\n */\nexport class OtelSpanProcessor {\n private readonly log: Logger;\n private readonly attributesKey: string;\n\n constructor(log: Logger, options: OtelSpanProcessorOptions = {}) {\n this.log = log;\n this.attributesKey = options.attributesKey ?? \"attributes\";\n }\n\n /** Called by the tracer provider when a span starts — emits `.action()`. */\n onStart(span: OtelSpanLike): void {\n this.log.action(span.name, this.baseMeta(span));\n }\n\n /** Called by the tracer provider when a span ends — emits `.observation()`, or `.error()` if the span's status is an error. */\n onEnd(span: OtelSpanLike): void {\n const meta = {\n ...this.baseMeta(span),\n durationMs: span.duration[0] * 1000 + span.duration[1] / 1e6,\n };\n if (span.status.code === OTEL_STATUS_CODE_ERROR) {\n this.log.error(span.name, {\n ...meta,\n error: span.status.message ?? \"span ended with an error status\",\n });\n return;\n }\n this.log.observation(span.name, meta);\n }\n\n /** No internal buffering to flush — every span is forwarded to the `Logger` immediately. */\n async forceFlush(): Promise<void> {}\n\n /** No resources of its own to release; flush/close the wrapped `Logger` separately. */\n async shutdown(): Promise<void> {}\n\n private baseMeta(span: OtelSpanLike): Record<string, unknown> {\n const meta: Record<string, unknown> = { spanId: span.spanContext().spanId };\n const parentSpanId = span.parentSpanContext?.spanId ?? span.parentSpanId;\n if (parentSpanId) {\n meta.parentSpanId = parentSpanId;\n }\n if (Object.keys(span.attributes).length > 0) {\n meta[this.attributesKey] = span.attributes;\n }\n return meta;\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** `meta` keys (case-insensitive) `RedactPlugin` replaces by default. */\nexport const DEFAULT_REDACTED_KEYS: readonly string[] = [\"password\", \"token\", \"secret\", \"api_key\", \"authorization\"];\n\n/** Options for {@link RedactPlugin}. */\nexport interface RedactPluginOptions {\n /** Keys (case-insensitive) to redact. Default `DEFAULT_REDACTED_KEYS`. */\n keys?: readonly string[];\n /** Placeholder a matched value is replaced with. Default `\"***\"`. */\n replacement?: string;\n}\n\n/** Replaces sensitive `meta` values, matched by key (case-insensitive), with a placeholder. */\nexport class RedactPlugin implements Plugin {\n private readonly keys: ReadonlySet<string>;\n /** Placeholder a matched value is replaced with. */\n readonly replacement: string;\n\n constructor(options: RedactPluginOptions = {}) {\n this.keys = new Set((options.keys ?? DEFAULT_REDACTED_KEYS).map((key) => key.toLowerCase()));\n this.replacement = options.replacement ?? \"***\";\n }\n\n beforeLog(record: LogRecord): LogRecord {\n const meta: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(record.meta)) {\n meta[key] = this.keys.has(key.toLowerCase()) ? this.replacement : value;\n }\n return { ...record, meta };\n }\n}\n","import type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Syntactic (not semantic) patterns — matched on shape, so both false\n * positives (a random 9-digit number) and false negatives (anything that\n * doesn't look like these shapes) are expected. Override via `patterns`\n * for anything stricter.\n */\nexport const DEFAULT_PII_PATTERNS: Readonly<Record<string, RegExp>> = {\n email: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/g,\n ssn: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g,\n creditCard: /\\b(?:\\d[ -]?){13,16}\\b/g,\n phone: /\\b(?:\\+?1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\\b/g,\n};\n\nconst MAX_DEPTH = 50;\n\n/** Options for {@link PIIRedactPlugin}. */\nexport interface PIIRedactPluginOptions {\n /** Named patterns to scan for. Default `DEFAULT_PII_PATTERNS`. */\n patterns?: Readonly<Record<string, RegExp>>;\n /** Placeholder a matched substring is replaced with. Default `\"***\"`. */\n replacement?: string;\n}\n\n/**\n * Regex-based PII redaction over `meta` **values**, not just keys.\n *\n * Complements `RedactPlugin`, which redacts by exact key match —\n * `PIIRedactPlugin` scans string values (recursively through nested\n * objects/arrays) for emails, SSNs, credit-card numbers, and phone\n * numbers, and redacts matches wherever they appear, regardless of which\n * key holds them (a `notes` field containing a stray SSN is still caught).\n *\n * Detection is pattern-based: fast and dependency-free, but it matches on\n * syntactic shape, not meaning — a random 9-digit number can false-positive\n * as an SSN, and anything that doesn't fit these shapes (a name, a street\n * address) is a false negative. Pass your own `patterns` to extend or\n * replace the defaults.\n *\n * Recursion into nested `meta` structures is depth- and cycle-bounded, so a\n * circular reference or a pathologically deep structure can't hang or\n * crash the caller — it's left unredacted past the bound rather than\n * throwing.\n */\nexport class PIIRedactPlugin implements Plugin {\n /** Named patterns scanned for in every string `meta` value. */\n readonly patterns: Readonly<Record<string, RegExp>>;\n /** Placeholder a matched substring is replaced with. */\n readonly replacement: string;\n\n constructor(options: PIIRedactPluginOptions = {}) {\n this.patterns = options.patterns ?? DEFAULT_PII_PATTERNS;\n this.replacement = options.replacement ?? \"***\";\n }\n\n beforeLog(record: LogRecord): LogRecord {\n return { ...record, meta: this.redactValue(record.meta, new Set(), 0) as Record<string, unknown> };\n }\n\n private redactValue(value: unknown, seen: ReadonlySet<unknown>, depth: number): unknown {\n if (depth > MAX_DEPTH) {\n return value;\n }\n if (typeof value === \"string\") {\n return this.redactText(value);\n }\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n return value; // circular reference — leave as-is rather than recurse forever\n }\n const nextSeen = new Set(seen).add(value);\n return value.map((entry) => this.redactValue(entry, nextSeen, depth + 1));\n }\n if (value !== null && typeof value === \"object\") {\n if (seen.has(value)) {\n return value;\n }\n const nextSeen = new Set(seen).add(value);\n const result: Record<string, unknown> = {};\n for (const [key, entryValue] of Object.entries(value)) {\n result[key] = this.redactValue(entryValue, nextSeen, depth + 1);\n }\n return result;\n }\n return value;\n }\n\n private redactText(text: string): string {\n let redacted = text;\n for (const pattern of Object.values(this.patterns)) {\n // Custom patterns aren't guaranteed to carry the \"g\" flag, but every\n // occurrence must be replaced (matching Python's `pattern.sub`) —\n // reconstruct with \"g\" added rather than silently stopping at the\n // first match.\n const global = pattern.global ? pattern : new RegExp(pattern.source, `${pattern.flags}g`);\n redacted = redacted.replace(global, this.replacement);\n }\n return redacted;\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"../core/levels.js\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport type { Transport } from \"../transports/transport.js\";\n\n/** Options for {@link SamplingPlugin}. */\nexport interface SamplingPluginOptions {\n /** Source of randomness for the rate check. Defaults to `Math.random`; override with a seeded/fake generator for deterministic tests. */\n rng?: () => number;\n /** `meta` key holding the trace/run id used to group buffered records. Default `\"traceId\"`. */\n traceKey?: string;\n /** A record at or above this level elevates its whole trace. Default `Level.ERROR`. */\n elevateAt?: LevelInput;\n /** Enables tail-based elevation, writing straight to these transports on elevation. Omit to disable and get plain rate-based sampling. */\n transports?: Transport[];\n /** Total buffered records allowed across every trace before the oldest trace is evicted. Default 1000. */\n maxBufferedRecords?: number;\n /** Distinct trace ids held at once before the oldest is evicted. Default 200. */\n maxTraces?: number;\n}\n\n/**\n * Keeps roughly `rate` of records (0.0-1.0), dropping the rest.\n *\n * With `transports` set, sampling becomes tail-based per trace: a record\n * that would otherwise be dropped is buffered under its `meta[traceKey]`\n * value instead of discarded outright. If any later record sharing that\n * trace id reaches `elevateAt` or above, the whole trace is \"elevated\" —\n * every buffered record for that trace id is flushed straight to\n * `transports`, and every subsequent record for that trace id ships\n * unconditionally. This is what lets a sampled-out request still produce a\n * complete trace once it turns out to matter (it errored).\n *\n * Flushing writes buffered records directly to `transports` — pass the\n * same array given to the `Logger`. This bypasses `beforeLog`/`afterLog`/\n * `onError` for any plugin *after* `SamplingPlugin` in the pipeline (the\n * plugins before it already ran, since that's how the buffered record was\n * built); put `SamplingPlugin` last if that matters for your pipeline.\n *\n * Without `transports`, tail-based elevation is inactive and this behaves\n * exactly like plain rate-based sampling (the original behavior) — a\n * record without `meta[traceKey]` is also just rate-sampled, since there's\n * no trace to buffer it under.\n *\n * Buffering is bounded: at most `maxBufferedRecords` records total and\n * `maxTraces` distinct trace ids are held at once. Once either limit is\n * hit, the oldest buffered trace is evicted (and its records are lost, not\n * flushed) — a deliberate bounded-memory trade-off, not a bug: an\n * unbounded per-trace buffer would let a single pathologically long-lived\n * or high-cardinality trace grow memory without limit.\n */\nexport class SamplingPlugin implements Plugin {\n /** Fraction of non-elevated records kept, in `[0, 1]`. */\n readonly rate: number;\n /** `meta` key holding the trace/run id used to group buffered records. */\n readonly traceKey: string;\n /** A record at or above this level elevates its whole trace. */\n readonly elevateAt: Level;\n /** Transports buffered records are flushed straight to on elevation; `undefined` disables tail-based elevation. */\n readonly transports: Transport[] | undefined;\n /** Total buffered records allowed across every trace before the oldest trace is evicted. */\n readonly maxBufferedRecords: number;\n /** Distinct trace ids held at once before the oldest is evicted. */\n readonly maxTraces: number;\n private readonly rng: () => number;\n private readonly buffer = new Map<unknown, LogRecord[]>();\n private bufferedCount = 0;\n private readonly elevated = new Set<unknown>();\n\n constructor(rate: number, options: SamplingPluginOptions = {}) {\n if (rate < 0 || rate > 1) {\n throw new Error(`rate must be between 0 and 1, got ${String(rate)}`);\n }\n this.rate = rate;\n this.rng = options.rng ?? Math.random;\n this.traceKey = options.traceKey ?? \"traceId\";\n this.elevateAt = parseLevel(options.elevateAt ?? Level.ERROR);\n this.transports = options.transports;\n this.maxBufferedRecords = options.maxBufferedRecords ?? 1000;\n this.maxTraces = options.maxTraces ?? 200;\n }\n\n beforeLog(record: LogRecord): LogRecord | null {\n const transports = this.transports;\n if (transports === undefined) {\n return this.rng() < this.rate ? record : null;\n }\n\n const traceId = record.meta[this.traceKey];\n\n if (traceId !== undefined && this.elevated.has(traceId)) {\n return record;\n }\n\n const keep = this.rng() < this.rate;\n const reachedElevateLevel = parseLevel(record.level) >= this.elevateAt;\n\n if (traceId !== undefined && reachedElevateLevel) {\n this.elevate(traceId, transports);\n return record;\n }\n\n if (keep) {\n return record;\n }\n\n if (traceId !== undefined) {\n this.bufferRecord(traceId, record);\n }\n\n return null;\n }\n\n private elevate(traceId: unknown, transports: Transport[]): void {\n this.elevated.add(traceId);\n const buffered = this.buffer.get(traceId) ?? [];\n this.buffer.delete(traceId);\n this.bufferedCount -= buffered.length;\n for (const bufferedRecord of buffered) {\n for (const transport of transports) {\n transport.write(transport.format(bufferedRecord), bufferedRecord);\n }\n }\n }\n\n private bufferRecord(traceId: unknown, record: LogRecord): void {\n let records = this.buffer.get(traceId);\n if (records) {\n // move to the end, marking this trace as most-recently-touched\n this.buffer.delete(traceId);\n this.buffer.set(traceId, records);\n } else {\n if (this.buffer.size >= this.maxTraces) {\n this.evictOldestTrace();\n }\n records = [];\n this.buffer.set(traceId, records);\n }\n\n records.push(record);\n this.bufferedCount += 1;\n\n while (this.bufferedCount > this.maxBufferedRecords && this.buffer.size > 0) {\n this.evictOldestTrace();\n }\n }\n\n private evictOldestTrace(): void {\n const oldest = this.buffer.entries().next();\n if (oldest.done) {\n return;\n }\n const [oldestKey, oldestRecords] = oldest.value;\n this.buffer.delete(oldestKey);\n this.bufferedCount -= oldestRecords.length;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** The hash chain's starting value — a record's `prevHash` when it's the first record in the chain. */\nexport const GENESIS_HASH = \"0\".repeat(64);\n\n/** Options for {@link TamperEvidentPlugin}. */\nexport interface TamperEvidentPluginOptions {\n /** Starting hash the chain builds from. Default `GENESIS_HASH`. Override to continue a chain started elsewhere (e.g. a previous process). */\n genesisHash?: string;\n}\n\n/** Deterministically stringifies a value with object keys sorted, so hashing doesn't depend on key insertion order. */\nfunction canonicalStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map((entry) => canonicalStringify(entry)).join(\",\")}]`;\n }\n if (value !== null && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n return `{${entries.map(([key, entryValue]) => `${JSON.stringify(key)}:${canonicalStringify(entryValue)}`).join(\",\")}}`;\n }\n if (value === undefined) {\n return \"null\"; // JSON has no \"undefined\" literal; fold it the way JSON.stringify does inside arrays/objects\n }\n return JSON.stringify(value);\n}\n\nfunction computeHash(record: Pick<LogRecord, \"timestamp\" | \"level\" | \"logger\" | \"message\" | \"meta\">, prevHash: string): string {\n const restMeta = Object.fromEntries(Object.entries(record.meta).filter(([key]) => key !== \"hash\" && key !== \"prevHash\"));\n const payload = canonicalStringify({\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: restMeta,\n });\n return createHash(\"sha256\").update(`${prevHash}${payload}`).digest(\"hex\");\n}\n\n/**\n * Hash-chains every record so tampering with a written log can be\n * detected after the fact.\n *\n * Each record gets `meta.hash` — a SHA-256 hex digest over the record's\n * own content plus the previous record's hash (`meta.prevHash`) — the same\n * hash-chain construction used by tamper-evident/append-only logs: editing\n * or deleting any one line breaks every hash after it in the chain, even\n * if the tamperer edits the file directly and not through this plugin.\n * Opt-in — hashing every record has a real, measurable CPU cost, so it\n * isn't part of the default pipeline.\n *\n * Verify a previously-written log with `TamperEvidentPlugin.verifyChain`,\n * which re-derives each record's hash from its content and confirms it\n * matches both the stored `meta.hash` and the chain built from the records\n * before it, in order.\n */\nexport class TamperEvidentPlugin implements Plugin {\n private readonly genesisHash: string;\n private lastHash: string;\n\n constructor(options: TamperEvidentPluginOptions = {}) {\n this.genesisHash = options.genesisHash ?? GENESIS_HASH;\n this.lastHash = this.genesisHash;\n }\n\n beforeLog(record: LogRecord): LogRecord {\n const prevHash = this.lastHash;\n const digest = computeHash(record, prevHash);\n const next = { ...record, meta: { ...record.meta, prevHash, hash: digest } };\n this.lastHash = digest;\n return next;\n }\n\n /**\n * Returns `true` iff every record's hash matches its content plus the\n * previous record's hash, in the given order. Returns `false` at the\n * first break in the chain (an edited, removed, or reordered record).\n */\n static verifyChain(\n records: Iterable<Pick<LogRecord, \"timestamp\" | \"level\" | \"logger\" | \"message\" | \"meta\">>,\n options: TamperEvidentPluginOptions = {},\n ): boolean {\n let prevHash = options.genesisHash ?? GENESIS_HASH;\n for (const record of records) {\n const storedHash = record.meta.hash;\n const storedPrevHash = record.meta.prevHash;\n if (typeof storedHash !== \"string\" || storedPrevHash !== prevHash) {\n return false;\n }\n if (computeHash(record, prevHash) !== storedHash) {\n return false;\n }\n prevHash = storedHash;\n }\n return true;\n }\n}\n","import { Level, parseLevel, type LevelInput } from \"../core/levels.js\";\nimport type { Plugin } from \"../core/plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\ninterface DedupeWindow {\n record: LogRecord;\n count: number;\n timer: ReturnType<typeof setTimeout>;\n}\n\n/** Options for {@link AlertingPlugin} and every concrete alert plugin that extends it. */\nexport interface AlertingPluginOptions {\n /** A record at or above this level fires an alert. Default `Level.ERROR`. */\n threshold?: LevelInput;\n /** How long a dedupe window stays open before a collapsed follow-up alert (if any) fires. Default 300_000 (5 minutes). */\n dedupeWindowMs?: number;\n /** Groups records into the same dedupe window. Default: `level:logger:message`. */\n dedupeKey?: (record: LogRecord) => string;\n /** Distinct concurrent dedupe keys tracked at once; beyond this, new keys are dropped rather than tracked. Default 500. */\n maxTrackedKeys?: number;\n}\n\nfunction defaultDedupeKey(record: LogRecord): string {\n return `${record.level}:${record.logger}:${record.message}`;\n}\n\n/**\n * Base class for plugins that fire an external alert on ERROR/FATAL (or any\n * configurable `threshold`).\n *\n * A concrete subclass implements only `sendAlert(record, occurrences)` —\n * everything else (thresholding, deduplication, never blocking the caller,\n * never letting a broken destination crash logging) lives here.\n *\n * The first record at or above `threshold` for a given dedupe key (by\n * default: level + logger + message) fires `sendAlert` right away, without\n * awaiting it — so the log call that triggered it is never blocked on a\n * webhook, SMTP handshake, or any other I/O, even if the destination is\n * slow or unreachable. This stands in for `Logger`'s own async dispatch\n * queue, which doesn't yet handle alert delivery; `AlertingPlugin` could\n * route through it instead of firing its own unawaited call per alert\n * once it does.\n *\n * Any further record matching the same dedupe key within\n * `dedupeWindowMs` of the first is *not* sent again — it just increments a\n * counter. When the window closes, if more than one record matched,\n * exactly one follow-up alert is sent with the total occurrence count,\n * instead of spamming the destination once per record. Tracking is bounded\n * to `maxTrackedKeys` distinct concurrent dedupe keys; beyond that, new\n * keys are dropped rather than tracked (alerting degrades under extreme\n * cardinality, logging itself never does).\n *\n * `sendAlert` is always called without being awaited, and any rejection is\n * routed to this plugin's own `onError`, the same as any other plugin hook\n * that throws.\n */\nexport abstract class AlertingPlugin implements Plugin {\n /** A record at or above this level fires an alert. */\n readonly threshold: Level;\n /** How long a dedupe window stays open before a collapsed follow-up alert (if any) fires. */\n readonly dedupeWindowMs: number;\n /** Distinct concurrent dedupe keys tracked at once; beyond this, new keys are dropped rather than tracked. */\n readonly maxTrackedKeys: number;\n private readonly dedupeKeyFn: (record: LogRecord) => string;\n private readonly windows = new Map<string, DedupeWindow>();\n\n constructor(options: AlertingPluginOptions = {}) {\n this.threshold = parseLevel(options.threshold ?? Level.ERROR);\n this.dedupeWindowMs = options.dedupeWindowMs ?? 300_000;\n this.dedupeKeyFn = options.dedupeKey ?? defaultDedupeKey;\n this.maxTrackedKeys = options.maxTrackedKeys ?? 500;\n }\n\n afterLog(record: LogRecord): void {\n if (parseLevel(record.level) < this.threshold) {\n return;\n }\n\n const key = this.dedupeKeyFn(record);\n const existing = this.windows.get(key);\n if (existing) {\n existing.count += 1;\n return;\n }\n\n if (this.windows.size >= this.maxTrackedKeys) {\n return;\n }\n\n const timer = setTimeout(() => {\n this.flush(key);\n }, this.dedupeWindowMs);\n timer.unref();\n this.windows.set(key, { record, count: 1, timer });\n\n this.safeSend(record, 1);\n }\n\n private flush(key: string): void {\n const window = this.windows.get(key);\n this.windows.delete(key);\n if (!window || window.count <= 1) {\n return;\n }\n this.safeSend(window.record, window.count);\n }\n\n private safeSend(record: LogRecord, occurrences: number): void {\n Promise.resolve()\n .then(() => this.sendAlert(record, occurrences))\n .catch((error: unknown) => {\n try {\n this.onError?.(error, record);\n } catch {\n /* swallowed */\n }\n });\n }\n\n /**\n * Send one alert for `record`, representing `occurrences` collapsed\n * duplicates (1 on first occurrence; the deduped total on a follow-up\n * flush). Override in a concrete subclass — never call this directly,\n * `AlertingPlugin` calls it without awaiting it.\n */\n protected abstract sendAlert(record: LogRecord, occurrences: number): void | Promise<void>;\n\n onError?(error: unknown, record: LogRecord): void;\n\n /** Cancel any pending dedupe-window timers. Call on logger shutdown. */\n close(): void {\n const windows = [...this.windows.values()];\n this.windows.clear();\n for (const window of windows) {\n clearTimeout(window.timer);\n }\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** Posts one alert body to a Slack incoming webhook URL. Swap in a fake for tests. */\nexport type SlackSender = (webhookUrl: string, body: string) => Promise<void> | void;\n\nasync function fetchSlackSender(webhookUrl: string, body: string): Promise<void> {\n const response = await fetch(webhookUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n });\n if (!response.ok) {\n throw new Error(\n `SlackAlertPlugin: webhook returned HTTP ${String(response.status)} — check the webhook URL is still valid in Slack's app config`,\n );\n }\n}\n\nfunction formatMessage(record: LogRecord, occurrences: number): string {\n const suffix = occurrences > 1 ? ` (x${String(occurrences)})` : \"\";\n return `[${record.level}] ${record.logger}: ${record.message}${suffix}`;\n}\n\n/** Options for {@link SlackAlertPlugin}. */\nexport interface SlackAlertPluginOptions extends AlertingPluginOptions {\n /** Posts one alert. Defaults to a `fetch` POST; override for a fake or an alternate backend. */\n sender?: SlackSender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts to a Slack incoming webhook.\n *\n * `webhookUrl` is the full \"Incoming Webhook\" URL from Slack's app config.\n * Uses `fetch` — no extra dependency required. Pass `sender` to swap in a\n * fake for tests or an alternate backend.\n */\nexport class SlackAlertPlugin extends AlertingPlugin {\n /** Slack \"Incoming Webhook\" URL every alert is posted to. */\n readonly webhookUrl: string;\n private readonly sender: SlackSender;\n\n constructor(webhookUrl: string, options: SlackAlertPluginOptions = {}) {\n super(options);\n this.webhookUrl = webhookUrl;\n this.sender = options.sender ?? fetchSlackSender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n const body = JSON.stringify({ text: formatMessage(record, occurrences) });\n await this.sender(this.webhookUrl, body);\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\nconst ENDPOINT = \"https://events.pagerduty.com/v2/enqueue\";\nconst SEVERITY: Readonly<Record<string, string>> = { ERROR: \"error\", FATAL: \"critical\" };\n\n/** POSTs one PagerDuty Events API v2 payload. Swap in a fake for tests. */\nexport type PagerDutySender = (body: string) => Promise<void> | void;\n\nasync function fetchPagerDutySender(body: string): Promise<void> {\n const response = await fetch(ENDPOINT, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body,\n });\n if (!response.ok) {\n throw new Error(\n `PagerDutyAlertPlugin: Events API returned HTTP ${String(response.status)} — check the routing key is a valid Events API v2 integration key`,\n );\n }\n}\n\n/** Options for {@link PagerDutyAlertPlugin}. */\nexport interface PagerDutyAlertPluginOptions extends AlertingPluginOptions {\n /** Posts one Events API v2 payload. Defaults to a `fetch` POST; override for a fake or an alternate backend. */\n sender?: PagerDutySender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts to PagerDuty via the Events\n * API v2 (`POST https://events.pagerduty.com/v2/enqueue`).\n *\n * `routingKey` is an Events API v2 integration key from a PagerDuty\n * service. Uses `fetch` — no extra dependency required. Pass `sender` to\n * swap in a fake for tests or an alternate backend.\n */\nexport class PagerDutyAlertPlugin extends AlertingPlugin {\n /** PagerDuty Events API v2 integration key every alert is sent under. */\n readonly routingKey: string;\n private readonly sender: PagerDutySender;\n\n constructor(routingKey: string, options: PagerDutyAlertPluginOptions = {}) {\n super(options);\n this.routingKey = routingKey;\n this.sender = options.sender ?? fetchPagerDutySender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n let summary = `${record.logger}: ${record.message}`;\n if (occurrences > 1) {\n summary += ` (x${String(occurrences)})`;\n }\n const body = JSON.stringify({\n routing_key: this.routingKey,\n event_action: \"trigger\",\n payload: {\n summary,\n severity: SEVERITY[record.level] ?? \"error\",\n source: record.logger,\n timestamp: record.timestamp,\n custom_details: { occurrences, ...record.meta },\n },\n });\n await this.sender(body);\n }\n}\n","import { AlertingPlugin, type AlertingPluginOptions } from \"./alerting-plugin.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/** One email alert, as built from a deduplicated record before being handed to `nodemailer` (or an injected `sender`). */\nexport interface EmailMessage {\n /** Envelope `From` address. */\n from: string;\n /** Envelope `To` addresses. */\n to: string[];\n /** Subject line — the record's level and logger, with an occurrence count appended on a deduped follow-up. */\n subject: string;\n /** Plain-text body: the message, occurrence count, timestamp, and JSON-serialized `meta`. */\n text: string;\n}\n\n/** Sends one email message. Swap in a fake for tests. */\nexport type EmailSender = (message: EmailMessage) => Promise<void> | void;\n\n/** The subset of a `nodemailer` transporter that `EmailAlertPlugin` needs. */\nexport interface NodemailerTransporterLike {\n /** Sends one message; matches `nodemailer`'s own `Transporter.sendMail`. */\n sendMail(message: { from: string; to: string; subject: string; text: string }): Promise<unknown>;\n}\n\n/** Options for {@link EmailAlertPlugin}. */\nexport interface EmailAlertPluginOptions extends AlertingPluginOptions {\n /** SMTP server hostname. */\n smtpHost: string;\n /** SMTP server port. */\n smtpPort: number;\n /** Envelope `From` address for every alert. */\n fromAddr: string;\n /** Envelope `To` addresses for every alert. */\n toAddrs: string[];\n /** SMTP auth username. Only used if `password` is also set. */\n username?: string;\n /** SMTP auth password. Only used if `username` is also set. */\n password?: string;\n /** `false` for an SMTP server that doesn't support STARTTLS (e.g. a local relay). Default `true`. */\n useTls?: boolean;\n /** Pre-built sender, e.g. for tests. Skips the `nodemailer` auto-import entirely. */\n sender?: EmailSender;\n}\n\n/**\n * Sends deduplicated `AlertingPlugin` alerts by email over SMTP.\n *\n * `nodemailer` is an optional peer dependency: install it yourself, or\n * pass `sender` to swap in a fake for tests or an alternate backend —\n * `username`/`password` are only used if both are set.\n */\nexport class EmailAlertPlugin extends AlertingPlugin {\n /** SMTP server hostname. */\n readonly smtpHost: string;\n /** SMTP server port. */\n readonly smtpPort: number;\n /** Envelope `From` address for every alert. */\n readonly fromAddr: string;\n /** Envelope `To` addresses for every alert. */\n readonly toAddrs: string[];\n private readonly username: string | undefined;\n private readonly password: string | undefined;\n private readonly useTls: boolean;\n private readonly injectedSender: EmailSender | undefined;\n private transporter: NodemailerTransporterLike | undefined;\n\n constructor(options: EmailAlertPluginOptions) {\n super(options);\n this.smtpHost = options.smtpHost;\n this.smtpPort = options.smtpPort;\n this.fromAddr = options.fromAddr;\n this.toAddrs = options.toAddrs;\n this.username = options.username;\n this.password = options.password;\n this.useTls = options.useTls ?? true;\n this.injectedSender = options.sender;\n }\n\n protected async sendAlert(record: LogRecord, occurrences: number): Promise<void> {\n let subject = `[${record.level}] ${record.logger}`;\n if (occurrences > 1) {\n subject += ` (x${String(occurrences)})`;\n }\n const text = [\n record.message,\n \"\",\n `occurrences: ${String(occurrences)}`,\n `timestamp: ${record.timestamp}`,\n `meta: ${JSON.stringify(record.meta)}`,\n ].join(\"\\n\");\n const message: EmailMessage = { from: this.fromAddr, to: this.toAddrs, subject, text };\n\n if (this.injectedSender) {\n await this.injectedSender(message);\n return;\n }\n\n const transporter = this.transporter ?? (await this.importTransporter());\n await transporter.sendMail({ from: message.from, to: message.to.join(\", \"), subject: message.subject, text: message.text });\n }\n\n private async importTransporter(): Promise<NodemailerTransporterLike> {\n let createTransport: (options: Record<string, unknown>) => NodemailerTransporterLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"nodemailer\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { createTransport?: (options: Record<string, unknown>) => NodemailerTransporterLike };\n createTransport?: (options: Record<string, unknown>) => NodemailerTransporterLike;\n };\n const resolved = mod.default?.createTransport ?? mod.createTransport;\n if (!resolved) {\n throw new Error(\"no createTransport export found\");\n }\n createTransport = resolved;\n } catch {\n throw new Error(\n \"EmailAlertPlugin: install `nodemailer` to use this plugin without providing a `sender` — `npm install nodemailer`\",\n );\n }\n\n this.transporter = createTransport({\n host: this.smtpHost,\n port: this.smtpPort,\n secure: false,\n requireTLS: this.useTls,\n auth: this.username && this.password ? { user: this.username, pass: this.password } : undefined,\n });\n return this.transporter;\n }\n}\n","import { JSONFormatter, type Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\n\n/**\n * Sink for log records, per the cross-language transport contract:\n * `format(record) -> string`, `write(formatted, record)`, `close()` on shutdown.\n */\nexport abstract class Transport {\n /** Turns a `LogRecord` into the string this transport actually writes. Defaults to `JSONFormatter`. */\n formatter: Formatter;\n\n constructor(formatter: Formatter = new JSONFormatter()) {\n this.formatter = formatter;\n }\n\n /** Formats `record` via `this.formatter`. Called once per record before `write()`. */\n format(record: LogRecord): string {\n return this.formatter.format(record);\n }\n\n /** Sends the already-formatted record to this transport's sink. */\n abstract write(formatted: string, record: LogRecord): void;\n\n /** Flush/release resources on shutdown. No-op unless a transport overrides it. */\n close(): void {}\n}\n\n/** Duck-typed: a transport (typically a `BatchingTransport`) whose `flush()` sends its current buffer now, without closing. */\nexport interface FlushableTransport {\n /** Sends the current buffer now, even if it hasn't reached its own flush threshold. */\n flush(): void | Promise<void>;\n}\n\n/** Type guard for {@link FlushableTransport} — true for any transport (e.g. every `BatchingTransport`) that exposes a `flush()` method. */\nexport function hasFlush(transport: Transport): transport is Transport & FlushableTransport {\n return typeof (transport as Partial<FlushableTransport>).flush === \"function\";\n}\n\n/** In-memory transport for tests: collects every (formatted, record) pair written to it. */\nexport class CollectingTransport extends Transport {\n /** Every formatted string passed to `write()`, in call order. */\n readonly formatted: string[] = [];\n /** Every raw `LogRecord` passed to `write()`, in call order. */\n readonly records: LogRecord[] = [];\n /** Set once `close()` has been called. */\n closed = false;\n\n write(formatted: string, record: LogRecord): void {\n this.formatted.push(formatted);\n this.records.push(record);\n }\n\n override close(): void {\n this.closed = true;\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Options for {@link BatchingTransport} and every concrete batching transport that extends it. */\nexport interface BatchingTransportOptions {\n /** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */\n formatter?: Formatter;\n /** Flush once the buffer holds this many items. Default 100. */\n maxRecords?: number;\n /** Flush once the buffer's estimated byte size reaches this many bytes. Default 1_000_000 (1MB). */\n maxBytes?: number;\n}\n\n/**\n * Shared base for every batching sink transport (SQL, NoSQL, message queues,\n * batching cloud-native transports). Buffers items and flushes once either\n * `maxRecords` or `maxBytes` is reached, so no batching transport can grow\n * its buffer unboundedly under a sustained burst.\n *\n * `write()`/`close()` stay non-blocking from the caller's perspective: a\n * failed `sendBatch()` is reported via `console.error` rather than thrown,\n * matching `HTTPTransport`'s contract.\n */\nexport abstract class BatchingTransport<T = LogRecord> extends Transport {\n /** Buffer is flushed once it holds this many items. */\n readonly maxRecords: number;\n /** Buffer is flushed once its estimated byte size reaches this many bytes. */\n readonly maxBytes: number;\n private buffer: T[] = [];\n private bufferBytes = 0;\n\n constructor(options: BatchingTransportOptions = {}) {\n super(options.formatter);\n this.maxRecords = options.maxRecords ?? 100;\n this.maxBytes = options.maxBytes ?? 1_000_000;\n }\n\n /** Converts a written record into the buffered item type. Defaults to the record itself. */\n protected toItem(formatted: string, record: LogRecord): T {\n void formatted;\n return record as unknown as T;\n }\n\n /** Estimated byte size of one buffered item, used for the `maxBytes` bound. */\n protected sizeOf(item: T): number {\n return JSON.stringify(item).length;\n }\n\n /** Buffers the record, flushing the batch once `maxRecords`/`maxBytes` is reached. */\n write(formatted: string, record: LogRecord): void {\n const item = this.toItem(formatted, record);\n this.buffer.push(item);\n this.bufferBytes += this.sizeOf(item);\n if (this.buffer.length >= this.maxRecords || this.bufferBytes >= this.maxBytes) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached a bound. */\n flush(): void {\n if (this.buffer.length === 0) {\n return;\n }\n const batch = this.buffer;\n this.buffer = [];\n this.bufferBytes = 0;\n\n const result = this.sendBatch(batch);\n if (result) {\n result.catch((error: unknown) => {\n console.error(`${this.constructor.name}: failed to send log batch`, error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n\n /** Deliver one batch to the backend. Always called with a non-empty batch. */\n protected abstract sendBatch(batch: readonly T[]): Promise<void> | void;\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One row of the fixed `logs` table schema shared across every SQL transport. */\nexport interface SQLLogRow {\n /** `record.timestamp`, as ISO8601. */\n timestamp: string;\n /** `record.level`. */\n level: string;\n /** `record.logger`. */\n logger: string;\n /** `record.message`. */\n message: string;\n /** `record.meta`, JSON-serialized — every SQL dialect can store this as TEXT/JSON/JSONB. */\n meta: string;\n /** `record.meta.runId`, if present. */\n runId: string | null;\n /** `record.meta.spanId`, if present. */\n spanId: string | null;\n /** `record.meta.parentSpanId`, if present. */\n parentSpanId: string | null;\n /** `record.meta.traceId`, if present. */\n traceId: string | null;\n}\n\n/** Options for {@link BaseSQLTransport} and every concrete SQL transport that extends it. */\nexport interface BaseSQLTransportOptions extends BatchingTransportOptions {\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /**\n * Dev/test convenience only: run `createTableSQL()` before the first insert.\n * Production schema/migrations are the caller's responsibility — never\n * auto-create schema unless this is explicitly set. Default `false`.\n */\n ensureSchema?: boolean;\n}\n\nfunction metaString(meta: Record<string, unknown>, key: string): string | null {\n const value = meta[key];\n return typeof value === \"string\" ? value : null;\n}\n\n/**\n * Abstract base for every SQL transport (`SQLiteTransport`, `PostgresTransport`,\n * `MySQLTransport`, ...). Owns the fixed schema and the record → row mapping;\n * each driver-specific subclass only implements `ensureTable()`/`insertRows()`.\n * Inserts are always batched — never one query per log call.\n */\nexport abstract class BaseSQLTransport extends BatchingTransport<SQLLogRow> {\n /** Table records are inserted into. */\n readonly tableName: string;\n /** Whether `createTableSQL()` runs before the first insert. Dev/test convenience only. */\n readonly ensureSchema: boolean;\n private schemaEnsured = false;\n\n constructor(options: BaseSQLTransportOptions = {}) {\n super(options);\n this.tableName = options.tableName ?? \"logs\";\n this.ensureSchema = options.ensureSchema ?? false;\n }\n\n protected override toItem(_formatted: string, record: LogRecord): SQLLogRow {\n void _formatted;\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n runId: metaString(record.meta, \"runId\"),\n spanId: metaString(record.meta, \"spanId\"),\n parentSpanId: metaString(record.meta, \"parentSpanId\"),\n traceId: metaString(record.meta, \"traceId\"),\n };\n }\n\n protected override sizeOf(row: SQLLogRow): number {\n return row.message.length + row.meta.length + 96;\n }\n\n /**\n * Minimal, dialect-generic `CREATE TABLE IF NOT EXISTS` for dev/test use via\n * `ensureSchema: true`. Production deployments should manage this table with\n * a real migration instead — override in a subclass for dialect-correct\n * column types (e.g. `JSONB` on Postgres).\n */\n createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta TEXT NOT NULL,\n runId TEXT,\n spanId TEXT,\n parentSpanId TEXT,\n traceId TEXT\n)`;\n }\n\n protected override async sendBatch(rows: readonly SQLLogRow[]): Promise<void> {\n if (this.ensureSchema && !this.schemaEnsured) {\n // Set before awaiting: a synchronous second flush (e.g. maxRecords: 1)\n // must not re-trigger ensureTable() while the first call is in flight.\n this.schemaEnsured = true;\n await this.ensureTable();\n }\n await this.insertRows(rows);\n }\n\n /** Only invoked when `ensureSchema: true` was explicitly passed. */\n protected abstract ensureTable(): Promise<void>;\n\n /** Always-batched insert of every row in `rows` — never one query per row. */\n protected abstract insertRows(rows: readonly SQLLogRow[]): Promise<void>;\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `better-sqlite3` prepared statement that `SQLiteTransport` needs. */\nexport interface SQLiteStatementLike {\n /** Executes the prepared statement with `params` bound positionally. */\n run(...params: unknown[]): unknown;\n}\n\n/** The subset of a `better-sqlite3` `Database` that `SQLiteTransport` needs. Inject a fake in tests. */\nexport interface SQLiteClientLike {\n /** Runs one or more SQL statements with no return value, e.g. `createTableSQL()`. */\n exec(sql: string): unknown;\n /** Compiles `sql` into a reusable, repeatedly-`run`-able statement. */\n prepare(sql: string): SQLiteStatementLike;\n /** Wraps `fn` so every call runs inside a single SQLite transaction. */\n transaction<Args extends unknown[]>(fn: (...args: Args) => void): (...args: Args) => void;\n}\n\nexport interface SQLiteTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client, e.g. for tests. Skips the `better-sqlite3` auto-import entirely. */\n client?: SQLiteClientLike;\n /** Passed to `better-sqlite3` when no `client` is injected. Default `\":memory:\"`. */\n filename?: string;\n}\n\n/**\n * Zero-setup SQL sink — no server process, just a local (or in-memory) file\n * via `better-sqlite3`. Useful for local dev and pairs with the CLI trace\n * viewer (v2.0), which can read this file directly.\n *\n * `better-sqlite3` is an optional peer dependency: install it yourself, or\n * inject a `client` (e.g. a fake, or an already-open `Database` instance).\n */\nexport class SQLiteTransport extends BaseSQLTransport {\n private readonly injectedClient: SQLiteClientLike | undefined;\n private readonly filename: string;\n private client: SQLiteClientLike | undefined;\n\n constructor(options: SQLiteTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.filename = options.filename ?? \":memory:\";\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQLiteClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQLiteClientLike> {\n let DatabaseCtor: new (filename: string) => SQLiteClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"better-sqlite3\";\n const mod = (await import(moduleName)) as unknown as {\n default: new (filename: string) => SQLiteClientLike;\n };\n DatabaseCtor = mod.default;\n } catch {\n throw new Error(\n \"SQLiteTransport: install `better-sqlite3` to use this transport without providing a client — `npm install better-sqlite3`\",\n );\n }\n\n this.client = new DatabaseCtor(this.filename);\n return this.client;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n client.exec(this.createTableSQL());\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const stmt = client.prepare(\n `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n );\n const insertMany = client.transaction((batch: readonly SQLLogRow[]) => {\n for (const row of batch) {\n stmt.run(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n });\n insertMany(rows);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `pg` `Pool`/`Client` that `PostgresTransport` needs. Inject a fake in tests. */\nexport interface PgClientLike {\n /** Runs a parameterized query, matching `pg`'s own `Pool`/`Client.query(text, values)`. */\n query(text: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface PostgresTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `pg.Pool`/`pg.Client`. Skips the `pg` auto-import entirely. */\n client?: PgClientLike;\n /** Passed to `pg.Pool` when no `client` is injected, e.g. `\"postgres://user:pass@host:5432/db\"`. */\n connectionString?: string;\n /** Passed to `pg.Pool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by Postgres via `pg`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `pg` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Pool`/`Client` instance).\n */\nexport class PostgresTransport extends BaseSQLTransport {\n private readonly injectedClient: PgClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: PgClientLike | undefined;\n\n constructor(options: PostgresTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PgClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PgClientLike> {\n let PoolCtor: new (config?: Record<string, unknown>) => PgClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"pg\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { Pool?: new (config?: Record<string, unknown>) => PgClientLike };\n Pool?: new (config?: Record<string, unknown>) => PgClientLike;\n };\n const resolved = mod.default?.Pool ?? mod.Pool;\n if (!resolved) {\n throw new Error(\"no Pool export found\");\n }\n PoolCtor = resolved;\n } catch {\n throw new Error(\n \"PostgresTransport: install `pg` to use this transport without providing a client — `npm install pg`\",\n );\n }\n\n const config = this.connectionString\n ? { connectionString: this.connectionString }\n : (this.connectionConfig ?? {});\n this.client = new PoolCtor(config);\n return this.client;\n }\n\n /** Postgres-correct `CREATE TABLE IF NOT EXISTS`: `SERIAL` primary key, `JSONB` for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id SERIAL PRIMARY KEY,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n logger TEXT NOT NULL,\n message TEXT NOT NULL,\n meta JSONB NOT NULL,\n \"runId\" TEXT,\n \"spanId\" TEXT,\n \"parentSpanId\" TEXT,\n \"traceId\" TEXT\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.query(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n rows.forEach((row, rowIndex) => {\n const base = rowIndex * columns;\n placeholders.push(\n `(${Array.from({ length: columns }, (_, col) => `$${String(base + col + 1)}`).join(\", \")})`,\n );\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n });\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, \"runId\", \"spanId\", \"parentSpanId\", \"traceId\") VALUES ${placeholders.join(\", \")}`;\n await client.query(sql, values);\n }\n}\n","import { BaseSQLTransport, type BaseSQLTransportOptions, type SQLLogRow } from \"./base-sql-transport.js\";\n\n/** The subset of a `mysql2/promise` connection/pool that `MySQLTransport` needs. Inject a fake in tests. */\nexport interface MySQLClientLike {\n /** Runs a parameterized query, matching `mysql2`'s own `Connection`/`Pool.execute(sql, values)`. */\n execute(sql: string, values: unknown[]): Promise<unknown>;\n}\n\nexport interface MySQLTransportOptions extends BaseSQLTransportOptions {\n /** Pre-built client/pool, e.g. for tests, or an already-open `mysql2/promise` `Pool`/`Connection`. Skips the `mysql2` auto-import entirely. */\n client?: MySQLClientLike;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected, e.g. `\"mysql://user:pass@host:3306/db\"`. */\n connectionString?: string;\n /** Passed to `mysql2/promise`'s `createPool` when no `client` is injected and `connectionString` isn't used. */\n connectionConfig?: Record<string, unknown>;\n}\n\n/**\n * SQL sink backed by MySQL via `mysql2`. Builds one parameterized multi-row\n * `INSERT` per batch — never one query per log call — matching the\n * always-batched contract every `BaseSQLTransport` subclass shares.\n *\n * `mysql2` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open pool/connection from\n * `mysql2/promise`).\n */\nexport class MySQLTransport extends BaseSQLTransport {\n private readonly injectedClient: MySQLClientLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly connectionConfig: Record<string, unknown> | undefined;\n private client: MySQLClientLike | undefined;\n\n constructor(options: MySQLTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.connectionString = options.connectionString;\n this.connectionConfig = options.connectionConfig;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): MySQLClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<MySQLClientLike> {\n let createPool: (target: string | Record<string, unknown>) => MySQLClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mysql2/promise\";\n const mod = (await import(moduleName)) as unknown as {\n default?: { createPool?: (target: string | Record<string, unknown>) => MySQLClientLike };\n createPool?: (target: string | Record<string, unknown>) => MySQLClientLike;\n };\n const resolved = mod.default?.createPool ?? mod.createPool;\n if (!resolved) {\n throw new Error(\"no createPool export found\");\n }\n createPool = resolved;\n } catch {\n throw new Error(\n \"MySQLTransport: install `mysql2` to use this transport without providing a client — `npm install mysql2`\",\n );\n }\n\n const target = this.connectionString ?? this.connectionConfig ?? {};\n this.client = createPool(target);\n return this.client;\n }\n\n /** MySQL-correct `CREATE TABLE IF NOT EXISTS`: `AUTO_INCREMENT` primary key, `JSON` column type for `meta`. */\n override createTableSQL(): string {\n return `CREATE TABLE IF NOT EXISTS ${this.tableName} (\n id INT AUTO_INCREMENT PRIMARY KEY,\n timestamp VARCHAR(64) NOT NULL,\n level VARCHAR(16) NOT NULL,\n logger VARCHAR(255) NOT NULL,\n message TEXT NOT NULL,\n meta JSON NOT NULL,\n runId VARCHAR(255),\n spanId VARCHAR(255),\n parentSpanId VARCHAR(255),\n traceId VARCHAR(255)\n)`;\n }\n\n protected async ensureTable(): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.execute(this.createTableSQL(), []);\n }\n\n protected async insertRows(rows: readonly SQLLogRow[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const columns = 9;\n const values: unknown[] = [];\n const placeholders: string[] = [];\n for (const row of rows) {\n placeholders.push(`(${Array.from({ length: columns }, () => \"?\").join(\", \")})`);\n values.push(\n row.timestamp,\n row.level,\n row.logger,\n row.message,\n row.meta,\n row.runId,\n row.spanId,\n row.parentSpanId,\n row.traceId,\n );\n }\n\n const sql = `INSERT INTO ${this.tableName} (timestamp, level, logger, message, meta, runId, spanId, parentSpanId, traceId) VALUES ${placeholders.join(\", \")}`;\n await client.execute(sql, values);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `mongodb` `Collection` that `MongoDBTransport` needs. Inject a fake in tests. */\nexport interface MongoCollectionLike {\n /** Inserts every document in one call, matching `mongodb`'s own `Collection.insertMany()`. */\n insertMany(docs: readonly unknown[]): Promise<unknown>;\n}\n\n/** The subset of a `mongodb` `MongoClient` that `MongoDBTransport` needs to lazily connect. */\nexport interface MongoClientLike {\n /** Opens the connection, matching `mongodb`'s own `MongoClient.connect()`. */\n connect(): Promise<unknown>;\n /** Returns a database handle, from which a collection is looked up by name. */\n db(name: string): {\n /** Returns a collection handle for `name`, matching `mongodb`'s own `Db.collection()`. */\n collection(name: string): MongoCollectionLike;\n };\n}\n\n/** Options for {@link MongoDBTransport}. */\nexport interface MongoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built collection, e.g. for tests, or an already-connected app. Skips the `mongodb` auto-import entirely. */\n collection?: MongoCollectionLike;\n /** `mongodb` connection string, used when no `collection` is injected. Required in that case. */\n connectionString?: string;\n /** Database to write into when connecting via `connectionString`. Default `\"logquill\"`. */\n database?: string;\n /** Collection to write into when connecting via `connectionString`. Default `\"logs\"`. */\n collectionName?: string;\n}\n\n/**\n * Sink for MongoDB. Records map 1:1 to documents — no JSON-in-a-column\n * workaround needed, unlike the SQL transports.\n *\n * `mongodb` is an optional peer dependency: install it yourself, or inject a\n * `collection` (e.g. a fake, or a `Collection` from a client your app already\n * manages).\n */\nexport class MongoDBTransport extends BatchingTransport {\n private readonly injectedCollection: MongoCollectionLike | undefined;\n private readonly connectionString: string | undefined;\n private readonly database: string;\n private readonly collectionName: string;\n private collection: MongoCollectionLike | undefined;\n\n constructor(options: MongoDBTransportOptions = {}) {\n super(options);\n this.injectedCollection = options.collection;\n this.connectionString = options.connectionString;\n this.database = options.database ?? \"logquill\";\n this.collectionName = options.collectionName ?? \"logs\";\n }\n\n /** Synchronously available collection, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedCollection(): MongoCollectionLike | undefined {\n return this.injectedCollection ?? this.collection;\n }\n\n private async importCollection(): Promise<MongoCollectionLike> {\n if (!this.connectionString) {\n throw new Error(\n \"MongoDBTransport: provide either a `collection` or a `connectionString` to connect with — neither was given\",\n );\n }\n\n let MongoClientCtor: new (connectionString: string) => MongoClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"mongodb\";\n const mod = (await import(moduleName)) as unknown as {\n MongoClient: new (connectionString: string) => MongoClientLike;\n };\n MongoClientCtor = mod.MongoClient;\n } catch {\n throw new Error(\n \"MongoDBTransport: install `mongodb` to use this transport without providing a client — `npm install mongodb`\",\n );\n }\n\n const client = new MongoClientCtor(this.connectionString);\n await client.connect();\n this.collection = client.db(this.database).collection(this.collectionName);\n return this.collection;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const collection = this.resolvedCollection() ?? (await this.importCollection());\n // Records already match the cross-language JSON record shape, so each one\n // becomes a document as-is — spread to give Mongo a fresh plain object per doc.\n await collection.insertMany(batch.map((record) => ({ ...record })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** DynamoDB's hard cap on items per `BatchWriteItem` call — respected by chunking within `sendBatch()`. */\nconst DYNAMO_BATCH_LIMIT = 25;\n\n/** One item written to DynamoDB: `runId` is the partition key, `timestamp` is the sort key. */\nexport interface DynamoLogItem {\n /** Partition key: `record.meta.runId`, else `record.meta.traceId`, else the logger name. */\n runId: string;\n /** Sort key: `record.timestamp`, as ISO8601. */\n timestamp: string;\n /** `record.level`. */\n level: string;\n /** `record.logger`. */\n logger: string;\n /** `record.message`. */\n message: string;\n /** `record.meta`, stored as-is (DynamoDB items are schemaless). */\n meta: Record<string, unknown>;\n /** `record.meta.spanId`, if present. */\n spanId?: string;\n /** `record.meta.parentSpanId`, if present. */\n parentSpanId?: string;\n /** `record.meta.traceId`, if present. */\n traceId?: string;\n}\n\n/**\n * The subset of DynamoDB write access `DynamoDBTransport` needs, deliberately\n * narrower than the AWS SDK v3 command pattern (`send(command)`): one\n * `BatchWriteItem`-equivalent call per sub-batch, already capped at\n * `DYNAMO_BATCH_LIMIT` items by the caller. This keeps fake-based tests\n * trivial — a fake just needs to record `(tableName, items)` calls, not\n * emulate a `DynamoDBClient`. Inject a fake in tests, or rely on the built-in\n * `@aws-sdk/client-dynamodb` wrapper by not injecting a `client`.\n */\nexport interface DynamoClientLike {\n /** Writes one chunk of items (already capped at `DYNAMO_BATCH_LIMIT`) to `tableName` via a `BatchWriteItem`-equivalent call. */\n batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown>;\n}\n\n/** Options for {@link DynamoDBTransport}. */\nexport interface DynamoDBTransportOptions extends BatchingTransportOptions {\n /** Pre-built client, e.g. for tests, or a custom wrapper. Skips the `@aws-sdk/client-dynamodb` auto-import entirely. */\n client?: DynamoClientLike;\n /** Table to write into. Default `\"logs\"`. */\n tableName?: string;\n /** AWS region, used when no `client` is injected. Falls back to the SDK's own credential-chain resolution when omitted. */\n region?: string;\n}\n\n/** Minimal JS -> DynamoDB `AttributeValue` marshaller for the real-SDK code path, so this transport doesn't need `@aws-sdk/util-dynamodb` as a second peer dependency just to build one request shape. */\nfunction toAttributeValue(value: unknown): Record<string, unknown> {\n if (value === null || value === undefined) {\n return { NULL: true };\n }\n if (typeof value === \"string\") {\n return { S: value };\n }\n if (typeof value === \"number\") {\n return { N: String(value) };\n }\n if (typeof value === \"boolean\") {\n return { BOOL: value };\n }\n if (typeof value === \"bigint\") {\n return { N: value.toString() };\n }\n if (Array.isArray(value)) {\n return { L: value.map((entry) => toAttributeValue(entry)) };\n }\n if (typeof value === \"object\") {\n const m: Record<string, unknown> = {};\n for (const [key, entryValue] of Object.entries(value as Record<string, unknown>)) {\n m[key] = toAttributeValue(entryValue);\n }\n return { M: m };\n }\n // Functions/symbols aren't serializable log data — drop rather than stringify unpredictably.\n return { NULL: true };\n}\n\nfunction marshallItem(item: DynamoLogItem): Record<string, unknown> {\n return toAttributeValue({ ...item }).M as Record<string, unknown>;\n}\n\n/**\n * Sink for Amazon DynamoDB. Partition key is `runId`/`traceId` (whichever is\n * present on `record.meta`, `runId` taking priority), falling back to the\n * logger name when neither is set, so every record always lands under some\n * partition even before `RunPlugin`/`TraceContextPlugin` are wired up. Sort\n * key is `timestamp`.\n *\n * DynamoDB's actual `BatchWriteItem` API caps a call at 25 items, so\n * `sendBatch()` chunks a larger batch into sub-batches of 25 — matching how\n * `SQSTransport` respects `SendMessageBatch`'s 10-item cap.\n *\n * `@aws-sdk/client-dynamodb` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a custom wrapper around a\n * `DynamoDBClient` your app already manages).\n */\nexport class DynamoDBTransport extends BatchingTransport {\n private readonly injectedClient: DynamoClientLike | undefined;\n private readonly tableName: string;\n private readonly region: string | undefined;\n private client: DynamoClientLike | undefined;\n\n constructor(options: DynamoDBTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.tableName = options.tableName ?? \"logs\";\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): DynamoClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<DynamoClientLike> {\n let DynamoDBClientCtor: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n let BatchWriteItemCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-dynamodb\";\n const mod = (await import(moduleName)) as unknown as {\n DynamoDBClient: new (config: { region?: string }) => { send(command: unknown): Promise<unknown> };\n BatchWriteItemCommand: new (input: unknown) => unknown;\n };\n DynamoDBClientCtor = mod.DynamoDBClient;\n BatchWriteItemCommandCtor = mod.BatchWriteItemCommand;\n } catch {\n throw new Error(\n \"DynamoDBTransport: install `@aws-sdk/client-dynamodb` to use this transport without providing a client — `npm install @aws-sdk/client-dynamodb`\",\n );\n }\n\n const sdkClient = new DynamoDBClientCtor(this.region ? { region: this.region } : {});\n this.client = {\n async batchWriteItems(tableName: string, items: readonly DynamoLogItem[]): Promise<unknown> {\n const requestItems = {\n [tableName]: items.map((item) => ({ PutRequest: { Item: marshallItem(item) } })),\n };\n return sdkClient.send(new BatchWriteItemCommandCtor({ RequestItems: requestItems }));\n },\n };\n return this.client;\n }\n\n /** `meta.runId`, else `meta.traceId`, else the logger name — see the class doc for why. */\n private partitionKey(record: LogRecord): string {\n const runId = record.meta.runId;\n if (typeof runId === \"string\" && runId.length > 0) {\n return runId;\n }\n const traceId = record.meta.traceId;\n if (typeof traceId === \"string\" && traceId.length > 0) {\n return traceId;\n }\n return record.logger;\n }\n\n private toDynamoItem(record: LogRecord): DynamoLogItem {\n const spanId = record.meta.spanId;\n const parentSpanId = record.meta.parentSpanId;\n const traceId = record.meta.traceId;\n return {\n runId: this.partitionKey(record),\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: record.meta,\n ...(typeof spanId === \"string\" ? { spanId } : {}),\n ...(typeof parentSpanId === \"string\" ? { parentSpanId } : {}),\n ...(typeof traceId === \"string\" ? { traceId } : {}),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const items = batch.map((record) => this.toDynamoItem(record));\n const chunks: DynamoLogItem[][] = [];\n for (let offset = 0; offset < items.length; offset += DYNAMO_BATCH_LIMIT) {\n chunks.push(items.slice(offset, offset + DYNAMO_BATCH_LIMIT));\n }\n // Dispatched concurrently rather than one-at-a-time: each sub-batch is an\n // independent BatchWriteItem call, and issuing them together (instead of\n // serially awaiting each) is both higher-throughput and keeps every call\n // in a sub-batch-sized flush starting in the same tick `sendBatch` runs.\n await Promise.all(chunks.map((chunk) => client.batchWriteItems(this.tableName, chunk)));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `redis` (node-redis v4) client that `RedisTransport` needs. Inject a fake in tests. */\nexport interface RedisClientLike {\n /** Appends one entry to `stream`, matching `node-redis`'s own `client.xAdd()`. */\n xAdd(stream: string, id: string, fields: Record<string, string>): Promise<unknown>;\n}\n\n/** Options for {@link RedisTransport}. */\nexport interface RedisTransportOptions extends BatchingTransportOptions {\n /** Pre-built, already-connected client, e.g. for tests. Skips the `redis` auto-import entirely. */\n client?: RedisClientLike;\n /** `redis` connection URL, used when no `client` is injected. Default `\"redis://localhost:6379\"`. */\n url?: string;\n /** Stream key to `XADD` into. Default `\"logquill:logs\"`. */\n stream?: string;\n}\n\n/**\n * Sink for Redis, via Redis Streams (`XADD`) — a fast local buffer, a\n * different use case from durable storage, not a replacement for the\n * others. Reach for this when you want a low-latency\n * local tail (e.g. feeding a `redis-cli XREAD`-based live viewer) rather than\n * a system of record.\n *\n * Streams has no true multi-entry `XADD`, so unlike the other batching\n * transports this issues one `XADD` per record within the batch rather than\n * one network call per batch — batching here still bounds memory and reduces\n * GC/buffer churn, but it is honestly not a network-call batch the way\n * `MongoDBTransport.insertMany()` or `DynamoDBTransport`'s `BatchWriteItem`\n * chunks are.\n *\n * `redis` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-connected client your app manages).\n */\nexport class RedisTransport extends BatchingTransport {\n private readonly injectedClient: RedisClientLike | undefined;\n private readonly url: string;\n private readonly stream: string;\n private client: RedisClientLike | undefined;\n\n constructor(options: RedisTransportOptions = {}) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"redis://localhost:6379\";\n this.stream = options.stream ?? \"logquill:logs\";\n }\n\n /** Synchronously available client, if one was injected or already connected — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): RedisClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<RedisClientLike> {\n let createClient: (options: {\n url: string;\n }) => RedisClientLike & { connect(): Promise<unknown> };\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"redis\";\n const mod = (await import(moduleName)) as unknown as {\n createClient: (options: {\n url: string;\n }) => RedisClientLike & { connect(): Promise<unknown> };\n };\n createClient = mod.createClient;\n } catch {\n throw new Error(\n \"RedisTransport: install `redis` to use this transport without providing a client — `npm install redis`\",\n );\n }\n\n const client = createClient({ url: this.url });\n await client.connect();\n this.client = client;\n return client;\n }\n\n private toFields(record: LogRecord): Record<string, string> {\n return {\n timestamp: record.timestamp,\n level: record.level,\n logger: record.logger,\n message: record.message,\n meta: JSON.stringify(record.meta),\n };\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // One XADD per record, all issued together rather than serially awaited —\n // see the class doc for why Streams can't take a single multi-entry append.\n await Promise.all(batch.map((record) => client.xAdd(this.stream, \"*\", this.toFields(record))));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Options for {@link BaseQueueTransport} and every concrete queue transport that extends it. */\nexport interface BaseQueueTransportOptions extends BatchingTransportOptions {\n /**\n * Destination name on the backend — a Kafka topic, a RabbitMQ queue name,\n * an SQS queue URL, or a GCP Pub/Sub topic. One generic option name so the\n * base class's orchestration stays backend-agnostic; each subclass's own\n * docs use its backend's own vocabulary for what this means.\n */\n topic: string;\n}\n\n/**\n * Abstract base for every message-queue transport (`KafkaTransport`,\n * `RabbitMQTransport`, `SQSTransport`, `PubSubTransport`). Owns the \"always\n * batch, never publish one message per log call\" contract shared across\n * every queue backend — buffering itself is inherited from\n * `BatchingTransport`; each concrete subclass only implements\n * `publishBatch()` against its own driver's publish API.\n */\nexport abstract class BaseQueueTransport extends BatchingTransport {\n /** Destination name on the backend — a Kafka topic, a RabbitMQ queue name, an SQS queue URL, or a GCP Pub/Sub topic. */\n readonly topic: string;\n\n constructor(options: BaseQueueTransportOptions) {\n super(options);\n this.topic = options.topic;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> {\n return this.publishBatch(batch);\n }\n\n /** Deliver one batch of records to the queue backend. Always called with a non-empty batch. */\n protected abstract publishBatch(records: readonly LogRecord[]): Promise<void>;\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of a `kafkajs` `Producer` that `KafkaTransport` needs. Inject a fake in tests. */\nexport interface KafkaProducerLike {\n /** Optional: some injected producers (or fakes) are already connected. */\n connect?(): Promise<void>;\n /** Publishes one batch of messages to a topic, matching `kafkajs`'s own `Producer.send()`. */\n send(record: { topic: string; messages: { key: string | null; value: string }[] }): Promise<unknown>;\n}\n\nexport interface KafkaTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built producer, e.g. for tests, or an already-configured kafkajs `Producer`. Skips the `kafkajs` auto-import entirely. */\n client?: KafkaProducerLike;\n /** Broker addresses passed to `kafkajs`'s `Kafka({ brokers })` when no `client` is injected. Default `[\"localhost:9092\"]`. */\n brokers?: string[];\n}\n\nfunction metaKey(meta: Record<string, unknown>, key: string): string | undefined {\n const value = meta[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Publishes batches to a Kafka topic via `kafkajs`. Each message's `key` is\n * set to `meta.runId` (falling back to `meta.traceId`, then `null`), so\n * kafkajs's default partitioner keeps every message from the same agent\n * run/trace on one partition — preserving per-trace ordering, per the\n * message-queue contract in the project spec.\n *\n * `kafkajs` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-configured `Producer`).\n */\nexport class KafkaTransport extends BaseQueueTransport {\n private readonly injectedClient: KafkaProducerLike | undefined;\n private readonly brokers: string[];\n private client: KafkaProducerLike | undefined;\n\n constructor(options: KafkaTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.brokers = options.brokers ?? [\"localhost:9092\"];\n }\n\n /** Synchronously available producer, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): KafkaProducerLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Builds the real `kafkajs` producer and connects it. Connection happens\n * here, once, as part of acquiring the driver — not on every\n * `publishBatch()` call — so an injected `client` (tests, or a caller's\n * own already-connected producer) is trusted to already be ready and is\n * never re-connected.\n */\n private async importClient(): Promise<KafkaProducerLike> {\n let producer: KafkaProducerLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"kafkajs\";\n const mod = (await import(moduleName)) as unknown as {\n Kafka: new (config: { brokers: string[] }) => { producer(): KafkaProducerLike };\n };\n producer = new mod.Kafka({ brokers: this.brokers }).producer();\n await producer.connect?.();\n } catch {\n throw new Error(\n \"KafkaTransport: install `kafkajs` to use this transport without providing a client — `npm install kafkajs`\",\n );\n }\n\n this.client = producer;\n return producer;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n await client.send({\n topic: this.topic,\n messages: records.map((record) => ({\n key: metaKey(record.meta, \"runId\") ?? metaKey(record.meta, \"traceId\") ?? null,\n value: JSON.stringify(record),\n })),\n });\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** The subset of an `amqplib` `Channel` that `RabbitMQTransport` needs. Inject a fake in tests. */\nexport interface AmqpChannelLike {\n /** Optional: only called once, and only when provided, to ensure the queue exists. */\n assertQueue?(queue: string, options?: unknown): Promise<unknown>;\n /** Publishes one message directly to `queue`, matching `amqplib`'s own `Channel.sendToQueue()`. */\n sendToQueue(queue: string, content: Buffer, options?: unknown): boolean;\n}\n\nexport interface RabbitMQTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built channel, e.g. for tests, or an already-open amqplib `Channel`. Skips the `amqplib` auto-import entirely. */\n client?: AmqpChannelLike;\n /** Connection URL passed to `amqplib.connect()` when no `client` is injected. Default `\"amqp://localhost\"`. */\n url?: string;\n}\n\n/**\n * Publishes batches to a RabbitMQ queue via `amqplib`. RabbitMQ's core API\n * has no native multi-message batch primitive — there is no\n * `sendToQueue`-equivalent that takes an array — so `publishBatch()` loops\n * one `sendToQueue()` call per record. The \"batch\" LogQuill promises is at\n * the buffering level: `maxRecords`/`maxBytes` still governs how often that\n * loop runs, so this transport never makes one network round trip per log\n * call; it just can't make one round trip per *batch* either, honestly,\n * since RabbitMQ itself doesn't offer that primitive.\n *\n * `amqplib` is an optional peer dependency: install it yourself, or inject a\n * `client` (e.g. a fake, or an already-open `Channel`).\n */\nexport class RabbitMQTransport extends BaseQueueTransport {\n private readonly injectedClient: AmqpChannelLike | undefined;\n private readonly url: string;\n private client: AmqpChannelLike | undefined;\n\n constructor(options: RabbitMQTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.url = options.url ?? \"amqp://localhost\";\n }\n\n /** Synchronously available channel, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AmqpChannelLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n /**\n * Opens the real `amqplib` connection/channel and asserts the queue\n * exists. Both happen here, once, as part of acquiring the driver — not on\n * every `publishBatch()` call — so an injected `client` (tests, or a\n * caller's own already-open channel) is trusted to already have its queue\n * set up and is never re-asserted.\n */\n private async importClient(): Promise<AmqpChannelLike> {\n let channel: AmqpChannelLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"amqplib\";\n const mod = (await import(moduleName)) as unknown as {\n connect(url: string): Promise<{ createChannel(): Promise<AmqpChannelLike> }>;\n };\n const connection = await mod.connect(this.url);\n channel = await connection.createChannel();\n await channel.assertQueue?.(this.topic);\n } catch {\n throw new Error(\n \"RabbitMQTransport: install `amqplib` to use this transport without providing a client — `npm install amqplib`\",\n );\n }\n\n this.client = channel;\n return channel;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n for (const record of records) {\n client.sendToQueue(this.topic, Buffer.from(JSON.stringify(record)));\n }\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** AWS's own cap on a single `SendMessageBatch` request. Never exceed it. */\nconst SQS_BATCH_LIMIT = 10;\n\n/**\n * The subset of AWS SDK v3's SQS client that `SQSTransport` needs, narrowed\n * to a plain `sendMessageBatch(queueUrl, entries)` method rather than\n * modeling the full `@aws-sdk/client-sqs` command/client pattern — simpler\n * to fake in tests, and the only shape this transport actually calls. Inject\n * a fake in tests, or wrap a real `SQSClient` to match this shape.\n */\nexport interface SQSClientLike {\n /** Sends one chunk of entries (already capped at SQS's 10-message `SendMessageBatch` limit) to `queueUrl`. */\n sendMessageBatch(queueUrl: string, entries: { id: string; body: string }[]): Promise<unknown>;\n}\n\nexport interface SQSTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built client, e.g. for tests, or a thin wrapper around `@aws-sdk/client-sqs`'s `SQSClient`. Skips the `@aws-sdk/client-sqs` auto-import entirely. */\n client?: SQSClientLike;\n /** AWS region passed to `@aws-sdk/client-sqs` when no `client` is injected. */\n region?: string;\n}\n\n/**\n * Publishes batches to an SQS queue via `@aws-sdk/client-sqs`'s\n * `SendMessageBatch`. That API caps a single request at 10 messages, so\n * `publishBatch()` chunks any larger batch into sub-batches of 10 —\n * LogQuill's own `maxRecords`/`maxBytes` buffering can flush more than 10\n * records at once; this transport is responsible for respecting SQS's own\n * limit underneath, per the message-queue contract in the project spec.\n *\n * `@aws-sdk/client-sqs` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a wrapped `SQSClient`).\n */\nexport class SQSTransport extends BaseQueueTransport {\n private readonly injectedClient: SQSClientLike | undefined;\n private readonly region: string | undefined;\n private client: SQSClientLike | undefined;\n\n constructor(options: SQSTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.region = options.region;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): SQSClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<SQSClientLike> {\n let client: SQSClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-sqs\";\n const mod = (await import(moduleName)) as unknown as {\n SQSClient: new (config: { region?: string | undefined }) => { send(command: unknown): Promise<unknown> };\n SendMessageBatchCommand: new (input: {\n QueueUrl: string;\n Entries: { Id: string; MessageBody: string }[];\n }) => unknown;\n };\n const sdkClient = new mod.SQSClient({ region: this.region });\n const CommandCtor = mod.SendMessageBatchCommand;\n client = {\n sendMessageBatch: (queueUrl, entries) =>\n sdkClient.send(\n new CommandCtor({\n QueueUrl: queueUrl,\n Entries: entries.map((entry) => ({ Id: entry.id, MessageBody: entry.body })),\n }),\n ),\n };\n } catch {\n throw new Error(\n \"SQSTransport: install `@aws-sdk/client-sqs` to use this transport without providing a client — `npm install @aws-sdk/client-sqs`\",\n );\n }\n\n this.client = client;\n return client;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const chunks: (readonly LogRecord[])[] = [];\n for (let start = 0; start < records.length; start += SQS_BATCH_LIMIT) {\n chunks.push(records.slice(start, start + SQS_BATCH_LIMIT));\n }\n // Fire every sub-batch's request in the same tick (via `.map`) and await\n // them together, rather than one at a time — an `await` per iteration of\n // a sequential loop would otherwise force each sub-batch onto its own\n // microtask turn for no benefit, since the requests don't depend on\n // each other.\n await Promise.all(\n chunks.map((chunk) =>\n client.sendMessageBatch(\n this.topic,\n chunk.map((record, index) => ({ id: String(index), body: JSON.stringify(record) })),\n ),\n ),\n );\n }\n}\n","import { BaseQueueTransport, type BaseQueueTransportOptions } from \"./base-queue-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/**\n * The subset of a `@google-cloud/pubsub` `Topic` that `PubSubTransport`\n * needs. Inject a fake in tests, or an already-resolved `Topic` instance.\n */\nexport interface PubSubTopicLike {\n /** Publishes one message, matching `@google-cloud/pubsub`'s own `Topic.publishMessage()`. */\n publishMessage(message: { data: Buffer }): Promise<string>;\n}\n\nexport interface PubSubTransportOptions extends BaseQueueTransportOptions {\n /** Pre-built topic reference, e.g. for tests, or an already-resolved `@google-cloud/pubsub` `Topic`. Skips the `@google-cloud/pubsub` auto-import entirely. */\n client?: PubSubTopicLike;\n /** GCP project ID passed to `@google-cloud/pubsub` when no `client` is injected. */\n projectId?: string;\n}\n\n/**\n * Publishes batches to a GCP Pub/Sub topic via `@google-cloud/pubsub`. The\n * real client already does its own internal batching/flow-control underneath\n * `publishMessage()` — this transport doesn't reimplement that. What it does\n * own is LogQuill's own bounded-memory contract: `publishBatch()` only runs\n * once per buffer flush (`maxRecords`/`maxBytes`), so the driver is never\n * invoked once per individual log call.\n *\n * `@google-cloud/pubsub` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or a resolved `Topic`).\n */\nexport class PubSubTransport extends BaseQueueTransport {\n private readonly injectedClient: PubSubTopicLike | undefined;\n private readonly projectId: string | undefined;\n private client: PubSubTopicLike | undefined;\n\n constructor(options: PubSubTransportOptions) {\n super(options);\n this.injectedClient = options.client;\n this.projectId = options.projectId;\n }\n\n /** Synchronously available topic reference, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): PubSubTopicLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<PubSubTopicLike> {\n let topic: PubSubTopicLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/pubsub\";\n const mod = (await import(moduleName)) as unknown as {\n PubSub: new (config: { projectId?: string | undefined }) => { topic(name: string): PubSubTopicLike };\n };\n topic = new mod.PubSub({ projectId: this.projectId }).topic(this.topic);\n } catch {\n throw new Error(\n \"PubSubTransport: install `@google-cloud/pubsub` to use this transport without providing a client — `npm install @google-cloud/pubsub`\",\n );\n }\n\n this.client = topic;\n return topic;\n }\n\n protected async publishBatch(records: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n // Fire every `publishMessage()` call in the same tick (via `.map`) and\n // await them together, rather than one at a time — the real client\n // already does its own internal batching/flow-control, so a sequential\n // per-record `await` here would only add unnecessary microtask turns.\n await Promise.all(records.map((record) => client.publishMessage({ data: Buffer.from(JSON.stringify(record)) })));\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One CloudWatch Logs event: epoch-milliseconds timestamp plus a single log line. */\nexport interface CloudWatchLogEvent {\n /** Epoch-milliseconds timestamp. */\n timestamp: number;\n /** Formatted log line. */\n message: string;\n}\n\n/**\n * The subset of the AWS SDK v3 CloudWatch Logs client that `CloudWatchTransport`\n * needs. Deliberately narrower than the SDK's full command pattern (build a\n * `PutLogEventsCommand`, `.send()` it, track the deprecated sequence-token\n * dance) — modeling just this one operation keeps the injectable-fake surface\n * small for tests; `importClient()` builds the real adapter around it.\n */\nexport interface CloudWatchClientLike {\n /** Sends one already timestamp-sorted batch of events to `logGroupName`/`logStreamName`. */\n putLogEvents(\n logGroupName: string,\n logStreamName: string,\n events: readonly CloudWatchLogEvent[],\n ): Promise<unknown>;\n}\n\n/** Options for {@link CloudWatchTransport}. */\nexport interface CloudWatchTransportOptions extends BatchingTransportOptions {\n /** CloudWatch Logs log group to write into. */\n logGroupName: string;\n /** CloudWatch Logs log stream, within `logGroupName`, to write into. */\n logStreamName: string;\n /** AWS region, e.g. `\"us-east-1\"`. Passed to the real SDK client; ignored when `client` is injected. */\n region?: string;\n /** Pre-built client, e.g. for tests. Skips the `@aws-sdk/client-cloudwatch-logs` auto-import entirely. */\n client?: CloudWatchClientLike;\n}\n\ninterface AWSCloudWatchLogsClientLike {\n send(command: unknown): Promise<unknown>;\n}\n\n/**\n * Ships batched records to AWS CloudWatch Logs via the AWS SDK v3\n * (`@aws-sdk/client-cloudwatch-logs`). Each buffered record becomes one log\n * event; CloudWatch requires events within a single `PutLogEvents` call to be\n * sorted by timestamp ascending, which `sendBatch()` does before sending.\n *\n * `@aws-sdk/client-cloudwatch-logs` is an optional peer dependency: install\n * it yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `CloudWatchLogsClient` wrapped to match `CloudWatchClientLike`).\n */\nexport class CloudWatchTransport extends BatchingTransport {\n /** CloudWatch Logs log group written into. */\n readonly logGroupName: string;\n /** CloudWatch Logs log stream, within `logGroupName`, written into. */\n readonly logStreamName: string;\n /** AWS region passed to the real SDK client; `undefined` when `client` is injected or the SDK's own credential-chain resolution is used. */\n readonly region: string | undefined;\n private readonly injectedClient: CloudWatchClientLike | undefined;\n private client: CloudWatchClientLike | undefined;\n\n constructor(options: CloudWatchTransportOptions) {\n super(options);\n this.logGroupName = options.logGroupName;\n this.logStreamName = options.logStreamName;\n this.region = options.region;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudWatchClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudWatchClientLike> {\n let ClientCtor: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n let PutLogEventsCommandCtor: new (input: unknown) => unknown;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@aws-sdk/client-cloudwatch-logs\";\n const mod = (await import(moduleName)) as unknown as {\n CloudWatchLogsClient: new (config: { region?: string | undefined }) => AWSCloudWatchLogsClientLike;\n PutLogEventsCommand: new (input: unknown) => unknown;\n };\n ClientCtor = mod.CloudWatchLogsClient;\n PutLogEventsCommandCtor = mod.PutLogEventsCommand;\n } catch {\n throw new Error(\n \"CloudWatchTransport: install `@aws-sdk/client-cloudwatch-logs` to use this transport without providing a client — `npm install @aws-sdk/client-cloudwatch-logs`\",\n );\n }\n\n const sdkClient = new ClientCtor({ region: this.region });\n this.client = {\n putLogEvents: (logGroupName, logStreamName, events) =>\n sdkClient.send(\n new PutLogEventsCommandCtor({\n logGroupName,\n logStreamName,\n logEvents: events,\n }),\n ),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const events = batch\n .map((record) => ({\n timestamp: Date.parse(record.timestamp),\n message: this.format(record),\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n await client.putLogEvents(this.logGroupName, this.logStreamName, events);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One GCP Cloud Logging entry, shaped for `Log#write`. */\nexport interface CloudLoggingEntry {\n /** Cloud Logging `LogSeverity` value, mapped from the record's level. */\n severity: string;\n /** ISO8601 timestamp. */\n timestamp: string;\n /** The record, JSON-decoded, as Cloud Logging's structured payload. */\n jsonPayload: Record<string, unknown>;\n}\n\n/**\n * The subset of the `@google-cloud/logging` client that `CloudLoggingTransport`\n * needs. Deliberately narrower than the SDK's full `Log`/`Entry` object model —\n * `importClient()` builds the real adapter around `logging.log(name).write(entries)`.\n */\nexport interface CloudLoggingClientLike {\n /** Writes one batch of entries to the configured log. */\n writeLogEntries(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\n/** Options for {@link CloudLoggingTransport}. */\nexport interface CloudLoggingTransportOptions extends BatchingTransportOptions {\n /** GCP log name (the last segment of the log resource path). Default `\"logquill\"`. */\n logName?: string;\n /** GCP project ID. Passed to the real SDK client; ignored when `client` is injected — omit to use Application Default Credentials' project. */\n projectId?: string;\n /** Pre-built client, e.g. for tests. Skips the `@google-cloud/logging` auto-import entirely. */\n client?: CloudLoggingClientLike;\n}\n\ninterface GCPLogLike {\n write(entries: readonly CloudLoggingEntry[]): Promise<unknown>;\n}\n\ninterface GCPLoggingLike {\n log(name: string): GCPLogLike;\n}\n\n/** Maps LogQuill's level names onto Cloud Logging's `LogSeverity` enum values. */\nfunction gcpSeverity(levelValue: string): string {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return \"DEBUG\";\n case Level.INFO:\n return \"INFO\";\n case Level.WARN:\n return \"WARNING\";\n case Level.ERROR:\n return \"ERROR\";\n case Level.FATAL:\n return \"CRITICAL\";\n }\n}\n\n/**\n * Ships batched records to Google Cloud Logging via `@google-cloud/logging`.\n * Each record becomes one structured entry (`jsonPayload`), with `level`\n * mapped onto Cloud Logging's `severity` enum.\n *\n * `@google-cloud/logging` is an optional peer dependency: install it\n * yourself, or inject a `client` (e.g. a fake, or an already-configured\n * `Log` wrapped to match `CloudLoggingClientLike`).\n */\nexport class CloudLoggingTransport extends BatchingTransport {\n /** GCP log name (the last segment of the log resource path). */\n readonly logName: string;\n /** GCP project ID passed to the real SDK client; `undefined` when `client` is injected or Application Default Credentials' project is used. */\n readonly projectId: string | undefined;\n private readonly injectedClient: CloudLoggingClientLike | undefined;\n private client: CloudLoggingClientLike | undefined;\n\n constructor(options: CloudLoggingTransportOptions = {}) {\n super(options);\n this.logName = options.logName ?? \"logquill\";\n this.projectId = options.projectId;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): CloudLoggingClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<CloudLoggingClientLike> {\n let LoggingCtor: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"@google-cloud/logging\";\n const mod = (await import(moduleName)) as unknown as {\n Logging: new (options?: { projectId?: string | undefined }) => GCPLoggingLike;\n };\n LoggingCtor = mod.Logging;\n } catch {\n throw new Error(\n \"CloudLoggingTransport: install `@google-cloud/logging` to use this transport without providing a client — `npm install @google-cloud/logging`\",\n );\n }\n\n const logging = new LoggingCtor({ projectId: this.projectId });\n const log = logging.log(this.logName);\n this.client = {\n writeLogEntries: (entries) => log.write(entries),\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const entries = batch.map((record) => ({\n severity: gcpSeverity(record.level),\n timestamp: record.timestamp,\n jsonPayload: JSON.parse(this.format(record)) as Record<string, unknown>,\n }));\n await client.writeLogEntries(entries);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport { Level, parseLevel } from \"../../core/levels.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** One Application Insights trace: a message plus its `SeverityLevel`. */\nexport interface AppInsightsTrace {\n /** Formatted log line. */\n message: string;\n /** Application Insights `SeverityLevel` value, mapped from the record's level. */\n severity: number;\n}\n\n/**\n * The subset of Application Insights telemetry that `AppInsightsTransport`\n * needs.\n *\n * `trackTraceBatch` is LogQuill's own batching contract, not a native\n * `applicationinsights` SDK method — the real SDK only exposes a single-record\n * `trackTrace()` plus an async `flush()`. The real-client adapter built by\n * `importClient()` loops `trackTrace()` calls inside `trackTraceBatch` and\n * flushes once at the end, so batching happens at the LogQuill buffering\n * level (bounded by `maxRecords`/`maxBytes`), not as a real network-level\n * batch call — Application Insights doesn't offer one.\n */\nexport interface AppInsightsClientLike {\n /** Tracks every trace in the batch, then flushes once at the end. */\n trackTraceBatch(traces: readonly AppInsightsTrace[]): Promise<unknown>;\n}\n\n/** Options for {@link AppInsightsTransport}. */\nexport interface AppInsightsTransportOptions extends BatchingTransportOptions {\n /** Azure Application Insights connection string. Passed to the real SDK client; ignored when `client` is injected. */\n connectionString?: string;\n /** Pre-built client, e.g. for tests. Skips the `applicationinsights` auto-import entirely. */\n client?: AppInsightsClientLike;\n}\n\ninterface AzureTelemetryClientLike {\n trackTrace(telemetry: AppInsightsTrace): void;\n flush(): void;\n}\n\n/** Maps LogQuill's level names onto Application Insights' `SeverityLevel` enum values. */\nfunction appInsightsSeverity(levelValue: string): number {\n const level = parseLevel(levelValue);\n switch (level) {\n case Level.TRACE:\n case Level.DEBUG:\n return 0; // Verbose\n case Level.INFO:\n return 1; // Information\n case Level.WARN:\n return 2; // Warning\n case Level.ERROR:\n return 3; // Error\n case Level.FATAL:\n return 4; // Critical\n }\n}\n\n/**\n * Ships batched records to Azure Application Insights via `applicationinsights`,\n * as trace telemetry with `level` mapped onto Application Insights' severity\n * scale. See `AppInsightsClientLike` for why \"batch\" means LogQuill-side\n * buffering plus a loop of single `trackTrace()` calls, not one network batch\n * request — the underlying SDK has no batch-track API.\n *\n * `applicationinsights` is an optional peer dependency: install it yourself,\n * or inject a `client` (e.g. a fake, or an already-configured `TelemetryClient`\n * wrapped to match `AppInsightsClientLike`).\n */\nexport class AppInsightsTransport extends BatchingTransport {\n /** Azure Application Insights connection string passed to the real SDK client; `undefined` when `client` is injected. */\n readonly connectionString: string | undefined;\n private readonly injectedClient: AppInsightsClientLike | undefined;\n private client: AppInsightsClientLike | undefined;\n\n constructor(options: AppInsightsTransportOptions = {}) {\n super(options);\n this.connectionString = options.connectionString;\n this.injectedClient = options.client;\n }\n\n /** Synchronously available client, if one was injected or already imported — avoids an unnecessary microtask hop on the hot path. */\n private resolvedClient(): AppInsightsClientLike | undefined {\n return this.injectedClient ?? this.client;\n }\n\n private async importClient(): Promise<AppInsightsClientLike> {\n let TelemetryClientCtor: new (connectionString?: string) => AzureTelemetryClientLike;\n try {\n // A non-literal specifier keeps this an optional peer dependency: `tsc`\n // won't try to resolve types for it, and bundlers won't force-include it.\n const moduleName = \"applicationinsights\";\n const mod = (await import(moduleName)) as unknown as {\n TelemetryClient: new (connectionString?: string) => AzureTelemetryClientLike;\n };\n TelemetryClientCtor = mod.TelemetryClient;\n } catch {\n throw new Error(\n \"AppInsightsTransport: install `applicationinsights` to use this transport without providing a client — `npm install applicationinsights`\",\n );\n }\n\n const telemetryClient = new TelemetryClientCtor(this.connectionString);\n this.client = {\n trackTraceBatch: (traces) => {\n for (const trace of traces) {\n telemetryClient.trackTrace(trace);\n }\n telemetryClient.flush();\n return Promise.resolve();\n },\n };\n return this.client;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const client = this.resolvedClient() ?? (await this.importClient());\n const traces = batch.map((record) => ({\n message: this.format(record),\n severity: appInsightsSeverity(record.level),\n }));\n await client.trackTraceBatch(traces);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one batch of formatted lines to Datadog's Logs intake API at `url`. Swap in a fake for tests. */\nexport type DatadogSender = (url: string, apiKey: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchDatadogSender(url: string, apiKey: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", \"DD-API-KEY\": apiKey },\n body: `[${batch.join(\",\")}]`,\n });\n if (!response.ok) {\n throw new Error(\n `DatadogTransport: request to ${url} failed with status ${String(response.status)} — check the API key and site region`,\n );\n }\n}\n\n/** Options for {@link DatadogTransport}. */\nexport interface DatadogTransportOptions extends BatchingTransportOptions {\n /** Datadog API key, sent in the `DD-API-KEY` header. */\n apiKey: string;\n /**\n * Datadog site (region), e.g. `\"datadoghq.com\"` (US1, default),\n * `\"datadoghq.eu\"` (EU), `\"us3.datadoghq.com\"`, `\"us5.datadoghq.com\"`,\n * `\"ap1.datadoghq.com\"`. Never hardcode this — sending to the wrong\n * region's intake host silently fails to deliver logs to your account.\n */\n site?: string;\n /** Delivers one batch. Defaults to a `fetch` POST; override for a fake or a different delivery mechanism. */\n sender?: DatadogSender;\n}\n\n/**\n * Batches records and POSTs them as a JSON array to Datadog's Logs intake\n * API (`https://http-intake.logs.<site>/api/v2/logs`) via `fetch`. Pass\n * `sender` to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class DatadogTransport extends BatchingTransport {\n /** Logs intake endpoint derived from `site`. */\n readonly url: string;\n /** Datadog API key sent in the `DD-API-KEY` header. */\n readonly apiKey: string;\n /** Datadog site (region) this transport sends to. */\n readonly site: string;\n private readonly sender: DatadogSender;\n\n constructor(options: DatadogTransportOptions) {\n super(options);\n this.apiKey = options.apiKey;\n this.site = options.site ?? \"datadoghq.com\";\n this.url = `https://http-intake.logs.${this.site}/api/v2/logs`;\n this.sender = options.sender ?? fetchDatadogSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const formatted = batch.map((record) => this.format(record));\n return this.sender(this.url, this.apiKey, formatted);\n }\n}\n","import { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Sends one pre-built NDJSON `_bulk` body to `url` with the given headers. Swap in a fake for tests. */\nexport type ElasticsearchSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n) => Promise<void> | void;\n\nasync function fetchElasticsearchSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: string,\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { ...headers, \"Content-Type\": \"application/x-ndjson\" },\n body,\n });\n if (!response.ok) {\n throw new Error(`ElasticsearchTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\n/** Options for {@link ElasticsearchTransport}. */\nexport interface ElasticsearchTransportOptions extends BatchingTransportOptions {\n /** Cluster base URL, e.g. `\"https://localhost:9200\"`. */\n node: string;\n /** Index to write into. Default `\"logs\"`. */\n index?: string;\n /** Elasticsearch API key (base64 `id:api_key`), sent as `Authorization: ApiKey <apiKey>`. Omit to send no auth header (e.g. behind a proxy that adds its own). */\n apiKey?: string;\n /** Delivers one NDJSON `_bulk` body. Defaults to a `fetch` POST; override for a fake or a different delivery mechanism. */\n sender?: ElasticsearchSender;\n}\n\n/**\n * Batches records and POSTs them to Elasticsearch's `_bulk` API\n * (`<node>/_bulk`) via `fetch`, as newline-delimited action+source pairs —\n * no client dependency needed, just NDJSON body construction. Pass `sender`\n * to swap in a fake for tests, or a different delivery mechanism.\n */\nexport class ElasticsearchTransport extends BatchingTransport {\n /** `_bulk` endpoint derived from the `node` option. */\n readonly url: string;\n /** Index written into. */\n readonly index: string;\n private readonly apiKey: string | undefined;\n private readonly sender: ElasticsearchSender;\n\n constructor(options: ElasticsearchTransportOptions) {\n super(options);\n this.index = options.index ?? \"logs\";\n this.url = `${options.node.replace(/\\/+$/, \"\")}/_bulk`;\n this.apiKey = options.apiKey;\n this.sender = options.sender ?? fetchElasticsearchSender;\n }\n\n protected override sendBatch(batch: readonly LogRecord[]): Promise<void> | void {\n const lines: string[] = [];\n for (const record of batch) {\n lines.push(JSON.stringify({ index: { _index: this.index } }));\n lines.push(this.format(record));\n }\n // The bulk API requires a trailing newline after the final action/source pair.\n const body = `${lines.join(\"\\n\")}\\n`;\n const headers: Record<string, string> = {};\n if (this.apiKey !== undefined) {\n headers.Authorization = `ApiKey ${this.apiKey}`;\n }\n return this.sender(this.url, headers, body);\n }\n}\n","import { gzipSync } from \"node:zlib\";\nimport { BatchingTransport, type BatchingTransportOptions } from \"../batching-transport.js\";\nimport type { LogRecord } from \"../../core/records.js\";\n\n/** Which New Relic ingest region to send to — determines the Log API host. */\nexport type NewRelicRegion = \"US\" | \"EU\";\n\n/** What `NewRelicSender` reports back about one delivery attempt, so the transport can drive its own 429 backoff logic. */\nexport interface NewRelicSenderResult {\n /** `true` for a 2xx response. */\n ok: boolean;\n /** HTTP status code of the response. */\n status: number;\n /** The raw `Retry-After` response header value, if present — either a number of seconds or an HTTP-date, per RFC 9110. */\n retryAfter: string | null;\n}\n\n/** Sends one gzip-compressed batch to New Relic's Log API at `url`. Swap in a fake for tests. */\nexport type NewRelicSender = (\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n) => Promise<NewRelicSenderResult> | NewRelicSenderResult;\n\nasync function fetchNewRelicSender(\n url: string,\n headers: Readonly<Record<string, string>>,\n body: Buffer,\n): Promise<NewRelicSenderResult> {\n const response = await fetch(url, { method: \"POST\", headers, body });\n return {\n ok: response.ok,\n status: response.status,\n retryAfter: response.headers.get(\"retry-after\"),\n };\n}\n\n/** Returns a copy of `record` with the reserved `meta.eventType` key removed, leaving the original record untouched. */\nfunction withoutEventType(record: LogRecord): LogRecord {\n const meta = { ...record.meta };\n delete meta.eventType;\n return { ...record, meta };\n}\n\n/** Resolves a `Retry-After` header value (seconds, or an HTTP-date) to an absolute epoch-ms resume time. */\nfunction resumeTimestamp(retryAfter: string | null, now: number): number {\n if (retryAfter === null) {\n // New Relic blocks further sends for the rest of that calendar minute on\n // a rate-limit breach even when the header is missing — 60s is a safe floor.\n return now + 60_000;\n }\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n return now + seconds * 1000;\n }\n const dateMs = Date.parse(retryAfter);\n return Number.isNaN(dateMs) ? now + 60_000 : dateMs;\n}\n\n/** Options for {@link NewRelicTransport}. */\nexport interface NewRelicTransportOptions extends BatchingTransportOptions {\n /** New Relic license key, sent in the `Api-Key` header. */\n licenseKey: string;\n /**\n * New Relic account region — selects the ingest host\n * (`log-api.newrelic.com` for US, `log-api.eu.newrelic.com` for EU).\n * Never hardcode this: an EU-region license key sent to the US host (or\n * vice versa) is rejected. Default `\"US\"`.\n */\n region?: NewRelicRegion;\n /** Delivers one gzip-compressed batch. Defaults to a `fetch` POST; override for a fake or to intercept 429s in tests. */\n sender?: NewRelicSender;\n /** Injectable clock for the 429 backoff window, matching `SamplingPlugin`'s injectable `rng`. Default `Date.now`. */\n clock?: () => number;\n}\n\n/**\n * Batches records and POSTs them, gzip-compressed, to New Relic's Log API\n * (`log-api.newrelic.com` / `log-api.eu.newrelic.com`, region-configurable)\n * via `fetch`. Strips the reserved `meta.eventType` key (New Relic drops\n * records carrying it) and honors 429 responses by reading `Retry-After`\n * and pausing further sends until it elapses, rather than hammering an\n * account that's already been rate-limited for the rest of the minute.\n *\n * Pass `sender` to swap in a fake for tests, and `clock` to control time in\n * backoff tests without waiting on a real clock.\n */\nexport class NewRelicTransport extends BatchingTransport {\n /** Ingest endpoint derived from `region`. */\n readonly url: string;\n /** New Relic account region this transport sends to. */\n readonly region: NewRelicRegion;\n private readonly licenseKey: string;\n private readonly sender: NewRelicSender;\n private readonly clock: () => number;\n private pausedUntil: number | null = null;\n\n constructor(options: NewRelicTransportOptions) {\n super(options);\n this.licenseKey = options.licenseKey;\n this.region = options.region ?? \"US\";\n this.url =\n this.region === \"EU\" ? \"https://log-api.eu.newrelic.com/log/v1\" : \"https://log-api.newrelic.com/log/v1\";\n this.sender = options.sender ?? fetchNewRelicSender;\n this.clock = options.clock ?? Date.now;\n }\n\n protected override async sendBatch(batch: readonly LogRecord[]): Promise<void> {\n const now = this.clock();\n if (this.pausedUntil !== null && now < this.pausedUntil) {\n console.error(\n `NewRelicTransport: sends paused until ${new Date(this.pausedUntil).toISOString()} after a 429 rate-limit response — skipping this batch rather than making a doomed request`,\n );\n return;\n }\n this.pausedUntil = null;\n\n const records = batch.map((record) => withoutEventType(record));\n const body = gzipSync(Buffer.from(JSON.stringify(records)));\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n \"Api-Key\": this.licenseKey,\n };\n\n const result = await this.sender(this.url, headers, body);\n\n if (result.status === 429) {\n this.pausedUntil = resumeTimestamp(result.retryAfter, now);\n console.error(\n `NewRelicTransport: received 429 from New Relic — pausing sends until ${new Date(this.pausedUntil).toISOString()}. Reduce log volume or increase batching to stay under the rate limit.`,\n );\n return;\n }\n\n if (!result.ok) {\n throw new Error(\n `NewRelicTransport: request to ${this.url} failed with status ${String(result.status)} — check the license key and region`,\n );\n }\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Level, parseLevel } from \"../core/levels.js\";\nimport type { LogRecord } from \"../core/records.js\";\nimport { Transport } from \"./transport.js\";\n\nconst COLORS: Readonly<Record<Level, string>> = {\n [Level.TRACE]: \"\\x1b[90m\", // gray\n [Level.DEBUG]: \"\\x1b[36m\", // cyan\n [Level.INFO]: \"\\x1b[32m\", // green\n [Level.WARN]: \"\\x1b[33m\", // yellow\n [Level.ERROR]: \"\\x1b[31m\", // red\n [Level.FATAL]: \"\\x1b[35m\", // magenta\n};\nconst RESET = \"\\x1b[0m\";\n\n/** The subset of `console` this transport needs — swap in a fake for tests. */\nexport interface ConsoleLike {\n /** Writes one already-formatted line, e.g. for a TRACE–WARN record. */\n log(message: string): void;\n /** Writes one already-formatted line, e.g. for an ERROR/FATAL record. */\n error(message: string): void;\n}\n\n/** Options for {@link ConsoleTransport}. */\nexport interface ConsoleTransportOptions {\n /** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */\n formatter?: Formatter;\n /** Wrap each line in an ANSI color escape for its level. Defaults to `true` unless the `NO_COLOR` env var is set. */\n colorize?: boolean;\n /** Sink to write through instead of the global `console` — swap in a fake for tests. */\n console?: ConsoleLike;\n}\n\nfunction defaultColorize(): boolean {\n // Isomorphic guard: `process` doesn't exist in a browser bundle.\n const env: NodeJS.ProcessEnv | undefined = typeof process === \"undefined\" ? undefined : process.env;\n return env?.NO_COLOR === undefined;\n}\n\n/**\n * Writes to `console.log`, routing ERROR/FATAL to `console.error`, colorized by\n * level. Uses the global `console` rather than Node's `process.stdout`/`stderr`\n * so this transport works unmodified in a browser bundle.\n */\nexport class ConsoleTransport extends Transport {\n /** Whether each line is wrapped in an ANSI color escape for its level. */\n colorize: boolean;\n private readonly out: ConsoleLike;\n\n constructor(options: ConsoleTransportOptions = {}) {\n super(options.formatter);\n this.colorize = options.colorize ?? defaultColorize();\n this.out = options.console ?? console;\n }\n\n /** Writes `formatted` via `console.log`, or `console.error` for ERROR/FATAL records. */\n write(formatted: string, record: LogRecord): void {\n const level = parseLevel(record.level);\n const line = this.colorize ? this.applyColor(formatted, level) : formatted;\n if (level >= Level.ERROR) {\n this.out.error(line);\n } else {\n this.out.log(line);\n }\n }\n\n private applyColor(formatted: string, level: Level): string {\n return `${COLORS[level]}${formatted}${RESET}`;\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Sends one batch of formatted lines to `url`. Swap in a fake for tests. */\nexport type BeaconSender = (url: string, batch: readonly string[]) => void;\n\n/**\n * `@types/node`'s `Navigator` doesn't declare `sendBeacon` (it's DOM-only,\n * and this project has no DOM lib), so it's cast to this local shape at the\n * one call site that needs it.\n */\ninterface BeaconNavigator {\n sendBeacon(url: string, data: string): boolean;\n}\n\nfunction defaultBeaconSender(url: string, batch: readonly string[]): void {\n const body = batch.join(\"\\n\");\n // Isomorphic guard: `navigator` doesn't exist at runtime before Node 21,\n // and its presence there is limited (no `sendBeacon`) — same pattern as\n // ConsoleTransport's `typeof process === \"undefined\"` guard.\n const nav = typeof navigator === \"undefined\" ? undefined : (navigator as unknown as BeaconNavigator);\n if (nav && typeof nav.sendBeacon === \"function\") {\n nav.sendBeacon(url, body);\n return;\n }\n // Fallback for environments without `navigator.sendBeacon` (a worker, an\n // older browser, or this transport running under Node): `fetch` with\n // `keepalive` so the request can still complete after the page/caller\n // that queued it goes away, matching `sendBeacon`'s fire-and-forget contract.\n void fetch(url, { method: \"POST\", body, keepalive: true }).catch((error: unknown) => {\n // write()/close() are non-blocking by contract, so a send failure can't\n // propagate to the caller — report it the same way HTTPTransport does.\n console.error(\"BeaconTransport: failed to send log batch\", error);\n });\n}\n\n/** Options for {@link BeaconTransport}. */\nexport interface BeaconTransportOptions {\n /** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */\n formatter?: Formatter;\n /** Flush once the buffer holds this many lines. Default 20 — kept low since `sendBeacon` payloads are capped. */\n batchSize?: number;\n /** Delivers one batch. Defaults to `sendBeacon` with a `fetch(..., { keepalive: true })` fallback; override for a fake or a different backend. */\n sender?: BeaconSender;\n}\n\n/**\n * Batches formatted records and sends them via `navigator.sendBeacon`,\n * falling back to a `keepalive` `fetch` where `sendBeacon` isn't available.\n * Meant for the browser: unlike `HTTPTransport`, a beacon send can complete\n * even after the page that queued it starts unloading. Keep `batchSize`\n * small — `sendBeacon` payloads are capped (64KB in most browsers).\n */\nexport class BeaconTransport extends Transport {\n /** Endpoint each batch is sent to. */\n readonly url: string;\n /** Buffer is flushed once it holds this many lines. */\n readonly batchSize: number;\n private readonly sender: BeaconSender;\n private batch: string[] = [];\n\n constructor(url: string, options: BeaconTransportOptions = {}) {\n super(options.formatter);\n this.url = url;\n this.batchSize = options.batchSize ?? 20;\n this.sender = options.sender ?? defaultBeaconSender;\n }\n\n /** Buffers the formatted line, flushing the batch once `batchSize` is reached. */\n write(formatted: string): void {\n this.batch.push(formatted);\n if (this.batch.length >= this.batchSize) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached `batchSize`. */\n flush(): void {\n if (this.batch.length === 0) {\n return;\n }\n const batch = this.batch;\n this.batch = [];\n\n try {\n this.sender(this.url, batch);\n } catch (error) {\n console.error(\"BeaconTransport: failed to send log batch\", error);\n }\n }\n\n override close(): void {\n this.flush();\n }\n}\n","import { closeSync, existsSync, fstatSync, mkdirSync, openSync, renameSync, unlinkSync, writeSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Options for {@link FileTransport}. */\nexport interface FileTransportOptions {\n /** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */\n formatter?: Formatter;\n /** Rotate once the file reaches this many bytes. `0` disables rotation. Default 10MB. */\n maxBytes?: number;\n /** How many rotated backups (`.1`, `.2`, ...) to keep. The oldest is deleted once exceeded. Default 5. */\n backupCount?: number;\n}\n\n/** Appends formatted records to a file, rotating when it exceeds `maxBytes`. */\nexport class FileTransport extends Transport {\n /** Path of the file records are appended to. */\n readonly path: string;\n /** File is rotated once it reaches this many bytes. `0` disables rotation. */\n readonly maxBytes: number;\n /** How many rotated backups (`.1`, `.2`, ...) are kept. */\n readonly backupCount: number;\n private fd: number;\n\n constructor(path: string, options: FileTransportOptions = {}) {\n super(options.formatter);\n this.path = path;\n this.maxBytes = options.maxBytes ?? 10 * 1024 * 1024;\n this.backupCount = options.backupCount ?? 5;\n mkdirSync(dirname(path), { recursive: true });\n this.fd = openSync(this.path, \"a\");\n }\n\n /** Appends one formatted line to the file, rotating first if `maxBytes` has been exceeded. */\n write(formatted: string): void {\n writeSync(this.fd, formatted + \"\\n\");\n if (this.maxBytes > 0 && fstatSync(this.fd).size >= this.maxBytes) {\n this.rotate();\n }\n }\n\n private rotate(): void {\n closeSync(this.fd);\n\n if (this.backupCount > 0) {\n for (let index = this.backupCount - 1; index > 0; index--) {\n const src = `${this.path}.${String(index)}`;\n const dst = `${this.path}.${String(index + 1)}`;\n if (existsSync(src)) {\n if (existsSync(dst)) {\n unlinkSync(dst);\n }\n renameSync(src, dst);\n }\n }\n const backup = `${this.path}.1`;\n if (existsSync(backup)) {\n unlinkSync(backup);\n }\n renameSync(this.path, backup);\n } else {\n unlinkSync(this.path);\n }\n\n this.fd = openSync(this.path, \"a\");\n }\n\n override close(): void {\n closeSync(this.fd);\n }\n}\n","import type { Formatter } from \"../core/formatter.js\";\nimport { Transport } from \"./transport.js\";\n\n/** Sends one batch of formatted lines to `url`. Swap in a fake for tests. */\nexport type Sender = (url: string, batch: readonly string[]) => Promise<void> | void;\n\nasync function fetchSender(url: string, batch: readonly string[]): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-ndjson\" },\n body: batch.join(\"\\n\"),\n });\n if (!response.ok) {\n throw new Error(`HTTPTransport: request to ${url} failed with status ${String(response.status)}`);\n }\n}\n\n/** Options for {@link HTTPTransport}. */\nexport interface HTTPTransportOptions {\n /** Turns a `LogRecord` into the string this transport writes. Defaults to `JSONFormatter`. */\n formatter?: Formatter;\n /** Flush once the buffer holds this many lines. Default 50. */\n batchSize?: number;\n /** Delivers one batch. Defaults to a `fetch` POST of newline-delimited JSON; override for a fake or a different backend. */\n sender?: Sender;\n}\n\n/**\n * Batches formatted records and POSTs them as newline-delimited JSON via `fetch`.\n * Pass `sender` to swap in a fake for tests, or a different backend.\n */\nexport class HTTPTransport extends Transport {\n /** Endpoint each batch is POSTed to. */\n readonly url: string;\n /** Buffer is flushed once it holds this many lines. */\n readonly batchSize: number;\n private readonly sender: Sender;\n private batch: string[] = [];\n\n constructor(url: string, options: HTTPTransportOptions = {}) {\n super(options.formatter);\n this.url = url;\n this.batchSize = options.batchSize ?? 50;\n this.sender = options.sender ?? fetchSender;\n }\n\n /** Buffers the formatted line, flushing the batch once `batchSize` is reached. */\n write(formatted: string): void {\n this.batch.push(formatted);\n if (this.batch.length >= this.batchSize) {\n this.flush();\n }\n }\n\n /** Send the current batch now, even if it hasn't reached `batchSize`. */\n flush(): void {\n if (this.batch.length === 0) {\n return;\n }\n const batch = this.batch;\n this.batch = [];\n\n const result = this.sender(this.url, batch);\n if (result) {\n result.catch((error: unknown) => {\n // write()/close() are non-blocking by contract, so a send failure can't\n // propagate to the caller — report it the same way a broken plugin would.\n console.error(\"HTTPTransport: failed to send log batch\", error);\n });\n }\n }\n\n override close(): void {\n this.flush();\n }\n}\n","/** How a full queue behaves when another task arrives. */\nexport type BackpressurePolicy = \"dropOldest\" | \"dropNewest\" | \"block\";\n\n/** Options for the {@link DispatchQueue} constructor. */\nexport interface DispatchQueueOptions {\n /** Maximum number of pending tasks the queue holds at once. Default 10_000. */\n maxSize?: number;\n /**\n * What happens when `enqueue()` is called while the queue is already at\n * `maxSize`:\n * - `\"dropOldest\"` (default) — evict the longest-waiting task (it never\n * runs) and enqueue the new one. Favors recent records.\n * - `\"dropNewest\"` — discard the incoming task; everything already queued\n * is left alone. Favors records already in flight.\n * - `\"block\"` — run the task synchronously, right now, on the caller's\n * stack instead of queueing it. Nothing is ever dropped, at the cost of\n * the caller (e.g. `logger.info()`) taking as long as the write itself —\n * real backpressure rather than a silent drop.\n */\n policy?: BackpressurePolicy;\n /**\n * Called at most once per `warnIntervalMs` (default 5000) when the queue\n * drops tasks, with the number dropped since the last call — a\n * rate-limited way to surface sustained overload without flooding the\n * caller's own logs with one warning per drop. Defaults to `console.warn`.\n */\n onDrop?: (droppedSinceLastWarning: number, policy: BackpressurePolicy) => void;\n /** Minimum gap between `onDrop` calls. Default 5000ms. */\n warnIntervalMs?: number;\n}\n\n/** A unit of deferred work queued via `DispatchQueue.enqueue()`. */\nexport type Task = () => void | Promise<void>;\n\nfunction isPromise(value: void | Promise<void>): value is Promise<void> {\n return typeof value === \"object\" && typeof value.then === \"function\";\n}\n\nfunction defaultScheduler(run: () => void): void {\n // Node has setImmediate (a real macrotask, letting the current call stack\n // — and any synchronous work queued right after it — finish first); a\n // browser bundle falls back to a microtask.\n if (typeof setImmediate === \"function\") {\n setImmediate(run);\n } else {\n queueMicrotask(run);\n }\n}\n\nfunction defaultOnDrop(count: number, policy: BackpressurePolicy): void {\n console.warn(\n `DispatchQueue: dropped ${String(count)} record(s) — queue exceeded its configured size under the \"${policy}\" backpressure policy`,\n );\n}\n\n/**\n * A bounded, in-order queue of pending write tasks, drained outside the\n * caller's own call stack (`setImmediate`/microtask) so `Logger` methods can\n * return before the I/O they triggered actually runs. Backed by an explicit\n * size cap and backpressure policy — see `DispatchQueueOptions` — so a\n * sustained burst can never grow memory unboundedly.\n */\nexport class DispatchQueue {\n /** Maximum number of pending tasks held at once, as configured via `DispatchQueueOptions`. */\n readonly maxSize: number;\n /** Backpressure policy applied once `maxSize` is reached, as configured via `DispatchQueueOptions`. */\n readonly policy: BackpressurePolicy;\n private readonly onDrop: (count: number, policy: BackpressurePolicy) => void;\n private readonly warnIntervalMs: number;\n\n private readonly tasks: Task[] = [];\n private draining = false;\n private scheduled = false;\n private idleWaiters: (() => void)[] = [];\n private droppedSinceWarning = 0;\n private lastWarnAt = 0;\n\n constructor(options: DispatchQueueOptions = {}) {\n this.maxSize = options.maxSize ?? 10_000;\n this.policy = options.policy ?? \"dropOldest\";\n this.onDrop = options.onDrop ?? defaultOnDrop;\n this.warnIntervalMs = options.warnIntervalMs ?? 5000;\n }\n\n /** Number of tasks currently waiting to run. Bounded by `maxSize`. */\n get size(): number {\n return this.tasks.length;\n }\n\n /**\n * Queue `task` to run outside the current call stack, applying the\n * configured backpressure policy if the queue is already full. Under\n * `\"block\"`, `task` may run synchronously before this call returns.\n */\n enqueue(task: Task): void {\n if (this.tasks.length < this.maxSize) {\n this.tasks.push(task);\n this.schedule();\n return;\n }\n\n switch (this.policy) {\n case \"dropNewest\":\n this.recordDrop();\n return;\n case \"block\":\n this.runInline(task);\n return;\n case \"dropOldest\":\n default:\n this.tasks.shift();\n this.recordDrop();\n this.tasks.push(task);\n this.schedule();\n return;\n }\n }\n\n /** Resolves once every task queued so far has run. Safe to call when idle. */\n async flush(): Promise<void> {\n if (this.tasks.length === 0 && !this.draining) {\n return;\n }\n await new Promise<void>((resolve) => {\n this.idleWaiters.push(resolve);\n this.schedule();\n });\n }\n\n private recordDrop(): void {\n this.droppedSinceWarning += 1;\n const now = Date.now();\n if (now - this.lastWarnAt >= this.warnIntervalMs) {\n const count = this.droppedSinceWarning;\n this.droppedSinceWarning = 0;\n this.lastWarnAt = now;\n try {\n this.onDrop(count, this.policy);\n } catch {\n /* a broken onDrop callback must not crash logging */\n }\n }\n }\n\n private runInline(task: Task): void {\n try {\n const result = task();\n if (isPromise(result)) {\n result.catch((error: unknown) => {\n console.error(\"DispatchQueue: a blocked task failed\", error);\n });\n }\n } catch (error) {\n console.error(\"DispatchQueue: a blocked task failed\", error);\n }\n }\n\n private schedule(): void {\n if (this.scheduled) {\n return;\n }\n this.scheduled = true;\n defaultScheduler(() => {\n this.scheduled = false;\n void this.drainAll();\n });\n }\n\n private async drainAll(): Promise<void> {\n if (this.draining) {\n return;\n }\n this.draining = true;\n try {\n while (this.tasks.length > 0) {\n const task = this.tasks.shift();\n if (!task) {\n continue;\n }\n try {\n await task();\n } catch (error) {\n console.error(\"DispatchQueue: a queued task failed\", error);\n }\n }\n } finally {\n this.draining = false;\n const waiters = this.idleWaiters;\n this.idleWaiters = [];\n for (const resolve of waiters) {\n resolve();\n }\n }\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomBytes } from \"node:crypto\";\n\nconst spanIdStore = new AsyncLocalStorage<string>();\n\n/**\n * The `spanId` of the innermost `Logger.span()` block active in this\n * execution context, or `undefined` outside any span. Backed by\n * `AsyncLocalStorage` (not a plain module variable) so concurrent async\n * operations sharing one `Logger` don't see each other's span nesting —\n * the Node equivalent of Python's `contextvars`-based `current_span_id()`.\n */\nexport function currentSpanId(): string | undefined {\n return spanIdStore.getStore();\n}\n\n/** A 16-hex-char id, matching the shape of an OTel span id. */\nexport function newSpanId(): string {\n return randomBytes(8).toString(\"hex\");\n}\n\n/**\n * Runs `fn` with `spanId` as the active span for the rest of its\n * synchronous execution and every asynchronous continuation chained from\n * it — including `await`s inside `fn` — so nested log calls and nested\n * `span()` blocks resolve `currentSpanId()` correctly without needing to\n * be passed the span explicitly.\n */\nexport function runInSpan<T>(spanId: string, fn: () => T): T {\n return spanIdStore.run(spanId, fn);\n}\n","import { currentContext } from \"#context\";\nimport { DispatchQueue, type DispatchQueueOptions } from \"./dispatch-queue.js\";\nimport { Level, parseLevel, type LevelInput } from \"./levels.js\";\nimport { FunctionPlugin, type MiddlewareFunc, type Plugin } from \"./plugin.js\";\nimport { createRecord, type LogRecord } from \"./records.js\";\nimport { currentSpanId, newSpanId, runInSpan } from \"#span\";\nimport type { Transport } from \"../transports/transport.js\";\n\n/** Options for `Logger.span()`. Any extra keys become the span's own `meta`. */\nexport interface SpanOptions extends Record<string, unknown> {\n /** Adopt an id handed in from elsewhere (e.g. a framework's own run id) instead of generating one. */\n spanId?: string;\n /** Adopt a parent id explicitly, overriding auto-nesting from an enclosing `span()` block. */\n parentSpanId?: string;\n}\n\nfunction formatSpanError(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n return String(error);\n}\n\n/**\n * If `meta.err` is an `Error`, replaces it with a formatted `meta.stack`\n * (the JS analogue of `logquill-python`'s `exc_info` kwarg, which pops\n * `exc_info` and populates `meta[\"stack\"]` the same way). Left as-is\n * otherwise — a non-`Error` `meta.err` is passed through unchanged rather\n * than rejected, so a call site can't crash logging by getting this wrong.\n */\nfunction withStackFromErr(meta: Record<string, unknown>): Record<string, unknown> {\n const err = meta.err;\n if (!(err instanceof Error)) {\n return meta;\n }\n const next = { ...meta };\n delete next.err;\n next.stack = err.stack ?? `${err.name}: ${err.message}`;\n return next;\n}\n\n/** Options for the {@link Logger} constructor. */\nexport interface LoggerOptions {\n /** Minimum level that reaches a transport; records below it are dropped before any plugin runs. Default `INFO`. */\n level?: LevelInput;\n /** Sinks every record that passes the level filter and plugin pipeline is written to. */\n transports?: Transport[];\n /** Registered via `.use()` in order — a plain function is wrapped as an anonymous `Plugin`. */\n plugins?: (Plugin | MiddlewareFunc)[];\n /** Merged into every record's `meta`, before a call-site `meta` value (which always wins on collision). */\n meta?: Record<string, unknown>;\n /** Bounds and backpressure policy for the internal async dispatch queue. See `DispatchQueueOptions`. */\n queue?: DispatchQueueOptions;\n}\n\n/**\n * The core logger: leveled, structured logging over a pluggable transport\n * and plugin pipeline. Every log call returns the finished `LogRecord` (or\n * `null` if it was filtered by level or dropped by a plugin) synchronously —\n * the actual transport writes are dispatched onto an internal queue so the\n * call returns before any I/O runs; see `flush()`/`close()`.\n */\nexport class Logger {\n /** This logger's name, as passed to the constructor (or derived via `.child()`). Appears on every record as `logger`. */\n readonly name: string;\n /** Every transport a written record is sent to. */\n readonly transports: Transport[];\n /** Every plugin registered via `.use()`, in registration order. */\n readonly plugins: Plugin[];\n private currentLevel: Level;\n private readonly baseMeta: Record<string, unknown>;\n private dispatchQueue: DispatchQueue;\n\n constructor(name: string, options: LoggerOptions = {}) {\n this.name = name;\n this.currentLevel = parseLevel(options.level ?? Level.INFO);\n this.transports = options.transports ? [...options.transports] : [];\n this.plugins = [];\n for (const plugin of options.plugins ?? []) {\n this.use(plugin);\n }\n this.baseMeta = options.meta ? { ...options.meta } : {};\n this.dispatchQueue = new DispatchQueue(options.queue);\n }\n\n /** This logger's current minimum level — records below it are filtered before any plugin runs. */\n get level(): Level {\n return this.currentLevel;\n }\n\n /** Changes the minimum level records must meet to reach a transport. Accepts a `Level`, its numeric weight, or its name. */\n setLevel(level: LevelInput): void {\n this.currentLevel = parseLevel(level);\n }\n\n /**\n * Register a plugin, or a plain `beforeLog`-style function. A function is\n * wrapped internally as an anonymous `Plugin` (`FunctionPlugin`) — the\n * same middleware ergonomics as Express/Koa, without needing to read the\n * `Plugin` interface first. Returns `this` so calls can be chained.\n */\n use(plugin: Plugin | MiddlewareFunc): this {\n this.plugins.push(typeof plugin === \"function\" ? new FunctionPlugin(plugin) : plugin);\n return this;\n }\n\n /** Number of dispatched records not yet written to their transports. Bounded by the `queue` option. */\n get queueSize(): number {\n return this.dispatchQueue.size;\n }\n\n /**\n * Waits for every record dispatched so far to reach its transports'\n * `write()` (and any plugin `afterLog` hooks). Note this does *not* force\n * a batching transport (SQL, a queue, `HTTPTransport`, ...) to send a\n * batch still under its own `maxRecords`/`maxBytes` threshold early — it\n * only guarantees the record has been handed to that transport, the same\n * contract `write()` always had. Before a process may pause or exit\n * (a serverless freeze, a shutdown signal), prefer `withLambda`/\n * `installShutdownHandlers`, which additionally force every batching\n * transport to send its current buffer regardless of threshold.\n */\n async flush(): Promise<void> {\n await this.dispatchQueue.flush();\n }\n\n /** Flush every pending record, then close every attached transport. Call once, on shutdown. */\n async close(): Promise<void> {\n await this.flush();\n for (const transport of this.transports) {\n transport.close();\n }\n }\n\n /** A logger scoped under this one, inheriting its level, transports, plugins, and dispatch queue. */\n child(name: string, meta: Record<string, unknown> = {}): Logger {\n const child = new Logger(`${this.name}.${name}`, {\n level: this.currentLevel,\n transports: this.transports,\n plugins: this.plugins,\n meta: { ...this.baseMeta, ...meta },\n });\n child.dispatchQueue = this.dispatchQueue;\n return child;\n }\n\n private notifyError(plugin: Plugin, error: unknown, record: LogRecord): void {\n // a broken error handler must not crash logging either\n try {\n plugin.onError?.(error, record);\n } catch {\n /* swallowed */\n }\n }\n\n private dispatch(level: Level, message: string, meta: Record<string, unknown>): LogRecord | null {\n if (level < this.currentLevel) {\n return null;\n }\n\n let record = createRecord({\n level,\n logger: this.name,\n message,\n meta: { ...this.baseMeta, ...currentContext(), ...withStackFromErr(meta) },\n });\n\n const parentSpanId = currentSpanId();\n if (parentSpanId !== undefined) {\n record.meta.parentSpanId ??= parentSpanId;\n }\n\n for (const plugin of this.plugins) {\n let result: LogRecord | null;\n try {\n result = plugin.beforeLog ? plugin.beforeLog(record) : record;\n } catch (error) {\n this.notifyError(plugin, error, record);\n continue;\n }\n if (result === null) {\n return null;\n }\n record = result;\n }\n\n // The write itself (I/O) and afterLog are deferred onto the dispatch\n // queue so this call returns before either runs — see DispatchQueue.\n // They're bundled into one task to preserve the existing contract that\n // afterLog fires only once the record has reached every transport.\n this.dispatchQueue.enqueue(() => {\n this.writeAndNotify(record);\n });\n\n return record;\n }\n\n private writeAndNotify(record: LogRecord): void {\n for (const transport of this.transports) {\n try {\n transport.write(transport.format(record), record);\n } catch (error) {\n // a transport that can't format or write this particular record\n // (e.g. a circular reference in `meta`) must not crash the caller\n console.error(`${transport.constructor.name}: failed to write a log record`, error);\n }\n }\n\n for (const plugin of this.plugins) {\n try {\n plugin.afterLog?.(record);\n } catch (error) {\n this.notifyError(plugin, error, record);\n }\n }\n }\n\n /** Logs at `TRACE` — the lowest level, for fine-grained diagnostic detail. Returns the record, or `null` if filtered/dropped. */\n trace(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.TRACE, message, meta);\n }\n\n /** Logs at `DEBUG`. Returns the record, or `null` if filtered/dropped. */\n debug(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.DEBUG, message, meta);\n }\n\n /** Logs at `INFO`. Returns the record, or `null` if filtered/dropped. */\n info(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, meta);\n }\n\n /** Logs at `WARN`. Returns the record, or `null` if filtered/dropped. */\n warn(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.WARN, message, meta);\n }\n\n /** Logs at `ERROR`. Returns the record, or `null` if filtered/dropped. */\n error(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.ERROR, message, meta);\n }\n\n /** Logs at `FATAL` — the highest level, for errors that precede an unrecoverable failure. Returns the record, or `null` if filtered/dropped. */\n fatal(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.FATAL, message, meta);\n }\n\n /** `.info()` tagged `meta.kind = \"thought\"` — an agent's internal reasoning step, for harness/agentic tracing. */\n thought(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, { kind: \"thought\", ...meta });\n }\n\n /** `.info()` tagged `meta.kind = \"action\"` — an agent taking an action (a tool call, an LLM request), for harness/agentic tracing. */\n action(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, { kind: \"action\", ...meta });\n }\n\n /** `.info()` tagged `meta.kind = \"observation\"` — the result an agent observed from an action, for harness/agentic tracing. */\n observation(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, { kind: \"observation\", ...meta });\n }\n\n /** `.info()` tagged `meta.kind = \"decision\"` — an agent's concluding decision for a step or run, for harness/agentic tracing. */\n decision(message: string, meta: Record<string, unknown> = {}): LogRecord | null {\n return this.dispatch(Level.INFO, message, { kind: \"decision\", ...meta });\n }\n\n /**\n * `await logger.span(\"callLlm\", async () => {...})` — runs `fn`, and on\n * settling (success or throw) emits one record for the span itself\n * carrying `meta.spanId` and `meta.durationMs`. Every record logged\n * inside `fn` — through any method, and through any further `await` —\n * is automatically stamped with `meta.parentSpanId` pointing at this\n * span, so nested/sub-agent calls reconstruct their exact nesting when\n * sorted by `spanId`/`parentSpanId`.\n *\n * Still emits its record — at `ERROR`, with `meta.error` set — if `fn`\n * throws; the error itself propagates unchanged to the caller.\n *\n * `spanId`/`parentSpanId` normally auto-generate/auto-nest; pass them in\n * `options` to adopt an id handed in from elsewhere (e.g. a framework\n * adapter translating an id it already received).\n */\n async span<T>(name: string, fn: () => T | Promise<T>, options: SpanOptions = {}): Promise<T> {\n const { spanId: explicitSpanId, parentSpanId: explicitParentSpanId, ...meta } = options;\n const spanId = explicitSpanId ?? newSpanId();\n const start = performance.now();\n\n try {\n const result = await runInSpan(spanId, () => fn());\n this.finishSpan(name, spanId, explicitParentSpanId, performance.now() - start, meta);\n return result;\n } catch (error) {\n this.finishSpan(name, spanId, explicitParentSpanId, performance.now() - start, meta, error);\n throw error;\n }\n }\n\n private finishSpan(\n name: string,\n spanId: string,\n explicitParentSpanId: string | undefined,\n durationMs: number,\n meta: Record<string, unknown>,\n error?: unknown,\n ): void {\n const fullMeta: Record<string, unknown> = {\n spanId,\n durationMs: Math.round(durationMs * 1000) / 1000,\n ...meta,\n };\n if (explicitParentSpanId !== undefined) {\n fullMeta.parentSpanId = explicitParentSpanId;\n }\n fullMeta.kind ??= \"span\";\n if (error !== undefined) {\n fullMeta.error = formatSpanError(error);\n }\n this.dispatch(error !== undefined ? Level.ERROR : Level.INFO, name, fullMeta);\n }\n}\n","import { hasFlush } from \"../transports/transport.js\";\nimport type { Logger } from \"./logger.js\";\n\nasync function flushEverything(logger: Logger): Promise<void> {\n await logger.flush();\n // logger.flush() only guarantees records reached each transport's write()\n // — a batching transport (SQL, a queue, HTTPTransport, ...) may still be\n // sitting on a batch under its own threshold. Force those out too: a\n // frozen/recycled execution environment may never come back to finish it.\n for (const transport of logger.transports) {\n if (!hasFlush(transport)) {\n continue;\n }\n try {\n await transport.flush();\n } catch (error) {\n console.error(`${transport.constructor.name}: failed to flush`, error);\n }\n }\n}\n\n/**\n * Wraps a serverless handler so `logger.flush()` is awaited before the\n * wrapped function returns or throws. A serverless runtime can freeze or\n * recycle its execution environment the instant a handler settles, so\n * anything still sitting in the dispatch queue — or a batching transport's\n * own buffer — needs to be sent before that happens, not left for an\n * invocation that may not come for a while (or ever, if the environment is\n * torn down instead of frozen).\n *\n * The handler shape itself doesn't matter here — only that `fn` is an async\n * function whose settling is the runtime's cue to freeze — so the same\n * wrapper covers AWS Lambda, GCP Cloud Functions, and Azure Functions\n * equally; `withLambda`/`withCloudFunction`/`withAzureFunction` are the same\n * function under names that match each platform's docs.\n *\n * ```ts\n * export const handler = withLambda(logger, async (event) => {\n * logger.info(\"handling request\", { requestId: event.requestId });\n * return { statusCode: 200 };\n * });\n * ```\n */\nexport function withFlush<Args extends unknown[], TResult>(\n logger: Logger,\n fn: (...args: Args) => Promise<TResult>,\n): (...args: Args) => Promise<TResult> {\n return async (...args: Args): Promise<TResult> => {\n try {\n return await fn(...args);\n } finally {\n await flushEverything(logger);\n }\n };\n}\n\n/** `withFlush`, named for an AWS Lambda handler. */\nexport const withLambda = withFlush;\n/** `withFlush`, named for a GCP Cloud Functions handler. */\nexport const withCloudFunction = withFlush;\n/** `withFlush`, named for an Azure Functions handler. */\nexport const withAzureFunction = withFlush;\n","import type { Logger } from \"./logger.js\";\n\n/** Options for {@link installShutdownHandlers}. */\nexport interface ShutdownHandlerOptions {\n /** Signals to flush-and-close on (e.g. an orchestrator's SIGTERM). Default `[\"SIGTERM\", \"SIGINT\"]`. */\n signals?: NodeJS.Signals[];\n}\n\n/**\n * Registers listeners so `logger.close()` runs once as the process ends —\n * on `beforeExit` (the event loop draining naturally) and on the given\n * `signals` (a container/orchestrator asking the process to stop) — so\n * whatever is still in the dispatch queue or a batching transport's buffer\n * isn't silently lost. Node-only (uses `process`); don't call this from a\n * browser bundle.\n *\n * Registering a listener for a signal like `SIGTERM` opts this process out\n * of Node's default \"terminate immediately\" behavior for it, so this\n * function calls `process.exit(0)` itself once `close()` settles — `\n * beforeExit` doesn't need that, since the process is already on its way\n * out there.\n *\n * Returns a function that removes the listeners again — call it in tests,\n * or if the caller wants to manage its own shutdown lifecycle instead.\n */\nexport function installShutdownHandlers(logger: Logger, options: ShutdownHandlerOptions = {}): () => void {\n const signals = options.signals ?? [\"SIGTERM\", \"SIGINT\"];\n let closed = false;\n\n const shutdown = (exitAfter: boolean): void => {\n if (closed) {\n return;\n }\n closed = true;\n logger\n .close()\n .catch((error: unknown) => {\n console.error(\"installShutdownHandlers: logger.close() failed during shutdown\", error);\n })\n .finally(() => {\n if (exitAfter) {\n process.exit(0);\n }\n });\n };\n\n const onBeforeExit = (): void => {\n shutdown(false);\n };\n const onSignal = (): void => {\n shutdown(true);\n };\n\n process.once(\"beforeExit\", onBeforeExit);\n for (const signal of signals) {\n process.once(signal, onSignal);\n }\n\n return () => {\n process.removeListener(\"beforeExit\", onBeforeExit);\n for (const signal of signals) {\n process.removeListener(signal, onSignal);\n }\n };\n}\n","export { Level, levelName, parseLevel } from \"./core/levels.js\";\nexport type { LevelInput } from \"./core/levels.js\";\n\nexport { createRecord, utcTimestamp } from \"./core/records.js\";\nexport type { LogRecord } from \"./core/records.js\";\n\nexport { JSONFormatter } from \"./core/formatter.js\";\nexport type { Formatter } from \"./core/formatter.js\";\n\nexport type { Plugin, MiddlewareFunc } from \"./core/plugin.js\";\nexport { FunctionPlugin } from \"./core/plugin.js\";\n\nexport { ContextPlugin } from \"./plugins/context-plugin.js\";\n\nexport { bindContext, currentContext } from \"./core/context.js\";\n\nexport { RateLimitPlugin } from \"./plugins/rate-limit-plugin.js\";\nexport type { RateLimitKeyFunc, RateLimitPluginOptions } from \"./plugins/rate-limit-plugin.js\";\n\nexport { DEFAULT_PINO_LEVEL_MAP, LogQuillPinoDestination } from \"./bridges/pino-destination.js\";\nexport type { LogQuillPinoDestinationOptions, PinoLevelMap } from \"./bridges/pino-destination.js\";\n\nexport { RunPlugin } from \"./plugins/run-plugin.js\";\nexport type { RunPluginOptions } from \"./plugins/run-plugin.js\";\n\nexport {\n defaultResolveActiveOtelTraceId,\n generateTraceId,\n getTraceparent,\n parseTraceHeader,\n setTraceparent,\n TraceContextPlugin,\n} from \"./plugins/trace-context-plugin.js\";\nexport type { TraceContextPluginOptions } from \"./plugins/trace-context-plugin.js\";\n\nexport { OtelSpanProcessor } from \"./plugins/otel-span-processor.js\";\nexport type {\n OtelSpanContextLike,\n OtelSpanLike,\n OtelSpanProcessorOptions,\n OtelStatusLike,\n} from \"./plugins/otel-span-processor.js\";\n\nexport { DEFAULT_REDACTED_KEYS, RedactPlugin } from \"./plugins/redact-plugin.js\";\nexport type { RedactPluginOptions } from \"./plugins/redact-plugin.js\";\n\nexport { DEFAULT_PII_PATTERNS, PIIRedactPlugin } from \"./plugins/pii-redact-plugin.js\";\nexport type { PIIRedactPluginOptions } from \"./plugins/pii-redact-plugin.js\";\n\nexport { SamplingPlugin } from \"./plugins/sampling-plugin.js\";\nexport type { SamplingPluginOptions } from \"./plugins/sampling-plugin.js\";\n\nexport { GENESIS_HASH, TamperEvidentPlugin } from \"./plugins/tamper-evident-plugin.js\";\nexport type { TamperEvidentPluginOptions } from \"./plugins/tamper-evident-plugin.js\";\n\nexport { AlertingPlugin } from \"./plugins/alerting-plugin.js\";\nexport type { AlertingPluginOptions } from \"./plugins/alerting-plugin.js\";\n\nexport { SlackAlertPlugin } from \"./plugins/slack-alert-plugin.js\";\nexport type { SlackAlertPluginOptions, SlackSender } from \"./plugins/slack-alert-plugin.js\";\n\nexport { PagerDutyAlertPlugin } from \"./plugins/pagerduty-alert-plugin.js\";\nexport type {\n PagerDutyAlertPluginOptions,\n PagerDutySender,\n} from \"./plugins/pagerduty-alert-plugin.js\";\n\nexport { EmailAlertPlugin } from \"./plugins/email-alert-plugin.js\";\nexport type {\n EmailAlertPluginOptions,\n EmailMessage,\n EmailSender,\n NodemailerTransporterLike,\n} from \"./plugins/email-alert-plugin.js\";\n\nexport { CollectingTransport, hasFlush, Transport } from \"./transports/transport.js\";\nexport type { FlushableTransport } from \"./transports/transport.js\";\n\nexport { BatchingTransport } from \"./transports/batching-transport.js\";\nexport type { BatchingTransportOptions } from \"./transports/batching-transport.js\";\n\nexport { BaseSQLTransport } from \"./transports/sql/base-sql-transport.js\";\nexport type { BaseSQLTransportOptions, SQLLogRow } from \"./transports/sql/base-sql-transport.js\";\n\nexport { SQLiteTransport } from \"./transports/sql/sqlite-transport.js\";\nexport type {\n SQLiteClientLike,\n SQLiteStatementLike,\n SQLiteTransportOptions,\n} from \"./transports/sql/sqlite-transport.js\";\n\nexport { PostgresTransport } from \"./transports/sql/postgres-transport.js\";\nexport type {\n PgClientLike,\n PostgresTransportOptions,\n} from \"./transports/sql/postgres-transport.js\";\n\nexport { MySQLTransport } from \"./transports/sql/mysql-transport.js\";\nexport type { MySQLClientLike, MySQLTransportOptions } from \"./transports/sql/mysql-transport.js\";\n\nexport { MongoDBTransport } from \"./transports/nosql/mongodb-transport.js\";\nexport type {\n MongoClientLike,\n MongoCollectionLike,\n MongoDBTransportOptions,\n} from \"./transports/nosql/mongodb-transport.js\";\n\nexport { DynamoDBTransport } from \"./transports/nosql/dynamodb-transport.js\";\nexport type {\n DynamoClientLike,\n DynamoLogItem,\n DynamoDBTransportOptions,\n} from \"./transports/nosql/dynamodb-transport.js\";\n\nexport { RedisTransport } from \"./transports/nosql/redis-transport.js\";\nexport type { RedisClientLike, RedisTransportOptions } from \"./transports/nosql/redis-transport.js\";\n\nexport { BaseQueueTransport } from \"./transports/queue/base-queue-transport.js\";\nexport type { BaseQueueTransportOptions } from \"./transports/queue/base-queue-transport.js\";\n\nexport { KafkaTransport } from \"./transports/queue/kafka-transport.js\";\nexport type {\n KafkaProducerLike,\n KafkaTransportOptions,\n} from \"./transports/queue/kafka-transport.js\";\n\nexport { RabbitMQTransport } from \"./transports/queue/rabbitmq-transport.js\";\nexport type {\n AmqpChannelLike,\n RabbitMQTransportOptions,\n} from \"./transports/queue/rabbitmq-transport.js\";\n\nexport { SQSTransport } from \"./transports/queue/sqs-transport.js\";\nexport type { SQSClientLike, SQSTransportOptions } from \"./transports/queue/sqs-transport.js\";\n\nexport { PubSubTransport } from \"./transports/queue/pubsub-transport.js\";\nexport type {\n PubSubTopicLike,\n PubSubTransportOptions,\n} from \"./transports/queue/pubsub-transport.js\";\n\nexport { CloudWatchTransport } from \"./transports/cloud/cloudwatch-transport.js\";\nexport type {\n CloudWatchClientLike,\n CloudWatchLogEvent,\n CloudWatchTransportOptions,\n} from \"./transports/cloud/cloudwatch-transport.js\";\n\nexport { CloudLoggingTransport } from \"./transports/cloud/cloud-logging-transport.js\";\nexport type {\n CloudLoggingClientLike,\n CloudLoggingEntry,\n CloudLoggingTransportOptions,\n} from \"./transports/cloud/cloud-logging-transport.js\";\n\nexport { AppInsightsTransport } from \"./transports/cloud/app-insights-transport.js\";\nexport type {\n AppInsightsClientLike,\n AppInsightsTrace,\n AppInsightsTransportOptions,\n} from \"./transports/cloud/app-insights-transport.js\";\n\nexport { DatadogTransport } from \"./transports/cloud/datadog-transport.js\";\nexport type {\n DatadogSender,\n DatadogTransportOptions,\n} from \"./transports/cloud/datadog-transport.js\";\n\nexport { ElasticsearchTransport } from \"./transports/cloud/elasticsearch-transport.js\";\nexport type {\n ElasticsearchSender,\n ElasticsearchTransportOptions,\n} from \"./transports/cloud/elasticsearch-transport.js\";\n\nexport { NewRelicTransport } from \"./transports/cloud/new-relic-transport.js\";\nexport type {\n NewRelicRegion,\n NewRelicSender,\n NewRelicSenderResult,\n NewRelicTransportOptions,\n} from \"./transports/cloud/new-relic-transport.js\";\n\nexport { ConsoleTransport } from \"./transports/console-transport.js\";\nexport type { ConsoleLike, ConsoleTransportOptions } from \"./transports/console-transport.js\";\n\nexport { BeaconTransport } from \"./transports/beacon-transport.js\";\nexport type { BeaconSender, BeaconTransportOptions } from \"./transports/beacon-transport.js\";\n\nexport { FileTransport } from \"./transports/file-transport.js\";\nexport type { FileTransportOptions } from \"./transports/file-transport.js\";\n\nexport { HTTPTransport } from \"./transports/http-transport.js\";\nexport type { HTTPTransportOptions, Sender } from \"./transports/http-transport.js\";\n\nexport { Logger } from \"./core/logger.js\";\nexport type { LoggerOptions, SpanOptions } from \"./core/logger.js\";\n\nexport { DispatchQueue } from \"./core/dispatch-queue.js\";\nexport type { BackpressurePolicy, DispatchQueueOptions, Task } from \"./core/dispatch-queue.js\";\n\nexport { withAzureFunction, withCloudFunction, withFlush, withLambda } from \"./core/serverless.js\";\n\nexport { installShutdownHandlers } from \"./core/shutdown.js\";\nexport type { ShutdownHandlerOptions } from \"./core/shutdown.js\";\n\n/** This package's version, matching `package.json`'s `version` field. */\nexport const VERSION = \"0.3.0\";\n"]}