@veris-ai/daytona 0.2.1 → 0.3.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/daytona.ts","../src/errors.ts","../src/control-plane.ts","../src/receipt.ts","../src/network.ts","../src/trust.ts","../src/gateway.ts","../src/state.ts","../src/veris-api.ts","../src/version.ts"],"sourcesContent":["// @veris-ai/daytona — Veris twin interception for Daytona sandboxes.\n//\n// This is the ENGINE integration, and it is deliberately generic: it knows\n// nothing about what you run in the sandbox, and needs no particular image.\n// Running an agent in there is one use of it (see @veris-ai/daytona-opencode)\n// rather than what it is for — the same relationship @veris-ai/e2b has to E2B.\n//\n// A drop-in for @daytona/sdk. The only difference is that `Daytona` is ours,\n// so every sandbox it creates comes up with a Veris twin already answering its\n// vendor API calls:\n//\n// import { Daytona } from '@veris-ai/daytona' // was '@daytona/sdk'\n// const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })\n// const sbx = await daytona.create()\n// await sbx.process.executeCommand('curl https://api.stripe.com/v1/charges')\n// await sbx.veris.assertTouched('stripe')\n// await sbx.delete() // deletes the twin too\n//\n// Everything else from @daytona/sdk is re-exported unchanged, so apps depend\n// only on this package.\n//\n// @daytona/sdk is a PEER dependency, deliberately. Consumers do\n// `err instanceof DaytonaNotFoundError` on errors that cross this boundary\n// (the OpenCode plugin branches on exactly that to tell \"sandbox is gone\" from\n// \"transient failure\"), and two copies of the SDK in one tree would make those\n// checks silently return false.\nexport * from '@daytona/sdk'\n\n// Ours wins the name. An explicit local export takes precedence over the star\n// above, which is the whole trick that makes the plugin fork a one-line diff.\nexport { Daytona, default } from './daytona'\nexport type { VerisOpts, VerisDaytonaConfig, VerisSandbox } from './daytona'\nexport { isVerisSandbox } from './daytona'\n\nexport type { VerisApi, TouchMatcher, DeliverToOpts, VerisContext } from './veris-api'\nexport type { Receipt, ReceiptEntry, ReceiptRequest, ReceiptLeak } from './receipt'\nexport type { EgressMode, NetworkParams } from './network'\nexport { DEFAULT_REGISTRY_HOSTS, vendorHosts, twinHosts, dataPlaneHosts } from './network'\nexport type { ServiceInfo as VerisServiceInfo, RouteEntry, TwinSandbox } from './control-plane'\nexport { ControlPlane } from './control-plane'\nexport { CA_CERT_PATH, SYSTEM_BUNDLE, VERIS_BUNDLE, VERIS_CA_FILE, vendoredTrustEnv } from './trust'\nexport { gatewayProxyUrl } from './gateway'\nexport { fetchManual, assertHttpControlPlane } from './state'\nexport {\n VerisError,\n MissingCredentialsError,\n VerisGatewayUnreachableError,\n VerisGatewayNotOfferedError,\n ReceiptIntegrityError,\n VerisUntouchedError,\n TwinExpiredError,\n SnapshotUnsupportedError,\n UnsupportedOperationError,\n} from './errors'\nexport type { VerisErrorPhase } from './errors'\nexport { SDK_VERSION } from './version'\n","// The Veris Daytona client: a drop-in subclass of @daytona/sdk's Daytona whose\n// sandboxes come up with a Veris twin already answering their vendor calls.\n//\n// Everything the product needs happens inside create() — snapshot registration,\n// twin provisioning, the network allowlist, the CA, starting the proxy and\n// waiting for it to bind. That is deliberate: it keeps the OpenCode plugin's\n// diff to a single changed import, and it means create() resolving is a promise\n// that interception is live.\n//\n// Note we do NOT subclass Sandbox the way @veris-ai/e2b does. Daytona builds\n// Sandbox internally from seven arguments, six of them private SDK types, so\n// there is nothing to extend. We enrich the params, call super, and attach the\n// Veris surface to the instance that comes back.\nimport { Daytona as BaseDaytona } from '@daytona/sdk'\nimport type {\n CreateSandboxFromImageParams,\n CreateSandboxFromSnapshotParams,\n DaytonaConfig,\n Image,\n ListSandboxesQuery,\n Sandbox,\n} from '@daytona/sdk'\nimport { ControlPlane } from './control-plane'\nimport type { TwinSandbox } from './control-plane'\nimport { VerisApiImpl } from './veris-api'\nimport type { VerisApi, VerisContext } from './veris-api'\nimport { buildNetwork, dataPlaneEnv } from './network'\nimport type { EgressMode } from './network'\nimport { CA_CERT_PATH, sanitizeTrustEnv } from './trust'\nimport { gatewayProxyUrl, installCa, probeCanary } from './gateway'\nimport { MissingCredentialsError, VerisError, VerisGatewayNotOfferedError } from './errors'\nimport { SDK_VERSION } from './version'\n\nexport interface VerisOpts {\n /** Veris API key. Falls back to process.env.VERIS_API_KEY. Required. */\n apiKey?: string\n /** Veris environment the twin is deployed from. Falls back to process.env.VERIS_ENVIRONMENT_ID. */\n environmentId?: string\n /** Control plane base. Falls back to process.env.VERIS_API_BASE, then 'https://svc.api.veris.ai'. */\n apiBase?: string\n /** Attach to an EXISTING twin instead of provisioning one (advanced). delete() will NOT remove it. */\n attachSandboxId?: string\n /** Twin TTL backstop, minutes. Default 60, kept in step with the sandbox's ttlMinutes. */\n ttlMinutes?: number\n /** 'strict' (default): the sandbox reaches only its twin, its data planes,\n * the control plane and package registries. 'open': no allowlist at all —\n * debugging only, because a bypassing client then reaches the real vendor. */\n egress?: EgressMode\n /** Extra hostnames to allow out. */\n allowOut?: string[]\n /** Allow package registries (npm, PyPI, apt, …). Default true: a coding\n * sandbox that cannot install dependencies is not usable. */\n allowRegistries?: boolean\n /** Install the gateway CA into the sandbox trust store. Default true; without\n * it every HTTPS call to a vendor host fails certificate validation. */\n installCa?: boolean\n /** Inject { [env_hint]: dsn } for non-HTTP twin services. Default true. */\n dataPlaneEnv?: boolean\n /** Turn Veris off entirely for this create — a plain Daytona sandbox. */\n disabled?: boolean\n}\n\nexport interface VerisDaytonaConfig extends DaytonaConfig {\n veris?: VerisOpts\n}\n\ntype CreateParams = (CreateSandboxFromSnapshotParams | CreateSandboxFromImageParams) & { veris?: VerisOpts }\n\n/** Labels the class stamps so get() can rehydrate without re-asking. */\nconst LABEL = {\n twinId: 'veris_twin_id',\n envId: 'veris_env_id',\n apiBase: 'veris_api_base',\n mode: 'veris_mode',\n egress: 'veris_egress',\n ownsTwin: 'veris_owns_twin',\n canaryHost: 'veris_canary_host',\n} as const\n\nconst VERIS_LABEL_KEYS: readonly string[] = Object.values(LABEL)\n\n/** A Daytona sandbox with the Veris surface attached. */\nexport type VerisSandbox = Sandbox & {\n /** Receipts, services, assertions. Everything Veris adds. */\n veris: VerisApi\n /** The Veris twin's id. Not to be confused with `sandbox.id`, the Daytona one. */\n verisSandboxId: string\n}\n\n/** Is this sandbox one of ours? Narrows for callers who hold a bare Sandbox. */\nexport function isVerisSandbox(sbx: Sandbox): sbx is VerisSandbox {\n return typeof (sbx as VerisSandbox).verisSandboxId === 'string'\n}\n\nexport class Daytona extends BaseDaytona {\n private readonly verisDefaults: VerisOpts\n\n constructor(config?: VerisDaytonaConfig) {\n super(config)\n this.verisDefaults = config?.veris ?? {}\n }\n\n // Both of the base class's overloads, redeclared so a caller passing either\n // params shape still type-checks against the subclass.\n override create(\n params?: CreateSandboxFromSnapshotParams & { veris?: VerisOpts },\n options?: { timeout?: number },\n ): Promise<Sandbox>\n override create(\n params?: CreateSandboxFromImageParams & { veris?: VerisOpts },\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox>\n override async create(\n params?: CreateParams,\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox> {\n const v: VerisOpts = { ...this.verisDefaults, ...(params?.veris ?? {}) }\n const rest = stripVeris(params)\n\n if (v.disabled) return this.baseCreate(rest, options)\n\n const coords = resolveCoordinates(v)\n const controlPlane = new ControlPlane({\n apiKey: coords.apiKey, apiBase: coords.apiBase, sdkVersion: SDK_VERSION,\n })\n const egress: EgressMode = v.egress ?? 'strict'\n const ttlMinutes = v.ttlMinutes ?? 60\n const ownsTwin = !v.attachSandboxId\n\n // 1. Provision the twin first: the allowlist needs the vendor hostnames it\n // answers for, and the egress credential is minted against it.\n const twin = await this.provisionTwin(controlPlane, v, coords, ttlMinutes)\n const cleanupTwin = async () => {\n if (ownsTwin) await controlPlane.deleteTwin(twin.environment_id, twin.id).catch(() => {})\n }\n\n let sandbox: Sandbox\n let credential\n try {\n // 2. Mint the egress credential. Daytona accepts only http/https outbound\n // proxies, so a control plane that offers SOCKS alone cannot be used\n // here at all — say so plainly rather than failing later in TLS.\n credential = await controlPlane.mintEgressCredential(twin.environment_id, twin.id)\n if (!credential) {\n throw new VerisGatewayNotOfferedError(\n 'this Veris control plane does not offer egress credentials, so there is no gateway ' +\n 'for the sandbox to route through',\n { phase: 'credential-mint', verisSandboxId: twin.id })\n }\n if (!credential.connect_address && !credential.http_proxy_url) {\n throw new VerisGatewayNotOfferedError(\n 'the Veris gateway offers SOCKS5 but no HTTP CONNECT endpoint, and Daytona accepts ' +\n 'only http/https outbound proxies (\"Unsupported outbound proxy scheme\"). Upgrade the ' +\n 'control plane to one that returns connect_address.',\n { phase: 'credential-mint', verisSandboxId: twin.id })\n }\n\n const services = twin.services?.length ? twin.services : await controlPlane.services(twin.id)\n // Validated here, before it reaches either the allowlist or Daytona.\n const proxyUrl = gatewayProxyUrl(credential)\n const network = buildNetwork({\n services, mode: egress,\n // The gateway has to be reachable or nothing is: taken from the URL we\n // are actually going to use, so the two can never disagree.\n gatewayHosts: [new URL(proxyUrl).hostname, credential.canary_host].filter(Boolean),\n allowOut: v.allowOut, allowRegistries: v.allowRegistries,\n })\n\n // Veris-managed vars WIN over caller envs: a caller value for a\n // data-plane env_hint (e.g. DATABASE_URL) would silently point the code\n // under test at production.\n const verisManaged: Record<string, string> = {\n ...(v.installCa !== false ? sanitizeTrustEnv(undefined) : {}),\n ...(v.dataPlaneEnv !== false ? dataPlaneEnv(services) : {}),\n VERIS_SANDBOX_ID: twin.id,\n }\n\n const createParams = {\n ...rest,\n envVars: { ...(rest.envVars ?? {}), ...verisManaged },\n labels: {\n ...reserveLabels(rest.labels),\n [LABEL.twinId]: twin.id,\n [LABEL.envId]: twin.environment_id,\n [LABEL.apiBase]: coords.apiBase,\n [LABEL.egress]: egress,\n [LABEL.ownsTwin]: String(ownsTwin),\n [LABEL.mode]: 'gateway',\n [LABEL.canaryHost]: credential.canary_host,\n },\n ...network,\n // 3. Where Daytona forwards everything the allowlist permits. Chained,\n // not advisory: an unreachable gateway makes allowed traffic 502\n // rather than quietly going direct.\n outboundProxyUrl: proxyUrl,\n ttlMinutes: rest.ttlMinutes ?? ttlMinutes,\n }\n\n sandbox = await this.baseCreate(createParams as CreateParams, options)\n } catch (cause) {\n await cleanupTwin()\n if (cause instanceof VerisError) throw cause\n throw new VerisError('Daytona sandbox create failed', {\n phase: 'sandbox-create', verisSandboxId: twin.id, cause })\n }\n\n // 4. Trust the gateway's CA, then prove the tunnel is live. Until the canary\n // answers, nothing about this sandbox is worth believing.\n try {\n await installCa(sandbox, credential.ca_pem)\n await probeCanary(sandbox, credential.canary_host, twin.id)\n } catch (err) {\n await sandbox.delete().catch(() => {})\n await cleanupTwin()\n throw err\n }\n\n return this.attach(sandbox, {\n controlPlane, environmentId: twin.environment_id, twinId: twin.id,\n egress, ownsTwin, canaryHost: credential.canary_host,\n })\n }\n\n /**\n * Rehydrate the Veris surface on an existing sandbox.\n *\n * Not an optimisation — a necessity. The OpenCode plugin reconnects to a\n * sandbox with get() on every resumed session and deletes through get() too,\n * so a get() that returned a bare Sandbox would mean no receipts after any\n * restart and a leaked twin on every delete.\n */\n override async get(sandboxIdOrName: string): Promise<Sandbox> {\n const sandbox = await super.get(sandboxIdOrName)\n return this.rehydrate(sandbox)\n }\n\n /** Same rehydration for the sandboxes a list() streams. */\n override list(query?: ListSandboxesQuery): AsyncIterableIterator<Sandbox> {\n const inner = super.list(query)\n const rehydrate = (s: Sandbox) => this.rehydrate(s)\n return (async function* () {\n for await (const sandbox of inner) yield rehydrate(sandbox)\n })()\n }\n\n /**\n * Attach the Veris surface to a sandbox whose labels say it has a twin.\n * A sandbox without our labels is passed through untouched — callers can use\n * this client for ordinary Daytona work.\n */\n private rehydrate(sandbox: Sandbox): Sandbox {\n const labels = sandbox.labels ?? {}\n const twinId = labels[LABEL.twinId]\n if (!twinId) return sandbox\n\n const apiKey = this.verisDefaults.apiKey ?? process.env.VERIS_API_KEY\n if (!apiKey) return sandbox // no key: no Veris surface, but not an error\n\n // A trusted source decides where the API key is sent — NEVER the sandbox\n // labels, which a compromised sandbox could rewrite to exfiltrate the key.\n const trustedBase = this.verisDefaults.apiBase ?? process.env.VERIS_API_BASE\n const labelBase = labels[LABEL.apiBase]\n if (trustedBase && labelBase && labelBase !== trustedBase) {\n throw new VerisError(\n `sandbox ${sandbox.id} labels name a different Veris control plane (${labelBase}) than ` +\n `your configuration (${trustedBase}) — refusing to send the API key to an unverified host`,\n { phase: 'attach' })\n }\n const apiBase = trustedBase ?? labelBase ?? 'https://svc.api.veris.ai'\n\n return this.attach(sandbox, {\n controlPlane: new ControlPlane({ apiKey, apiBase, sdkVersion: SDK_VERSION }),\n environmentId: labels[LABEL.envId] ?? '',\n twinId,\n // Re-minted below when a receipt is actually asked for; the label only\n // has to survive the reconnect.\n canaryHost: labels[LABEL.canaryHost] ?? '',\n egress: (labels[LABEL.egress] as EgressMode | undefined) ?? 'strict',\n ownsTwin: labels[LABEL.ownsTwin] !== 'false',\n })\n }\n\n private async provisionTwin(\n controlPlane: ControlPlane, v: VerisOpts, coords: ResolvedCoordinates, ttlMinutes: number,\n ): Promise<TwinSandbox> {\n if (v.attachSandboxId) {\n const existing = await controlPlane.getTwin(v.attachSandboxId)\n if (!existing) {\n throw new VerisError(`attach target ${v.attachSandboxId} not found`, {\n phase: 'twin-provision', verisSandboxId: v.attachSandboxId })\n }\n return existing.status === 'ready' ? existing : controlPlane.waitReady(v.attachSandboxId, 240_000)\n }\n if (!coords.environmentId) {\n throw new MissingCredentialsError(\n 'no Veris environment: set VERIS_ENVIRONMENT_ID, or pass veris.environmentId',\n { phase: 'credentials' })\n }\n const created = await controlPlane.createTwin(coords.environmentId, { ttlMinutes })\n try {\n return await controlPlane.waitReady(created.id, 240_000)\n } catch (e) {\n await controlPlane.deleteTwin(coords.environmentId, created.id).catch(() => {})\n throw e\n }\n }\n\n /**\n * Hang the Veris surface off the instance, and wrap delete() so teardown is\n * automatic.\n *\n * Wrapping rather than asking callers to remember is the point: the OpenCode\n * plugin's existing `sandbox.delete()` then removes the twin too, with no\n * change to the plugin at all. A twin outlives its sandbox otherwise, until\n * its TTL reaps it — invisible until the bill arrives.\n */\n private attach(sandbox: Sandbox, ctx: Omit<VerisContext, 'sandbox'>): Sandbox {\n // Attaching twice would capture our own wrapper as `originalDelete` and\n // tear the twin down twice. Only the prototype's delete is ever wrapped.\n if (isVerisSandbox(sandbox)) return sandbox\n\n const veris = new VerisApiImpl({ ...ctx, sandbox })\n const originalDelete = sandbox.delete.bind(sandbox)\n\n Object.defineProperties(sandbox, {\n veris: { value: veris, enumerable: true, configurable: true },\n verisSandboxId: { value: ctx.twinId, enumerable: true, configurable: true },\n delete: {\n configurable: true,\n value: async (timeout?: number, wait?: boolean): Promise<void> => {\n // Drop the twin before the container goes. Nothing to stop inside\n // the sandbox — the gateway is ours and host-side.\n if (ctx.ownsTwin) {\n await ctx.controlPlane.deleteTwin(ctx.environmentId, ctx.twinId).catch(() => {})\n }\n return originalDelete(timeout, wait)\n },\n },\n })\n return sandbox\n }\n\n /** super.create through the overload the params actually match. */\n private baseCreate(\n params: CreateParams | undefined,\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox> {\n type Create = (p?: CreateParams, o?: typeof options) => Promise<Sandbox>\n return (super.create as unknown as Create).call(this, params, options)\n }\n}\n\nexport default Daytona\n\ninterface ResolvedCoordinates {\n apiKey: string\n environmentId?: string\n apiBase: string\n}\n\nfunction resolveCoordinates(v: VerisOpts): ResolvedCoordinates {\n const apiKey = v.apiKey ?? process.env.VERIS_API_KEY\n if (!apiKey) {\n throw new MissingCredentialsError(\n 'no Veris API key: set VERIS_API_KEY in your environment, or pass veris.apiKey. ' +\n 'Get one at https://studio.veris.ai',\n { phase: 'credentials' })\n }\n return {\n apiKey,\n environmentId: v.environmentId ?? process.env.VERIS_ENVIRONMENT_ID,\n apiBase: (v.apiBase ?? process.env.VERIS_API_BASE ?? 'https://svc.api.veris.ai').replace(/\\/$/, ''),\n }\n}\n\nfunction stripVeris(params: CreateParams | undefined): Omit<CreateParams, 'veris'> {\n const { veris: _veris, ...rest } = params ?? {}\n return rest\n}\n\n/** Strip any Veris-reserved keys a caller tried to set in labels. */\nfunction reserveLabels(labels: Record<string, string> | undefined): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(labels ?? {})) {\n if (!VERIS_LABEL_KEYS.includes(k)) out[k] = val\n }\n return out\n}\n\nexport { CA_CERT_PATH }\n","/**\n * Every failure phase a Veris error can name. Bring-up spans four systems\n * (control plane, Daytona API, the sandbox, the Veris gateway), so errors\n * carry a structured phase rather than a wall of logs.\n */\nexport type VerisErrorPhase =\n | 'credentials'\n | 'twin-provision'\n | 'gateway-preflight'\n | 'credential-mint'\n | 'sandbox-create'\n | 'ca-install'\n | 'canary'\n | 'receipt'\n | 'twin-state'\n | 'attach'\n\n/**\n * Base class for every error this package throws. Deliberately NOT a subclass\n * of any Daytona error: `e instanceof VerisError` cleanly separates Veris\n * failures from Daytona failures in one catch.\n */\n/**\n * Fold the wrapped error's own message into ours.\n *\n * `cause` is preserved either way, but almost nothing that shows an error to a\n * human walks the cause chain -- OpenCode prints `err.message` and stops. So\n * \"Daytona sandbox create failed\" was all anyone saw for what was really\n * \"Invalid credentials\": a message that says a thing went wrong and refuses to\n * say why, which is the most expensive kind of error to be handed.\n */\nfunction withCause(message: string, cause: unknown): string {\n const detail =\n cause instanceof Error ? cause.message : typeof cause === 'string' ? cause : ''\n // Already said, or nothing to add.\n if (!detail || message.includes(detail)) return message\n const trimmed = detail.length > 200 ? `${detail.slice(0, 200)}…` : detail\n return `${message}: ${trimmed}`\n}\n\nexport class VerisError extends Error {\n readonly phase?: VerisErrorPhase\n /** The Veris twin's sandbox id, when one exists yet. */\n readonly verisSandboxId?: string\n /** Verbatim control-plane response body, when the failure came from an API call. */\n readonly responseBody?: unknown\n\n constructor(\n message: string,\n opts: { phase?: VerisErrorPhase; verisSandboxId?: string; responseBody?: unknown; cause?: unknown } = {},\n ) {\n super(withCause(message, opts.cause), opts.cause !== undefined ? { cause: opts.cause } : undefined)\n this.name = new.target.name\n this.phase = opts.phase\n this.verisSandboxId = opts.verisSandboxId\n this.responseBody = opts.responseBody\n }\n}\n\n/** A required credential/coordinate is missing. Thrown before any network call, naming the exact variable. */\nexport class MissingCredentialsError extends VerisError {}\n\n/** The Veris gateway infrastructure is down (control-plane health said so). */\nexport class VerisGatewayUnreachableError extends VerisError {}\n\n/** The control plane does not offer gateway mode (endpoint absent, or this SDK version is below min_sdk). */\nexport class VerisGatewayNotOfferedError extends VerisError {\n /** Server-announced minimum SDK version, when the refusal carried one. */\n readonly minSdk?: string\n constructor(message: string, opts: ConstructorParameters<typeof VerisError>[1] & { minSdk?: string } = {}) {\n super(message, opts)\n this.minSdk = opts.minSdk\n }\n}\n\n/** The canary probe failed: egress is not (or no longer) reaching the twin. */\nexport class ReceiptIntegrityError extends VerisError {}\n\n/** assertTouched(): the named service saw zero intercepted requests — green without the receipt. */\nexport class VerisUntouchedError extends VerisError {\n readonly service: string\n constructor(message: string, service: string, opts: ConstructorParameters<typeof VerisError>[1] = {}) {\n super(message, opts)\n this.service = service\n }\n}\n\n/** The Daytona sandbox is alive but its Veris twin is gone (TTL expiry, delete, reset). */\nexport class TwinExpiredError extends VerisError {}\n\n/** The sandbox image cannot host the Veris layer — in practice, no\n * ca-certificates, so the gateway CA cannot be trusted. */\nexport class SnapshotUnsupportedError extends VerisError {}\n\n/** An inherited Daytona operation that would break the one-sandbox-one-twin invariant (e.g. fork). */\nexport class UnsupportedOperationError extends VerisError {}\n","// Typed client for the Veris control plane (svc.api.veris.ai). Only the routes\n// the SDK needs; shapes mirror the platform's public models.\nimport { VerisError, VerisGatewayNotOfferedError, VerisGatewayUnreachableError, TwinExpiredError } from './errors'\n\nexport interface RouteEntry {\n /** A real vendor hostname the service answers for. */\n host: string\n /** Path prefixes narrowing the claim when several services share the host. */\n paths?: string[] | null\n}\n\nexport interface ServiceInfo {\n name: string\n status: string\n /** What the code under test points at: gateway URL for http services, a DSN for e.g. postgres. */\n url: string\n /** Where /veris/* lives — always an http URL. */\n control_url: string\n env_hint?: string | null\n routes?: RouteEntry[] | null\n}\n\nexport interface TwinSandbox {\n id: string\n environment_id: string\n status: 'provisioning' | 'ready' | 'failed' | 'degraded' | 'terminating' | string\n created_at?: string | null\n expires_at?: string | null\n services: ServiceInfo[]\n failure_reason?: string | null\n metadata?: Record<string, string>\n}\n\n/** Response of POST /v1/sandboxes/{sid}/egress-credential (gateway mode). */\nexport interface EgressCredential {\n /** SOCKS5 endpoint. What @veris-ai/e2b uses; Daytona cannot (it accepts only\n * http/https outbound proxies). */\n socks_address: string\n /** HTTP CONNECT endpoint, host:port. Absent on a control plane that predates\n * the CONNECT listener — which is a hard error here, since Daytona has no\n * other way to reach the gateway. */\n connect_address?: string\n /** The CONNECT endpoint as a complete proxy URL, credentials included.\n * Preferred over building one from connect_address: the gateway owns its own\n * auth format, and guessing it is how you end up sending the wrong password. */\n http_proxy_url?: string\n username: string\n password: string\n ca_pem: string\n canary_host: string\n min_sdk?: string\n expires_at?: string\n /** Server-served CA trust env map; the SDK's vendored list is the fallback. */\n trust_env?: Record<string, string>\n}\n\n/** Mutable fields of a running twin. An OMITTED key is left alone; an explicit\n * null is a value (client_base_url: null unregisters). */\nexport interface SandboxPatch {\n ttl_minutes?: number\n client_base_url?: string | null\n}\n\nexport interface ControlPlaneOpts {\n apiKey: string\n apiBase: string\n /** Sent as X-Veris-SDK on every request, so the server can version-gate. */\n sdkVersion: string\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\n\nexport class ControlPlane {\n readonly apiBase: string\n private readonly headers: Record<string, string>\n\n constructor(opts: ControlPlaneOpts) {\n this.apiBase = opts.apiBase.replace(/\\/$/, '')\n this.headers = {\n 'X-API-Key': opts.apiKey,\n 'X-Veris-SDK': opts.sdkVersion,\n 'Content-Type': 'application/json',\n }\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<Response> {\n let res: Response\n try {\n res = await fetch(`${this.apiBase}${path}`, {\n method,\n headers: this.headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (cause) {\n throw new VerisError(`Veris control plane unreachable (${method} ${path})`, { cause })\n }\n return res\n }\n\n private async json<T>(res: Response, context: string, phase?: import('./errors').VerisErrorPhase): Promise<T> {\n const text = await res.text()\n let parsed: unknown\n try { parsed = text ? JSON.parse(text) : undefined } catch { parsed = text }\n if (!res.ok) {\n throw new VerisError(`${context}: ${res.status}`, { phase, responseBody: parsed })\n }\n // A success with no body would surface downstream as an opaque\n // \"cannot read properties of undefined\" — turn it into a legible error here.\n if (parsed === undefined) {\n throw new VerisError(`${context}: empty response body`, { phase, responseBody: text })\n }\n return parsed as T\n }\n\n async createTwin(environmentId: string, opts: { ttlMinutes?: number; metadata?: Record<string, string> } = {}): Promise<TwinSandbox> {\n const res = await this.request('POST', `/v1/environments/${environmentId}/sandboxes`, {\n ttl_minutes: opts.ttlMinutes,\n metadata: opts.metadata,\n })\n // A 404 here is almost never a missing endpoint: environments are scoped to\n // one control plane, so the usual cause is an id from a DIFFERENT one --\n // a prod VERIS_ENVIRONMENT_ID against a dev VERIS_API_BASE, or the reverse.\n // The bare \"404\" sends people to check their key, which is fine, and their\n // network, which is fine, before they think to check the pairing.\n if (res.status === 404) {\n throw new VerisError(\n `environment '${environmentId}' does not exist on ${this.apiBase}. Environments belong ` +\n 'to one control plane: check that VERIS_ENVIRONMENT_ID and VERIS_API_BASE name the same ' +\n 'one (an id from the other environment gives exactly this 404).',\n { phase: 'twin-provision', responseBody: await res.text() })\n }\n return this.json<TwinSandbox>(res, `create sandbox in environment ${environmentId}`, 'twin-provision')\n }\n\n async getTwin(sandboxId: string): Promise<TwinSandbox | null> {\n const res = await this.request('GET', `/v1/sandboxes/${sandboxId}`)\n if (res.status === 404) return null\n return this.json<TwinSandbox>(res, `get sandbox ${sandboxId}`)\n }\n\n /** Poll until the twin reports ready. \"failed\" is terminal per the API docs. */\n async waitReady(sandboxId: string, timeoutMs: number): Promise<TwinSandbox> {\n const deadline = Date.now() + timeoutMs\n for (;;) {\n const twin = await this.getTwin(sandboxId)\n if (!twin) throw new TwinExpiredError(`Veris sandbox ${sandboxId} disappeared while provisioning`, { verisSandboxId: sandboxId })\n if (twin.status === 'ready') return twin\n if (twin.status === 'failed') {\n throw new VerisError(\n `Veris sandbox ${sandboxId} failed to provision: ${twin.failure_reason ?? 'no failure_reason'}`,\n { phase: 'twin-provision', verisSandboxId: sandboxId })\n }\n if (Date.now() > deadline) {\n throw new VerisError(\n `Veris sandbox ${sandboxId} not ready after ${timeoutMs}ms (status: ${twin.status})`,\n { phase: 'twin-provision', verisSandboxId: sandboxId })\n }\n await sleep(1500)\n }\n }\n\n async services(sandboxId: string): Promise<ServiceInfo[]> {\n const res = await this.request('GET', `/v1/sandboxes/${sandboxId}/services`)\n if (res.status === 404) {\n throw new TwinExpiredError(`Veris sandbox ${sandboxId} not found — expired or deleted`, { verisSandboxId: sandboxId })\n }\n return this.json<ServiceInfo[]>(res, `services of sandbox ${sandboxId}`, 'receipt')\n }\n\n async deleteTwin(environmentId: string, sandboxId: string): Promise<boolean> {\n const res = await this.request('DELETE', `/v1/environments/${environmentId}/sandboxes/${sandboxId}`)\n if (res.status === 404) return false\n if (!res.ok) await this.json(res, `delete sandbox ${sandboxId}`)\n return true\n }\n\n /**\n * Mint (or re-mint) the gateway egress credential for a twin. Returns null\n * when the control plane does not offer gateway mode at all (404 — route\n * absent), so `mode: 'auto'` can fall back; throws VerisGatewayNotOfferedError\n * on an explicit version refusal (409 sdk_too_old).\n */\n async mintEgressCredential(environmentId: string, sandboxId: string): Promise<EgressCredential | null> {\n const res = await this.request('POST', `/v1/environments/${environmentId}/sandboxes/${sandboxId}/egress-credential`)\n if (res.status === 404) return null\n if (res.status === 409) {\n const body = await res.json().catch(() => ({})) as { min_sdk?: string }\n throw new VerisGatewayNotOfferedError(\n `this SDK version is below the control plane's minimum for gateway mode${body.min_sdk ? ` (min_sdk ${body.min_sdk})` : ''} — upgrade @veris-ai/daytona`,\n { phase: 'credential-mint', verisSandboxId: sandboxId, minSdk: body.min_sdk, responseBody: body })\n }\n return this.json<EgressCredential>(res, `mint egress credential for ${sandboxId}`, 'credential-mint')\n }\n\n /** PATCH the twin resource. Omitted fields are untouched by the server. */\n async updateSandbox(environmentId: string, sandboxId: string, patch: SandboxPatch): Promise<void> {\n const res = await this.request('PATCH', `/v1/environments/${environmentId}/sandboxes/${sandboxId}`, patch)\n if (res.status === 404) {\n throw new TwinExpiredError(`Veris sandbox ${sandboxId} not found`, { verisSandboxId: sandboxId })\n }\n if (!res.ok) await this.json(res, `update sandbox ${sandboxId}`)\n }\n\n /** Extend a twin's TTL so it stays in lockstep with an extended Daytona sandbox. */\n async extendTtl(environmentId: string, sandboxId: string, ttlMinutes: number): Promise<void> {\n const res = await this.request('PATCH', `/v1/environments/${environmentId}/sandboxes/${sandboxId}`, { ttl_minutes: ttlMinutes })\n if (res.status === 404) {\n throw new TwinExpiredError(`Veris sandbox ${sandboxId} not found — cannot extend TTL`, { verisSandboxId: sandboxId })\n }\n // 405 = a control plane that does not accept this field yet: tolerated, the\n // original TTL keeps its backstop role and kill() still cleans up.\n if (!res.ok && res.status !== 405) await this.json(res, `extend TTL of ${sandboxId}`)\n }\n\n /** Create-time preflight: is the gateway infrastructure up, per the control plane? */\n async gatewayHealth(): Promise<void> {\n const res = await this.request('GET', '/v1/gateway/health')\n if (res.status === 404) return // control plane predates gateway mode; the credential probe decides\n if (!res.ok) {\n throw new VerisGatewayUnreachableError(\n `Veris gateway reported unhealthy (${res.status})`, { phase: 'gateway-preflight' })\n }\n }\n}\n","// The receipt: what the twin actually received, parsed from each service's\n// /veris/requests log — plus the integrity probe that keeps it honest.\nimport type { Sandbox } from '@daytona/sdk'\nimport { ReceiptIntegrityError, VerisError } from './errors'\nimport type { ServiceInfo } from './control-plane'\n\n/** One intercepted request, from the twin's trace log. */\nexport interface ReceiptRequest {\n method: string\n path: string\n /** null = no response sent (fault hang). */\n status: number | null\n}\n\nexport interface ReceiptEntry {\n /** Count of intercepted requests (real JSON parse, not a regex). */\n requests: number\n /** The twin service's /veris/* control plane. */\n controlUrl: string\n /** Typed request list, newest first. */\n entries: ReceiptRequest[]\n /** Verbatim /veris/requests body. */\n raw: unknown\n}\n\nexport type ReceiptLeak = 'udp-quic-possible' | 'ech-possible'\n\nexport interface Receipt {\n /** Keyed by service name. Partial: indexing an absent service is a type\n * error to handle, not a runtime TypeError to discover. */\n services: Partial<Record<string, ReceiptEntry>>\n /** How the traffic was moved. One tier now: the Veris gateway. */\n mode: 'gateway'\n /** 'verified' iff the canary probe confirmed egress is still tunnelled\n * through the gateway and demuxed to THIS twin. */\n integrity: 'verified'\n /** Known blind spots of THIS receipt. */\n leaks: ReceiptLeak[]\n}\n\ninterface RawRequestsBody { requests?: unknown[] }\n\nexport function parseRequestsBody(body: unknown): { count: number; entries: ReceiptRequest[] } {\n const rows = Array.isArray((body as RawRequestsBody)?.requests)\n ? (body as RawRequestsBody).requests!\n : []\n const entries: ReceiptRequest[] = rows.map((r) => {\n const row = r as Record<string, unknown>\n return {\n method: String(row.method ?? ''),\n path: String(row.path ?? ''),\n status: typeof row.status === 'number' ? row.status : null,\n }\n })\n return { count: entries.length, entries }\n}\n\nexport async function fetchReceiptEntry(svc: ServiceInfo): Promise<ReceiptEntry> {\n const url = `${svc.control_url}/veris/requests`\n const res = await fetch(url)\n const text = await res.text()\n if (!res.ok) {\n throw new VerisError(`could not read receipt for service '${svc.name}' (${res.status})`, {\n phase: 'receipt', responseBody: text.slice(0, 500) })\n }\n let raw: unknown\n try { raw = JSON.parse(text) } catch {\n throw new VerisError(`service '${svc.name}' returned a non-JSON receipt body`, {\n phase: 'receipt', responseBody: text.slice(0, 500) })\n }\n const { count, entries } = parseRequestsBody(raw)\n return { requests: count, controlUrl: svc.control_url, entries, raw }\n}\n","// Builds the Daytona network params.\n//\n// domainAllowList deny-all-except, enforced at the runner. Verified\n// transparent: a client that strips every proxy variable\n// still cannot reach a host directly, so this is a network\n// boundary and not an env-var convention.\n// outboundProxyUrl where Daytona forwards allowed traffic. Chained, not\n// advisory — an unreachable one makes allowed traffic 502.\n//\n// Together those two are the whole mechanism: the allowlist decides what may\n// leave, and the outbound proxy (the Veris gateway) decides what answers.\nimport type { ServiceInfo } from './control-plane'\n\nexport type EgressMode = 'strict' | 'open'\n\n/** A service whose `url` is an HTTP endpoint (vs a wire-protocol DSN). */\nexport const isHttpUrl = (u: string) => /^https?:/.test(u)\n\n/**\n * Vendor hostnames the twin answers for. These MUST be on the allowlist.\n *\n * That reads backwards until you follow the path: the sandbox's traffic goes to\n * Daytona's proxy, which drops anything not allowlisted and forwards the rest\n * to `outboundProxyUrl` — the Veris gateway. So a vendor host that is absent\n * never reaches the gateway and never reaches the twin; it is simply blocked.\n *\n * Allowing it is not a leak, because the allowlist is not what stands between\n * the sandbox and the real vendor — the gateway is. Verified: with every proxy\n * variable stripped, an allowlisted host is still intercepted rather than\n * dialled directly.\n */\nexport function vendorHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n for (const r of svc.routes ?? []) hosts.add(r.host)\n }\n return [...hosts].sort()\n}\n\n/** Hosts the twin itself lives at — the proxy must reach these or nothing works. */\nexport function twinHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n for (const u of [svc.control_url, svc.url]) {\n if (!u || !isHttpUrl(u)) continue\n try { hosts.add(new URL(u).hostname) } catch { /* skip unparseable */ }\n }\n }\n return [...hosts].sort()\n}\n\n/**\n * Endpoints of non-HTTP data planes (e.g. the pg-gateway a postgres DSN\n * targets). Handed over rather than intercepted, so they need plain\n * reachability on the allowlist or the data plane silently breaks.\n *\n * DSNs come in every shape — with/without credentials, with/without a trailing\n * path, redis/kafka/mongo, IPv6 in brackets, comma-separated multi-host — so we\n * parse with the URL parser (which handles all of them) and only fall back to a\n * regex for exotic non-URL forms. Every host in a multi-host DSN is allowed.\n */\nexport function dataPlaneHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n if (!svc.url || isHttpUrl(svc.url)) continue\n for (const h of hostsFromDsn(svc.url)) hosts.add(h)\n }\n return [...hosts].sort()\n}\n\nfunction hostsFromDsn(dsn: string): string[] {\n const out: string[] = []\n try {\n const u = new URL(dsn)\n // URL.hostname keeps IPv6 brackets; strip them for the allowlist entry.\n if (u.hostname) out.push(u.hostname.replace(/^\\[|\\]$/g, ''))\n } catch {\n // Not URL-parseable — fall through to the regex.\n }\n // Multi-host DSNs (mongodb://a:27017,b:27017/db) — the URL parser only sees\n // the first authority, so sweep the raw authority for the rest.\n const authority = dsn.replace(/^[^:]+:\\/\\//, '').split(/[/?]/)[0] ?? ''\n const afterAt = authority.includes('@') ? authority.slice(authority.lastIndexOf('@') + 1) : authority\n for (const part of afterAt.split(',')) {\n const m = part.match(/^\\[?([A-Za-z0-9_.:-]+?)\\]?(?::\\d+)?$/)\n if (m?.[1] && !/^\\d+$/.test(m[1])) out.push(m[1].replace(/^\\[|\\]$/g, ''))\n }\n return out\n}\n\n/**\n * `{ [env_hint]: dsn }` for the twin's non-HTTP data planes — the env the code\n * under test reads (e.g. DATABASE_URL). Sibling of dataPlaneHosts: same field,\n * one derivation, so a new service type changes one place.\n */\nexport function dataPlaneEnv(services: ServiceInfo[]): Record<string, string> {\n const envs: Record<string, string> = {}\n for (const svc of services) {\n if (!svc.env_hint || !svc.url || isHttpUrl(svc.url)) continue\n // The env NAME comes from the control plane and is injected into every\n // command, so it is shape-checked before use: a response naming PATH,\n // NODE_OPTIONS or BASH_ENV would otherwise steer the sandbox's processes.\n if (!isSafeEnvName(svc.env_hint)) continue\n envs[svc.env_hint] = svc.url\n }\n return envs\n}\n\n/** Env names a data-plane hint may claim: conventional SCREAMING_SNAKE, and\n * never one of the process-controlling variables. */\nconst PROCESS_CONTROLLING = new Set([\n 'PATH', 'LD_PRELOAD', 'LD_LIBRARY_PATH', 'NODE_OPTIONS', 'BASH_ENV', 'ENV',\n 'PYTHONPATH', 'PYTHONSTARTUP', 'SHELL', 'IFS', 'HOME', 'PROMPT_COMMAND',\n])\nexport function isSafeEnvName(name: string): boolean {\n return /^[A-Z][A-Z0-9_]{0,63}$/.test(name) && !PROCESS_CONTROLLING.has(name)\n}\n\n/**\n * Package registries and toolchain hosts, allowed by default.\n *\n * A coding sandbox that cannot `npm install` is not a coding sandbox, and\n * registries are not vendors under test, so they must stay reachable. Naming\n * them here keeps the list auditable rather than punching a wildcard.\n *\n * Override wholesale with `veris.allowRegistries: false` plus your own\n * `veris.allowOut`, for a sandbox that should reach nothing but its twin.\n */\nexport const DEFAULT_REGISTRY_HOSTS: readonly string[] = [\n // JS\n 'registry.npmjs.org', 'registry.yarnpkg.com',\n // Python\n 'pypi.org', 'files.pythonhosted.org',\n // Go\n 'proxy.golang.org', 'sum.golang.org',\n // Rust\n 'crates.io', 'static.crates.io', 'index.crates.io',\n // Debian/Ubuntu\n 'deb.debian.org', 'security.debian.org', 'archive.ubuntu.com', 'security.ubuntu.com',\n // Source + container hosts the above routinely redirect to\n 'github.com', 'codeload.github.com', 'objects.githubusercontent.com',\n 'raw.githubusercontent.com', 'ghcr.io',\n]\n\nexport interface BuildNetworkArgs {\n services: ServiceInfo[]\n mode: EgressMode\n /** The Veris gateway's host, and the canary hostname it answers on. Without\n * these the sandbox cannot reach the gateway at all. */\n gatewayHosts: string[]\n /** Extra hostnames the caller wants reachable. */\n allowOut?: string[]\n /** Include DEFAULT_REGISTRY_HOSTS. Default true. */\n allowRegistries?: boolean\n}\n\n/** The Daytona create params that decide what the sandbox may reach. */\nexport interface NetworkParams {\n networkBlockAll?: boolean\n domainAllowList?: string\n}\n\n/**\n * Strict (the default) is deny-all-except: the vendor hosts the twin answers\n * for, the gateway itself, the twin's data planes, and package registries.\n *\n * Open sets no allowlist at all. It exists for debugging and is never the\n * default: with no allowlist there is nothing forcing traffic at the gateway,\n * and the receipt cannot tell you what slipped past.\n */\nexport function buildNetwork(args: BuildNetworkArgs): NetworkParams {\n const { services, mode, gatewayHosts, allowOut = [], allowRegistries = true } = args\n if (mode === 'open') return {}\n\n const domains = [\n ...vendorHosts(services),\n ...gatewayHosts,\n ...dataPlaneHosts(services),\n ...(allowRegistries ? DEFAULT_REGISTRY_HOSTS : []),\n ...allowOut,\n ].filter((h): h is string => Boolean(h))\n\n return {\n // NOT networkBlockAll: that blocks everything including the gateway, and the\n // allowlist is what Daytona documents as \"unbypassable network-layer\n // enforcement\". Blocking all and then allowing is not a shape the API\n // offers; a non-empty domainAllowList IS the deny-by-default.\n domainAllowList: [...new Set(domains)].sort().join(','),\n }\n}\n","// CA trust: which env vars point which client stacks at the system bundle,\n// and the single tested install command.\n\n/** Where the Veris CA certificate lands in the Daytona sandbox. This is the\n * standard Debian drop-in directory, so any later `update-ca-certificates`\n * rebuilds the bundle with our cert still included. */\nexport const CA_CERT_PATH = '/usr/local/share/ca-certificates/veris-ca.crt'\n\n/** The distribution's own bundle, when it has one. */\nexport const SYSTEM_BUNDLE = '/etc/ssl/certs/ca-certificates.crt'\n\n/** Our CA alone, world-readable, written before anything needs it. */\nexport const VERIS_CA_FILE = '/tmp/veris-ca.crt'\n\n/**\n * The public roots plus ours, concatenated by us.\n *\n * Every path-valued trust var points here rather than at SYSTEM_BUNDLE, because\n * `update-ca-certificates` is not always present — Daytona's default image does\n * not ship it — and a var pointing at a bundle that was never rebuilt trusts\n * everything except the one CA that matters. We write this file ourselves, so\n * it is correct whether or not the distribution has the tooling.\n */\nexport const VERIS_BUNDLE = '/tmp/veris-ca-bundle.crt'\n\n/**\n * The trust variables injected into every sandbox at create time.\n *\n * This is the load-bearing half of CA trust: the gateway forges a leaf for each\n * vendor hostname, and a client that does not trust the Veris CA rejects it, so\n * without these (or the store install below) every HTTPS vendor call fails on\n * certificate validation.\n *\n * Every var is path-valued and points at VERIS_BUNDLE (public roots + ours, so\n * passthrough hosts keep verifying) — NODE_EXTRA_CA_CERTS included. That var is\n * additive, but only to Node's BAKED-IN Mozilla roots, never to the system\n * store — and on Daytona the leaf a client actually validates is signed by\n * Daytona's proxy CA (its proxy terminates TLS; see installCa's comment), which\n * lives in the system store and nowhere in Mozilla's roots. Point Node at the\n * single Veris cert and it can verify neither that leaf nor a directly served\n * gateway one behind it: UNABLE_TO_VERIFY_LEAF_SIGNATURE on every vendor call.\n * The bundle carries the system store (Daytona's CA with it) plus ours, so it\n * is the one file that works in both worlds.\n */\nexport function vendoredTrustEnv(): Record<string, string> {\n return {\n SSL_CERT_FILE: VERIS_BUNDLE,\n REQUESTS_CA_BUNDLE: VERIS_BUNDLE,\n CURL_CA_BUNDLE: VERIS_BUNDLE,\n GIT_SSL_CAINFO: VERIS_BUNDLE,\n AWS_CA_BUNDLE: VERIS_BUNDLE,\n CARGO_HTTP_CAINFO: VERIS_BUNDLE,\n DENO_CERT: VERIS_BUNDLE,\n PIP_CERT: VERIS_BUNDLE,\n npm_config_cafile: VERIS_BUNDLE,\n GRPC_DEFAULT_SSL_ROOTS_FILE_PATH: VERIS_BUNDLE,\n BUNDLE_SSL_CA_CERT: VERIS_BUNDLE,\n COMPOSER_CAFILE: VERIS_BUNDLE,\n HEX_CACERTS_PATH: VERIS_BUNDLE,\n JULIA_SSL_CA_ROOTS_PATH: VERIS_BUNDLE,\n NIX_SSL_CERT_FILE: VERIS_BUNDLE,\n PERL_LWP_SSL_CA_FILE: VERIS_BUNDLE,\n CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE: VERIS_BUNDLE,\n NODE_EXTRA_CA_CERTS: VERIS_BUNDLE,\n }\n}\n\n/**\n * The store-based install, for stacks that read a trust store rather than an\n * env var — a Java client honours no CA variable at all. Rebuilds the system\n * bundle with the Veris CA (already at CA_CERT_PATH), imports it into the JVM\n * cacerts (`|| true`: no Java → skipped), and adds it to NSS databases when\n * certutil exists.\n *\n * Entirely best-effort: it needs root and tooling the image may not have, which\n * is why VERIS_BUNDLE plus the trust variables — not this — is what actually\n * makes interception work.\n */\nexport const CA_INSTALL_CMD = [\n 'update-ca-certificates',\n `(keytool -importcert -noprompt -cacerts -storepass changeit -alias veris -file ${CA_CERT_PATH} 2>/dev/null || true)`,\n '(command -v certutil >/dev/null 2>&1 && ' +\n 'for db in $(find /home /root -maxdepth 4 -name \"cert9.db\" 2>/dev/null | xargs -r -n1 dirname); do ' +\n `certutil -A -n veris -t \"C,,\" -i ${CA_CERT_PATH} -d \"sql:$db\" 2>/dev/null || true; done || true)`,\n].join(' && ')\n\n/**\n * Sanitize a server-served trust_env map before injecting it into the sandbox.\n * A control-plane response must never become arbitrary env-var injection, so\n * only known trust variables survive, and every value is forced to a\n * path-shaped string (the vars are all CA *file paths*). Unknown keys and\n * non-path values are dropped. Returns the vendored map when nothing valid\n * remains.\n */\nexport function sanitizeTrustEnv(served: Record<string, unknown> | undefined): Record<string, string> {\n const vendored = vendoredTrustEnv()\n // Start from the vendored map so a single bad or absent served value falls\n // back PER KEY to the known-good default, rather than dropping that variable\n // and leaving (e.g.) Python's requests with no CA bundle.\n const out: Record<string, string> = { ...vendored }\n for (const [k, val] of Object.entries(served ?? {})) {\n if (!(k in vendored)) continue // unknown key: never injected\n if (typeof val !== 'string') continue\n // Absolute path; allow the common path characters (incl. + and ~).\n if (!/^\\/[\\w./+~-]+$/.test(val)) continue\n out[k] = val\n }\n return out\n}\n","// Gateway mode: the sandbox's egress is routed through the Veris gateway, which\n// answers vendor hostnames from the twin. Nothing Veris runs inside the sandbox\n// but one CA file.\n//\n// This is the same tier @veris-ai/e2b uses (there via network.egressProxy), and\n// the reason Daytona can host it is that outboundProxyUrl is genuinely chained:\n// Daytona's proxy forwards allowed traffic to it and returns 502 when it cannot.\n//\n// Two things still have to happen inside the sandbox, and both are here:\n// install the gateway's CA so the forged vendor leaves validate, and prove the\n// tunnel is actually live before anyone trusts a receipt.\nimport type { Sandbox } from '@daytona/sdk'\nimport { ReceiptIntegrityError, SnapshotUnsupportedError, VerisError } from './errors'\nimport { CA_CERT_PATH, CA_INSTALL_CMD, SYSTEM_BUNDLE, VERIS_BUNDLE, VERIS_CA_FILE } from './trust'\n\n/** A canary hostname must look like a hostname before it goes in a shell command. */\nconst HOSTNAME_RE = /^[A-Za-z0-9.-]+$/\n/** host:port, the only shape an outbound proxy address may take. */\nconst HOSTPORT_RE = /^[A-Za-z0-9.-]+:\\d{1,5}$/\n\n/** Single-quote a string for POSIX sh. */\nexport function shellQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n\nconst sh = (sandbox: Sandbox, cmd: string, timeoutSec = 60) =>\n sandbox.process.executeCommand(`sh -lc ${shellQuote(cmd)}`, undefined, undefined, timeoutSec)\n\n/**\n * Build the proxy URL Daytona is handed.\n *\n * The username is the tenant demux key — the gateway reads the sandbox id out\n * of it. There is no separate secret: the id IS the capability, exactly as the\n * SOCKS path treats it, so the password is a placeholder the gateway ignores.\n *\n * RFC 3986 §3.2.1 notes that `user:password` in userinfo is deprecated. It is\n * also the only form HTTP proxy clients accept for RFC 7617 Basic credentials,\n * and it is what Daytona forwards, so it is what we emit.\n *\n * `encodeURIComponent` is exactly right for userinfo: everything it leaves raw\n * is unreserved or a sub-delim, and it escapes both separators — `:` to %3A and\n * `@` to %40 — so a username can never break out into the authority.\n *\n * The address is validated rather than interpolated: it arrives from the\n * control plane, and an unchecked value here would land in a URL and then in\n * every client's proxy configuration.\n */\nexport function gatewayProxyUrl(credential: {\n http_proxy_url?: string\n connect_address?: string\n username: string\n}): string {\n // The gateway's own URL wins when it serves one. It knows its auth format —\n // the password is the twin id, not a placeholder — and a locally built URL\n // that guesses wrong authenticates as nobody.\n if (credential.http_proxy_url) return assertProxyUrl(credential.http_proxy_url)\n\n if (!credential.connect_address || !HOSTPORT_RE.test(credential.connect_address)) {\n throw new VerisError(\n `the control plane returned a malformed gateway address: ` +\n `${JSON.stringify(credential.connect_address)} (expected host:port)`,\n { phase: 'credential-mint' })\n }\n return `http://${encodeURIComponent(credential.username)}:x@${credential.connect_address}`\n}\n\n/**\n * A proxy URL from the control plane, before it becomes every client's egress\n * configuration. Untrusted input: it must parse, name a port, and speak a\n * scheme Daytona accepts — it rejects anything but http/https outright.\n */\nfunction assertProxyUrl(raw: string): string {\n let u: URL\n try { u = new URL(raw) } catch {\n throw new VerisError(\n `the control plane returned an unparseable gateway proxy URL: ${JSON.stringify(raw)}`,\n { phase: 'credential-mint' })\n }\n if (u.protocol !== 'http:' && u.protocol !== 'https:') {\n throw new VerisError(\n `the gateway proxy URL uses scheme \"${u.protocol.replace(':', '')}\", and Daytona accepts ` +\n `only http or https outbound proxies`,\n { phase: 'credential-mint' })\n }\n if (!u.hostname || !u.port) {\n throw new VerisError(\n `the gateway proxy URL is missing a host or port: ${JSON.stringify(raw)}`,\n { phase: 'credential-mint' })\n }\n return raw\n}\n\n/**\n * Make the gateway's CA trusted, without requiring anything of the image.\n *\n * Defensive rather than load-bearing on Daytona today, and the distinction is\n * worth recording. Daytona's own proxy terminates TLS with a certificate signed\n * by ITS CA — already trusted in the image — and re-originates to the gateway,\n * so the client never validates our forged leaf. Verified: a vendor call\n * succeeds with --cacert naming only Daytona's CA.\n *\n * We install ours regardless, because the day Daytona tunnels CONNECT\n * end-to-end (the ordinary behaviour for an HTTP proxy) the gateway's leaf\n * reaches the client directly and nothing works without it. One upload and one\n * shell command against a total outage is a trade worth making.\n *\n * The obvious approach — drop the cert in /usr/local/share/ca-certificates and\n * run update-ca-certificates — needs root AND that tool, and Daytona's default\n * image has neither. So the artefact is a bundle we build ourselves at a\n * world-writable path: the distribution's roots (when it has any) plus ours.\n *\n * Daytona overrides the best-known trust variables with its own CA, correctly\n * for its proxy. The dozen it does not set still point at this bundle, which\n * carries both CAs and every public root — so those tools verify rather than\n * break.\n *\n * The system-store install still runs when it can, for anything that reads the\n * store directly rather than honouring the variables. It is best-effort.\n */\nexport async function installCa(sandbox: Sandbox, caPem: string): Promise<void> {\n await sandbox.fs.uploadFile(Buffer.from(caPem, 'utf8'), VERIS_CA_FILE)\n\n const script = [\n `chmod 0644 ${VERIS_CA_FILE}`,\n // Public roots first so they keep working; ours appended. `cat` of a\n // missing file is tolerated — an image with no roots at all still gets a\n // bundle containing the one CA that matters here.\n `{ cat ${SYSTEM_BUNDLE} 2>/dev/null; cat ${VERIS_CA_FILE}; } > ${VERIS_BUNDLE}`,\n `chmod 0644 ${VERIS_BUNDLE}`,\n // Best-effort, for the stacks that read a store rather than a variable:\n // the system bundle, the JVM truststore, and NSS databases. All of it needs\n // root and tooling that may not be there, so none of it is load-bearing —\n // but a Java client honours no CA env var at all, so where we CAN do it,\n // we should.\n `SUDO=; [ \"$(id -u)\" = 0 ] || SUDO=\"sudo -n\"`,\n `($SUDO install -m 0644 -D ${VERIS_CA_FILE} ${CA_CERT_PATH} 2>/dev/null && ` +\n `$SUDO sh -c ${shellQuote(CA_INSTALL_CMD)} 2>/dev/null) || true`,\n // The bundle is the load-bearing one: fail loudly if it is not there.\n `[ -s ${VERIS_BUNDLE} ] && echo __VERIS_CA_OK__`,\n ].join('; ')\n\n const r = await sh(sandbox, script, 120).catch((e: unknown) => ({ exitCode: 1, result: String(e) }))\n if (!(r.result ?? '').includes('__VERIS_CA_OK__')) {\n throw new SnapshotUnsupportedError(\n `could not assemble a CA bundle at ${VERIS_BUNDLE}, so the gateway's certificates ` +\n `cannot be trusted (${(r.result ?? '').trim().slice(0, 200)})`,\n { phase: 'ca-install' })\n }\n}\n\n/**\n * The canary probe: one HTTPS request from inside the sandbox to a reserved\n * hostname only the gateway answers, with the twin id in the body.\n *\n * Green proves three things in a single request — egress really is tunnelled\n * through the gateway, the credential demuxed to the right twin, and the CA\n * install worked. Dialled outside the tunnel the host has no listener, so this\n * cannot pass by accident, which is what makes a receipt worth reading.\n */\nexport async function probeCanary(\n sandbox: Sandbox,\n canaryHost: string,\n expectedTwinId: string,\n): Promise<void> {\n if (!HOSTNAME_RE.test(canaryHost)) {\n throw new ReceiptIntegrityError(\n `refusing to probe a malformed canary host from the control plane: ${JSON.stringify(canaryHost)}`,\n { phase: 'canary', verisSandboxId: expectedTwinId })\n }\n // A non-zero curl exit must surface as a ReceiptIntegrityError, not as the\n // raw command failure, so print a marker and inspect the output ourselves.\n const r = await sh(\n sandbox,\n `curl -sS --cacert ${VERIS_BUNDLE} --max-time 20 https://${canaryHost}/ || echo __VERIS_CANARY_FAIL__`,\n 45,\n ).catch((e: unknown) => ({ exitCode: 1, result: String(e) }))\n\n let body: { veris_sandbox_id?: string } = {}\n try { body = JSON.parse(r.result ?? '') } catch { /* handled below */ }\n if (body.veris_sandbox_id !== expectedTwinId) {\n throw new ReceiptIntegrityError(\n `canary probe failed: egress from this Daytona sandbox is not tunnelled through the ` +\n `Veris gateway (expected twin ${expectedTwinId}, canary answered: ` +\n `${(r.result || 'nothing').trim().slice(0, 200)})`,\n { phase: 'canary', verisSandboxId: expectedTwinId })\n }\n}\n","// Reads of a twin service's own control plane that are not the receipt.\n//\n// Same shape and same reasoning as receipt.ts: these run HOST-SIDE, never from\n// inside the sandbox. `control_url` is deliberately absent from the sandbox's\n// domainAllowList, because a sandbox that can reach /veris/* can also reach\n// /veris/reset — and an agent that can clear request history can make its own\n// receipt say anything.\nimport { VerisError } from './errors'\nimport type { ServiceInfo } from './control-plane'\nimport { isHttpUrl } from './network'\n\n/** Guard shared by every control-plane read: a DSN-only service (postgres and\n * friends) has no /veris/* surface, and saying so beats a TypeError. */\nexport function assertHttpControlPlane(svc: ServiceInfo): void {\n if (!svc.control_url || !isHttpUrl(svc.control_url)) {\n throw new VerisError(\n `service '${svc.name}' has no HTTP control plane, so there is nothing to read`,\n { phase: 'twin-state' },\n )\n }\n}\n\n/**\n * The service's manual: what this twin models, which endpoints it answers, and\n * the conventions its data follows. Prose, not JSON — it is written to be read\n * before designing anything against the service.\n */\nexport async function fetchManual(svc: ServiceInfo): Promise<string> {\n assertHttpControlPlane(svc)\n const res = await fetch(`${svc.control_url}/veris/manual`)\n const text = await res.text()\n if (!res.ok) {\n throw new VerisError(`could not read the manual for service '${svc.name}' (${res.status})`, {\n phase: 'twin-state', responseBody: text.slice(0, 500) })\n }\n return text\n}\n","// The namespaced Veris surface: everything this package adds hangs off\n// `sbx.veris`, matching Daytona's own `sbx.fs` / `sbx.process` idiom so a\n// future @daytona/sdk minor can never collide with a generic method name.\nimport type { Sandbox } from '@daytona/sdk'\nimport type { ControlPlane, ServiceInfo } from './control-plane'\nimport { fetchReceiptEntry } from './receipt'\nimport type { Receipt, ReceiptEntry, ReceiptLeak } from './receipt'\nimport { VerisUntouchedError, VerisError } from './errors'\nimport { dataPlaneEnv, isHttpUrl } from './network'\nimport type { EgressMode } from './network'\nimport { probeCanary } from './gateway'\nimport { fetchManual } from './state'\nimport { vendoredTrustEnv } from './trust'\n\n/** Everything needed to answer Veris queries about a live sandbox. */\nexport interface VerisContext {\n sandbox: Sandbox\n controlPlane: ControlPlane\n environmentId: string\n twinId: string\n egress: EgressMode\n /** The reserved host the canary probe dials to prove the tunnel is live. */\n canaryHost: string\n /** Whether this twin is owned (delete removes it) or attached (caller owns it). */\n ownsTwin: boolean\n}\n\n/** Narrow assertTouched to specific requests. All fields AND together. */\nexport interface TouchMatcher {\n method?: string\n /** Substring match against the request path. */\n path?: string\n /** Minimum matching requests required (default 1). */\n minRequests?: number\n}\n\nexport interface VerisApi {\n /** The Veris twin's sandbox id — NOT the Daytona sandbox id. */\n readonly sandboxId: string\n readonly mode: 'gateway'\n services(): Promise<ServiceInfo[]>\n /** The service's own manual: what it models and how its data is shaped. */\n manual(service: string): Promise<string>\n receipt(): Promise<Receipt>\n receipt(service: string): Promise<ReceiptEntry>\n assertTouched(service: string, match?: TouchMatcher): Promise<void>\n getDataPlaneEnv(): Promise<Record<string, string>>\n getTrustEnv(): Record<string, string>\n deliverTo(port: number, opts?: DeliverToOpts): Promise<string>\n deliverTo(url: string | null, opts?: DeliverToOpts): Promise<string | null>\n}\n\nexport interface DeliverToOpts {\n /** Verify the destination is actually reachable from the twin before\n * returning, via each service's /veris/client/probe. Default true. */\n probe?: boolean\n}\n\nexport class VerisApiImpl implements VerisApi {\n constructor(private readonly ctx: VerisContext) {}\n\n get sandboxId(): string { return this.ctx.twinId }\n get mode(): 'gateway' { return 'gateway' }\n\n services(): Promise<ServiceInfo[]> {\n return this.ctx.controlPlane.services(this.ctx.twinId)\n }\n\n /** Resolve a service by name. A typo and a service that exists but saw\n * nothing are different failures, so this throws rather than returning\n * undefined and letting the caller report an empty result. */\n private async resolveService(service: string): Promise<ServiceInfo> {\n const services = await this.services()\n const svc = services.find((s) => s.name === service)\n if (!svc) {\n throw new VerisError(\n `unknown service '${service}' — the twin has no service by that name (available: ${services.map((s) => s.name).join(', ') || 'none'})`,\n { verisSandboxId: this.ctx.twinId })\n }\n return svc\n }\n\n async manual(service: string): Promise<string> {\n return fetchManual(await this.resolveService(service))\n }\n\n receipt(): Promise<Receipt>\n receipt(service: string): Promise<ReceiptEntry>\n async receipt(service?: string): Promise<Receipt | ReceiptEntry> {\n // Prove egress is STILL tunnelled before trusting any count. A receipt read\n // from a sandbox whose egress was detached would be a confident lie, which\n // is worse than no receipt at all.\n await probeCanary(this.ctx.sandbox, this.ctx.canaryHost, this.ctx.twinId)\n\n if (service !== undefined) return fetchReceiptEntry(await this.resolveService(service))\n\n const services = await this.services()\n const entries = await Promise.all(\n services.filter((s) => isHttpUrl(s.control_url)).map(async (svc) => [svc.name, await fetchReceiptEntry(svc)] as const))\n return {\n services: Object.fromEntries(entries),\n mode: 'gateway',\n integrity: 'verified',\n leaks: this.leaks(),\n }\n }\n\n /**\n * What this receipt cannot see. The gateway relays TCP, so QUIC/HTTP3 and ECH\n * ride around it — named rather than rounded off.\n */\n private leaks(): ReceiptLeak[] {\n return ['udp-quic-possible', 'ech-possible']\n }\n\n async assertTouched(service: string, match?: TouchMatcher): Promise<void> {\n // Throws VerisError (not VerisUntouchedError) for an unknown service — a\n // typo is a different failure from a service that saw zero traffic.\n const entry: ReceiptEntry = await this.receipt(service)\n const need = match?.minRequests ?? 1\n const matched = match\n ? entry.entries.filter((r) =>\n (match.method === undefined || r.method.toUpperCase() === match.method.toUpperCase()) &&\n (match.path === undefined || r.path.includes(match.path)))\n : entry.entries\n if (matched.length < need) {\n const what = match\n ? `matching ${match.method ?? 'ANY'} ${match.path ?? '*'} (${matched.length}/${need})`\n : 'any intercepted requests'\n throw new VerisUntouchedError(\n `service '${service}' saw no ${what} — the code under test never reached it ` +\n `(a green run that skipped its dependency looks identical to a working one)`,\n service, { verisSandboxId: this.ctx.twinId })\n }\n }\n\n async getDataPlaneEnv(): Promise<Record<string, string>> {\n return dataPlaneEnv(await this.services())\n }\n\n /** The CA trust vars injected at create, for callers building their own env. */\n getTrustEnv(): Record<string, string> {\n return vendoredTrustEnv()\n }\n\n /**\n * Point every mocked vendor's callbacks/webhooks at this sandbox.\n *\n * Pass a PORT your app listens on and it resolves the sandbox's own preview\n * URL — the address a vendor would POST to in production. Pass a full URL to\n * use that instead, or null to unregister.\n *\n * One call covers every service: a twin has ONE client, so the control plane\n * fans the destination out to all of them.\n */\n deliverTo(port: number, opts?: DeliverToOpts): Promise<string>\n deliverTo(url: string | null, opts?: DeliverToOpts): Promise<string | null>\n async deliverTo(target: number | string | null, opts: DeliverToOpts = {}): Promise<string | null> {\n const url = typeof target === 'number'\n ? (await this.ctx.sandbox.getPreviewLink(target)).url\n : target\n await this.ctx.controlPlane.updateSandbox(\n this.ctx.environmentId, this.ctx.twinId, { client_base_url: url })\n if (url !== null && opts.probe !== false) await this.probeDelivery(url)\n return url\n }\n\n /** Ask each service to re-probe the registered destination; throw if none can reach it. */\n private async probeDelivery(url: string): Promise<void> {\n const services = (await this.services()).filter((s) => isHttpUrl(s.control_url))\n if (!services.length) return\n const probes = await Promise.all(services.map(async (svc) => {\n try {\n const res = await fetch(`${svc.control_url}/veris/client/probe`, { method: 'POST' })\n return res.ok ? await res.json() as { answered?: boolean } : null\n } catch { return null }\n }))\n if (!probes.some((p) => p?.answered)) {\n throw new VerisError(\n `no service could reach ${url} — is your app listening on that port inside the Daytona sandbox?`,\n { phase: 'receipt', verisSandboxId: this.ctx.twinId, responseBody: probes })\n }\n }\n}\n","// The SDK version sent to the control plane as X-Veris-SDK (it version-gates\n// gateway mode on it). Injected from package.json at build time by tsup's\n// `define`; the fallback keeps `tsx`/vitest runs working from source.\ndeclare const __SDK_VERSION__: string | undefined\n\nexport const SDK_VERSION: string =\n typeof __SDK_VERSION__ === 'string' ? __SDK_VERSION__ : '0.0.0-dev'\n"],"mappings":";AA0BA,cAAc;;;ACbd,SAAS,WAAW,mBAAmB;;;ACkBvC,SAAS,UAAU,SAAiB,OAAwB;AAC1D,QAAM,SACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,UAAU,WAAW,QAAQ;AAE/E,MAAI,CAAC,UAAU,QAAQ,SAAS,MAAM,EAAG,QAAO;AAChD,QAAM,UAAU,OAAO,SAAS,MAAM,GAAG,OAAO,MAAM,GAAG,GAAG,CAAC,WAAM;AACnE,SAAO,GAAG,OAAO,KAAK,OAAO;AAC/B;AAEO,IAAM,aAAN,cAAyB,MAAM;AAAA,EAC3B;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,OAAsG,CAAC,GACvG;AACA,UAAM,UAAU,SAAS,KAAK,KAAK,GAAG,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,MAAS;AAClG,SAAK,OAAO,WAAW;AACvB,SAAK,QAAQ,KAAK;AAClB,SAAK,iBAAiB,KAAK;AAC3B,SAAK,eAAe,KAAK;AAAA,EAC3B;AACF;AAGO,IAAM,0BAAN,cAAsC,WAAW;AAAC;AAGlD,IAAM,+BAAN,cAA2C,WAAW;AAAC;AAGvD,IAAM,8BAAN,cAA0C,WAAW;AAAA;AAAA,EAEjD;AAAA,EACT,YAAY,SAAiB,OAA0E,CAAC,GAAG;AACzG,UAAM,SAAS,IAAI;AACnB,SAAK,SAAS,KAAK;AAAA,EACrB;AACF;AAGO,IAAM,wBAAN,cAAoC,WAAW;AAAC;AAGhD,IAAM,sBAAN,cAAkC,WAAW;AAAA,EACzC;AAAA,EACT,YAAY,SAAiB,SAAiB,OAAoD,CAAC,GAAG;AACpG,UAAM,SAAS,IAAI;AACnB,SAAK,UAAU;AAAA,EACjB;AACF;AAGO,IAAM,mBAAN,cAA+B,WAAW;AAAC;AAI3C,IAAM,2BAAN,cAAuC,WAAW;AAAC;AAGnD,IAAM,4BAAN,cAAwC,WAAW;AAAC;;;ACzB3D,IAAM,QAAQ,CAAC,OAAe,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE3D,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EACQ;AAAA,EAEjB,YAAY,MAAwB;AAClC,SAAK,UAAU,KAAK,QAAQ,QAAQ,OAAO,EAAE;AAC7C,SAAK,UAAU;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,eAAe,KAAK;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAc,QAAQ,QAAgB,MAAc,MAAmC;AACrF,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QAC1C;AAAA,QACA,SAAS,KAAK;AAAA,QACd,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,MAC5D,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,WAAW,oCAAoC,MAAM,IAAI,IAAI,KAAK,EAAE,MAAM,CAAC;AAAA,IACvF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,KAAQ,KAAe,SAAiB,OAAwD;AAC5G,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI;AACJ,QAAI;AAAE,eAAS,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,IAAU,QAAQ;AAAE,eAAS;AAAA,IAAK;AAC3E,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,WAAW,GAAG,OAAO,KAAK,IAAI,MAAM,IAAI,EAAE,OAAO,cAAc,OAAO,CAAC;AAAA,IACnF;AAGA,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,WAAW,GAAG,OAAO,yBAAyB,EAAE,OAAO,cAAc,KAAK,CAAC;AAAA,IACvF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,eAAuB,OAAmE,CAAC,GAAyB;AACnI,UAAM,MAAM,MAAM,KAAK,QAAQ,QAAQ,oBAAoB,aAAa,cAAc;AAAA,MACpF,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB,CAAC;AAMD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI;AAAA,QACR,gBAAgB,aAAa,uBAAuB,KAAK,OAAO;AAAA,QAGhE,EAAE,OAAO,kBAAkB,cAAc,MAAM,IAAI,KAAK,EAAE;AAAA,MAAC;AAAA,IAC/D;AACA,WAAO,KAAK,KAAkB,KAAK,iCAAiC,aAAa,IAAI,gBAAgB;AAAA,EACvG;AAAA,EAEA,MAAM,QAAQ,WAAgD;AAC5D,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,iBAAiB,SAAS,EAAE;AAClE,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,WAAO,KAAK,KAAkB,KAAK,eAAe,SAAS,EAAE;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,UAAU,WAAmB,WAAyC;AAC1E,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,eAAS;AACP,YAAM,OAAO,MAAM,KAAK,QAAQ,SAAS;AACzC,UAAI,CAAC,KAAM,OAAM,IAAI,iBAAiB,iBAAiB,SAAS,mCAAmC,EAAE,gBAAgB,UAAU,CAAC;AAChI,UAAI,KAAK,WAAW,QAAS,QAAO;AACpC,UAAI,KAAK,WAAW,UAAU;AAC5B,cAAM,IAAI;AAAA,UACR,iBAAiB,SAAS,yBAAyB,KAAK,kBAAkB,mBAAmB;AAAA,UAC7F,EAAE,OAAO,kBAAkB,gBAAgB,UAAU;AAAA,QAAC;AAAA,MAC1D;AACA,UAAI,KAAK,IAAI,IAAI,UAAU;AACzB,cAAM,IAAI;AAAA,UACR,iBAAiB,SAAS,oBAAoB,SAAS,eAAe,KAAK,MAAM;AAAA,UACjF,EAAE,OAAO,kBAAkB,gBAAgB,UAAU;AAAA,QAAC;AAAA,MAC1D;AACA,YAAM,MAAM,IAAI;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,WAA2C;AACxD,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,iBAAiB,SAAS,WAAW;AAC3E,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,SAAS,wCAAmC,EAAE,gBAAgB,UAAU,CAAC;AAAA,IACvH;AACA,WAAO,KAAK,KAAoB,KAAK,uBAAuB,SAAS,IAAI,SAAS;AAAA,EACpF;AAAA,EAEA,MAAM,WAAW,eAAuB,WAAqC;AAC3E,UAAM,MAAM,MAAM,KAAK,QAAQ,UAAU,oBAAoB,aAAa,cAAc,SAAS,EAAE;AACnG,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,KAAK,kBAAkB,SAAS,EAAE;AAC/D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,qBAAqB,eAAuB,WAAqD;AACrG,UAAM,MAAM,MAAM,KAAK,QAAQ,QAAQ,oBAAoB,aAAa,cAAc,SAAS,oBAAoB;AACnH,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,YAAM,IAAI;AAAA,QACR,yEAAyE,KAAK,UAAU,aAAa,KAAK,OAAO,MAAM,EAAE;AAAA,QACzH,EAAE,OAAO,mBAAmB,gBAAgB,WAAW,QAAQ,KAAK,SAAS,cAAc,KAAK;AAAA,MAAC;AAAA,IACrG;AACA,WAAO,KAAK,KAAuB,KAAK,8BAA8B,SAAS,IAAI,iBAAiB;AAAA,EACtG;AAAA;AAAA,EAGA,MAAM,cAAc,eAAuB,WAAmB,OAAoC;AAChG,UAAM,MAAM,MAAM,KAAK,QAAQ,SAAS,oBAAoB,aAAa,cAAc,SAAS,IAAI,KAAK;AACzG,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,SAAS,cAAc,EAAE,gBAAgB,UAAU,CAAC;AAAA,IAClG;AACA,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,KAAK,kBAAkB,SAAS,EAAE;AAAA,EACjE;AAAA;AAAA,EAGA,MAAM,UAAU,eAAuB,WAAmB,YAAmC;AAC3F,UAAM,MAAM,MAAM,KAAK,QAAQ,SAAS,oBAAoB,aAAa,cAAc,SAAS,IAAI,EAAE,aAAa,WAAW,CAAC;AAC/H,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,SAAS,uCAAkC,EAAE,gBAAgB,UAAU,CAAC;AAAA,IACtH;AAGA,QAAI,CAAC,IAAI,MAAM,IAAI,WAAW,IAAK,OAAM,KAAK,KAAK,KAAK,iBAAiB,SAAS,EAAE;AAAA,EACtF;AAAA;AAAA,EAGA,MAAM,gBAA+B;AACnC,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,oBAAoB;AAC1D,QAAI,IAAI,WAAW,IAAK;AACxB,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,qCAAqC,IAAI,MAAM;AAAA,QAAK,EAAE,OAAO,oBAAoB;AAAA,MAAC;AAAA,IACtF;AAAA,EACF;AACF;;;ACrLO,SAAS,kBAAkB,MAA6D;AAC7F,QAAM,OAAO,MAAM,QAAS,MAA0B,QAAQ,IACzD,KAAyB,WAC1B,CAAC;AACL,QAAM,UAA4B,KAAK,IAAI,CAAC,MAAM;AAChD,UAAM,MAAM;AACZ,WAAO;AAAA,MACL,QAAQ,OAAO,IAAI,UAAU,EAAE;AAAA,MAC/B,MAAM,OAAO,IAAI,QAAQ,EAAE;AAAA,MAC3B,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAAA,IACxD;AAAA,EACF,CAAC;AACD,SAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ;AAC1C;AAEA,eAAsB,kBAAkB,KAAyC;AAC/E,QAAM,MAAM,GAAG,IAAI,WAAW;AAC9B,QAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,WAAW,uCAAuC,IAAI,IAAI,MAAM,IAAI,MAAM,KAAK;AAAA,MACvF,OAAO;AAAA,MAAW,cAAc,KAAK,MAAM,GAAG,GAAG;AAAA,IAAE,CAAC;AAAA,EACxD;AACA,MAAI;AACJ,MAAI;AAAE,UAAM,KAAK,MAAM,IAAI;AAAA,EAAE,QAAQ;AACnC,UAAM,IAAI,WAAW,YAAY,IAAI,IAAI,sCAAsC;AAAA,MAC7E,OAAO;AAAA,MAAW,cAAc,KAAK,MAAM,GAAG,GAAG;AAAA,IAAE,CAAC;AAAA,EACxD;AACA,QAAM,EAAE,OAAO,QAAQ,IAAI,kBAAkB,GAAG;AAChD,SAAO,EAAE,UAAU,OAAO,YAAY,IAAI,aAAa,SAAS,IAAI;AACtE;;;ACxDO,IAAM,YAAY,CAAC,MAAc,WAAW,KAAK,CAAC;AAelD,SAAS,YAAY,UAAmC;AAC7D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,eAAW,KAAK,IAAI,UAAU,CAAC,EAAG,OAAM,IAAI,EAAE,IAAI;AAAA,EACpD;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAGO,SAAS,UAAU,UAAmC;AAC3D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,eAAW,KAAK,CAAC,IAAI,aAAa,IAAI,GAAG,GAAG;AAC1C,UAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAG;AACzB,UAAI;AAAE,cAAM,IAAI,IAAI,IAAI,CAAC,EAAE,QAAQ;AAAA,MAAE,QAAQ;AAAA,MAAyB;AAAA,IACxE;AAAA,EACF;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAYO,SAAS,eAAe,UAAmC;AAChE,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,IAAI,OAAO,UAAU,IAAI,GAAG,EAAG;AACpC,eAAW,KAAK,aAAa,IAAI,GAAG,EAAG,OAAM,IAAI,CAAC;AAAA,EACpD;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAEA,SAAS,aAAa,KAAuB;AAC3C,QAAM,MAAgB,CAAC;AACvB,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AAErB,QAAI,EAAE,SAAU,KAAI,KAAK,EAAE,SAAS,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC7D,QAAQ;AAAA,EAER;AAGA,QAAM,YAAY,IAAI,QAAQ,eAAe,EAAE,EAAE,MAAM,MAAM,EAAE,CAAC,KAAK;AACrE,QAAM,UAAU,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,UAAU,YAAY,GAAG,IAAI,CAAC,IAAI;AAC5F,aAAW,QAAQ,QAAQ,MAAM,GAAG,GAAG;AACrC,UAAM,IAAI,KAAK,MAAM,sCAAsC;AAC3D,QAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,EAAG,KAAI,KAAK,EAAE,CAAC,EAAE,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC1E;AACA,SAAO;AACT;AAOO,SAAS,aAAa,UAAiD;AAC5E,QAAM,OAA+B,CAAC;AACtC,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,OAAO,UAAU,IAAI,GAAG,EAAG;AAIrD,QAAI,CAAC,cAAc,IAAI,QAAQ,EAAG;AAClC,SAAK,IAAI,QAAQ,IAAI,IAAI;AAAA,EAC3B;AACA,SAAO;AACT;AAIA,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAmB;AAAA,EAAgB;AAAA,EAAY;AAAA,EACrE;AAAA,EAAc;AAAA,EAAiB;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AACzD,CAAC;AACM,SAAS,cAAc,MAAuB;AACnD,SAAO,yBAAyB,KAAK,IAAI,KAAK,CAAC,oBAAoB,IAAI,IAAI;AAC7E;AAYO,IAAM,yBAA4C;AAAA;AAAA,EAEvD;AAAA,EAAsB;AAAA;AAAA,EAEtB;AAAA,EAAY;AAAA;AAAA,EAEZ;AAAA,EAAoB;AAAA;AAAA,EAEpB;AAAA,EAAa;AAAA,EAAoB;AAAA;AAAA,EAEjC;AAAA,EAAkB;AAAA,EAAuB;AAAA,EAAsB;AAAA;AAAA,EAE/D;AAAA,EAAc;AAAA,EAAuB;AAAA,EACrC;AAAA,EAA6B;AAC/B;AA4BO,SAAS,aAAa,MAAuC;AAClE,QAAM,EAAE,UAAU,MAAM,cAAc,WAAW,CAAC,GAAG,kBAAkB,KAAK,IAAI;AAChF,MAAI,SAAS,OAAQ,QAAO,CAAC;AAE7B,QAAM,UAAU;AAAA,IACd,GAAG,YAAY,QAAQ;AAAA,IACvB,GAAG;AAAA,IACH,GAAG,eAAe,QAAQ;AAAA,IAC1B,GAAI,kBAAkB,yBAAyB,CAAC;AAAA,IAChD,GAAG;AAAA,EACL,EAAE,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC;AAEvC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,iBAAiB,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG;AAAA,EACxD;AACF;;;ACvLO,IAAM,eAAe;AAGrB,IAAM,gBAAgB;AAGtB,IAAM,gBAAgB;AAWtB,IAAM,eAAe;AAqBrB,SAAS,mBAA2C;AACzD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,kCAAkC;AAAA,IAClC,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,yBAAyB;AAAA,IACzB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,oCAAoC;AAAA,IACpC,qBAAqB;AAAA,EACvB;AACF;AAaO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA,kFAAkF,YAAY;AAAA,EAC9F,8KAEsC,YAAY;AACpD,EAAE,KAAK,MAAM;AAUN,SAAS,iBAAiB,QAAqE;AACpG,QAAM,WAAW,iBAAiB;AAIlC,QAAM,MAA8B,EAAE,GAAG,SAAS;AAClD,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AACnD,QAAI,EAAE,KAAK,UAAW;AACtB,QAAI,OAAO,QAAQ,SAAU;AAE7B,QAAI,CAAC,iBAAiB,KAAK,GAAG,EAAG;AACjC,QAAI,CAAC,IAAI;AAAA,EACX;AACA,SAAO;AACT;;;AC5FA,IAAM,cAAc;AAEpB,IAAM,cAAc;AAGb,SAAS,WAAW,GAAmB;AAC5C,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;AAEA,IAAM,KAAK,CAAC,SAAkB,KAAa,aAAa,OACtD,QAAQ,QAAQ,eAAe,UAAU,WAAW,GAAG,CAAC,IAAI,QAAW,QAAW,UAAU;AAqBvF,SAAS,gBAAgB,YAIrB;AAIT,MAAI,WAAW,eAAgB,QAAO,eAAe,WAAW,cAAc;AAE9E,MAAI,CAAC,WAAW,mBAAmB,CAAC,YAAY,KAAK,WAAW,eAAe,GAAG;AAChF,UAAM,IAAI;AAAA,MACR,2DACG,KAAK,UAAU,WAAW,eAAe,CAAC;AAAA,MAC7C,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,SAAO,UAAU,mBAAmB,WAAW,QAAQ,CAAC,MAAM,WAAW,eAAe;AAC1F;AAOA,SAAS,eAAe,KAAqB;AAC3C,MAAI;AACJ,MAAI;AAAE,QAAI,IAAI,IAAI,GAAG;AAAA,EAAE,QAAQ;AAC7B,UAAM,IAAI;AAAA,MACR,gEAAgE,KAAK,UAAU,GAAG,CAAC;AAAA,MACnF,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,MAAI,EAAE,aAAa,WAAW,EAAE,aAAa,UAAU;AACrD,UAAM,IAAI;AAAA,MACR,sCAAsC,EAAE,SAAS,QAAQ,KAAK,EAAE,CAAC;AAAA,MAEjE,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,MAAI,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM;AAC1B,UAAM,IAAI;AAAA,MACR,oDAAoD,KAAK,UAAU,GAAG,CAAC;AAAA,MACvE,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,SAAO;AACT;AA6BA,eAAsB,UAAU,SAAkB,OAA8B;AAC9E,QAAM,QAAQ,GAAG,WAAW,OAAO,KAAK,OAAO,MAAM,GAAG,aAAa;AAErE,QAAM,SAAS;AAAA,IACb,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA,IAI3B,SAAS,aAAa,qBAAqB,aAAa,SAAS,YAAY;AAAA,IAC7E,cAAc,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM1B;AAAA,IACA,6BAA6B,aAAa,IAAI,YAAY,+BACzC,WAAW,cAAc,CAAC;AAAA;AAAA,IAE3C,QAAQ,YAAY;AAAA,EACtB,EAAE,KAAK,IAAI;AAEX,QAAM,IAAI,MAAM,GAAG,SAAS,QAAQ,GAAG,EAAE,MAAM,CAAC,OAAgB,EAAE,UAAU,GAAG,QAAQ,OAAO,CAAC,EAAE,EAAE;AACnG,MAAI,EAAE,EAAE,UAAU,IAAI,SAAS,iBAAiB,GAAG;AACjD,UAAM,IAAI;AAAA,MACR,qCAAqC,YAAY,uDAC1B,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,MAC3D,EAAE,OAAO,aAAa;AAAA,IAAC;AAAA,EAC3B;AACF;AAWA,eAAsB,YACpB,SACA,YACA,gBACe;AACf,MAAI,CAAC,YAAY,KAAK,UAAU,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,qEAAqE,KAAK,UAAU,UAAU,CAAC;AAAA,MAC/F,EAAE,OAAO,UAAU,gBAAgB,eAAe;AAAA,IAAC;AAAA,EACvD;AAGA,QAAM,IAAI,MAAM;AAAA,IACd;AAAA,IACA,qBAAqB,YAAY,0BAA0B,UAAU;AAAA,IACrE;AAAA,EACF,EAAE,MAAM,CAAC,OAAgB,EAAE,UAAU,GAAG,QAAQ,OAAO,CAAC,EAAE,EAAE;AAE5D,MAAI,OAAsC,CAAC;AAC3C,MAAI;AAAE,WAAO,KAAK,MAAM,EAAE,UAAU,EAAE;AAAA,EAAE,QAAQ;AAAA,EAAsB;AACtE,MAAI,KAAK,qBAAqB,gBAAgB;AAC5C,UAAM,IAAI;AAAA,MACR,mHACgC,cAAc,uBAC1C,EAAE,UAAU,WAAW,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,MAC/C,EAAE,OAAO,UAAU,gBAAgB,eAAe;AAAA,IAAC;AAAA,EACvD;AACF;;;AC7KO,SAAS,uBAAuB,KAAwB;AAC7D,MAAI,CAAC,IAAI,eAAe,CAAC,UAAU,IAAI,WAAW,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,YAAY,IAAI,IAAI;AAAA,MACpB,EAAE,OAAO,aAAa;AAAA,IACxB;AAAA,EACF;AACF;AAOA,eAAsB,YAAY,KAAmC;AACnE,yBAAuB,GAAG;AAC1B,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,WAAW,eAAe;AACzD,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,WAAW,0CAA0C,IAAI,IAAI,MAAM,IAAI,MAAM,KAAK;AAAA,MAC1F,OAAO;AAAA,MAAc,cAAc,KAAK,MAAM,GAAG,GAAG;AAAA,IAAE,CAAC;AAAA,EAC3D;AACA,SAAO;AACT;;;ACsBO,IAAM,eAAN,MAAuC;AAAA,EAC5C,YAA6B,KAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA,EAE7B,IAAI,YAAoB;AAAE,WAAO,KAAK,IAAI;AAAA,EAAO;AAAA,EACjD,IAAI,OAAkB;AAAE,WAAO;AAAA,EAAU;AAAA,EAEzC,WAAmC;AACjC,WAAO,KAAK,IAAI,aAAa,SAAS,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,SAAuC;AAClE,UAAM,WAAW,MAAM,KAAK,SAAS;AACrC,UAAM,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AACnD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR,oBAAoB,OAAO,6DAAwD,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,QACnI,EAAE,gBAAgB,KAAK,IAAI,OAAO;AAAA,MAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,SAAkC;AAC7C,WAAO,YAAY,MAAM,KAAK,eAAe,OAAO,CAAC;AAAA,EACvD;AAAA,EAIA,MAAM,QAAQ,SAAmD;AAI/D,UAAM,YAAY,KAAK,IAAI,SAAS,KAAK,IAAI,YAAY,KAAK,IAAI,MAAM;AAExE,QAAI,YAAY,OAAW,QAAO,kBAAkB,MAAM,KAAK,eAAe,OAAO,CAAC;AAEtF,UAAM,WAAW,MAAM,KAAK,SAAS;AACrC,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,OAAO,CAAC,MAAM,UAAU,EAAE,WAAW,CAAC,EAAE,IAAI,OAAO,QAAQ,CAAC,IAAI,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAU;AAAA,IAAC;AACxH,WAAO;AAAA,MACL,UAAU,OAAO,YAAY,OAAO;AAAA,MACpC,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,KAAK,MAAM;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,QAAuB;AAC7B,WAAO,CAAC,qBAAqB,cAAc;AAAA,EAC7C;AAAA,EAEA,MAAM,cAAc,SAAiB,OAAqC;AAGxE,UAAM,QAAsB,MAAM,KAAK,QAAQ,OAAO;AACtD,UAAM,OAAO,OAAO,eAAe;AACnC,UAAM,UAAU,QACZ,MAAM,QAAQ,OAAO,CAAC,OACnB,MAAM,WAAW,UAAa,EAAE,OAAO,YAAY,MAAM,MAAM,OAAO,YAAY,OAClF,MAAM,SAAS,UAAa,EAAE,KAAK,SAAS,MAAM,IAAI,EAAE,IAC3D,MAAM;AACV,QAAI,QAAQ,SAAS,MAAM;AACzB,YAAM,OAAO,QACT,YAAY,MAAM,UAAU,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,QAAQ,MAAM,IAAI,IAAI,MACjF;AACJ,YAAM,IAAI;AAAA,QACR,YAAY,OAAO,YAAY,IAAI;AAAA,QAEnC;AAAA,QAAS,EAAE,gBAAgB,KAAK,IAAI,OAAO;AAAA,MAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,kBAAmD;AACvD,WAAO,aAAa,MAAM,KAAK,SAAS,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGA,cAAsC;AACpC,WAAO,iBAAiB;AAAA,EAC1B;AAAA,EAcA,MAAM,UAAU,QAAgC,OAAsB,CAAC,GAA2B;AAChG,UAAM,MAAM,OAAO,WAAW,YACzB,MAAM,KAAK,IAAI,QAAQ,eAAe,MAAM,GAAG,MAChD;AACJ,UAAM,KAAK,IAAI,aAAa;AAAA,MAC1B,KAAK,IAAI;AAAA,MAAe,KAAK,IAAI;AAAA,MAAQ,EAAE,iBAAiB,IAAI;AAAA,IAAC;AACnE,QAAI,QAAQ,QAAQ,KAAK,UAAU,MAAO,OAAM,KAAK,cAAc,GAAG;AACtE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAc,cAAc,KAA4B;AACtD,UAAM,YAAY,MAAM,KAAK,SAAS,GAAG,OAAO,CAAC,MAAM,UAAU,EAAE,WAAW,CAAC;AAC/E,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,SAAS,MAAM,QAAQ,IAAI,SAAS,IAAI,OAAO,QAAQ;AAC3D,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,GAAG,IAAI,WAAW,uBAAuB,EAAE,QAAQ,OAAO,CAAC;AACnF,eAAO,IAAI,KAAK,MAAM,IAAI,KAAK,IAA8B;AAAA,MAC/D,QAAQ;AAAE,eAAO;AAAA,MAAK;AAAA,IACxB,CAAC,CAAC;AACF,QAAI,CAAC,OAAO,KAAK,CAAC,MAAM,GAAG,QAAQ,GAAG;AACpC,YAAM,IAAI;AAAA,QACR,0BAA0B,GAAG;AAAA,QAC7B,EAAE,OAAO,WAAW,gBAAgB,KAAK,IAAI,QAAQ,cAAc,OAAO;AAAA,MAAC;AAAA,IAC/E;AAAA,EACF;AACF;;;AClLO,IAAM,cACX,OAAsC,UAAkB;;;AT+D1D,IAAM,QAAQ;AAAA,EACZ,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AACd;AAEA,IAAM,mBAAsC,OAAO,OAAO,KAAK;AAWxD,SAAS,eAAe,KAAmC;AAChE,SAAO,OAAQ,IAAqB,mBAAmB;AACzD;AAEO,IAAM,UAAN,cAAsB,YAAY;AAAA,EACtB;AAAA,EAEjB,YAAY,QAA6B;AACvC,UAAM,MAAM;AACZ,SAAK,gBAAgB,QAAQ,SAAS,CAAC;AAAA,EACzC;AAAA,EAYA,MAAe,OACb,QACA,SACkB;AAClB,UAAM,IAAe,EAAE,GAAG,KAAK,eAAe,GAAI,QAAQ,SAAS,CAAC,EAAG;AACvE,UAAM,OAAO,WAAW,MAAM;AAE9B,QAAI,EAAE,SAAU,QAAO,KAAK,WAAW,MAAM,OAAO;AAEpD,UAAM,SAAS,mBAAmB,CAAC;AACnC,UAAM,eAAe,IAAI,aAAa;AAAA,MACpC,QAAQ,OAAO;AAAA,MAAQ,SAAS,OAAO;AAAA,MAAS,YAAY;AAAA,IAC9D,CAAC;AACD,UAAM,SAAqB,EAAE,UAAU;AACvC,UAAM,aAAa,EAAE,cAAc;AACnC,UAAM,WAAW,CAAC,EAAE;AAIpB,UAAM,OAAO,MAAM,KAAK,cAAc,cAAc,GAAG,QAAQ,UAAU;AACzE,UAAM,cAAc,YAAY;AAC9B,UAAI,SAAU,OAAM,aAAa,WAAW,KAAK,gBAAgB,KAAK,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC1F;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AAIF,mBAAa,MAAM,aAAa,qBAAqB,KAAK,gBAAgB,KAAK,EAAE;AACjF,UAAI,CAAC,YAAY;AACf,cAAM,IAAI;AAAA,UACR;AAAA,UAEA,EAAE,OAAO,mBAAmB,gBAAgB,KAAK,GAAG;AAAA,QAAC;AAAA,MACzD;AACA,UAAI,CAAC,WAAW,mBAAmB,CAAC,WAAW,gBAAgB;AAC7D,cAAM,IAAI;AAAA,UACR;AAAA,UAGA,EAAE,OAAO,mBAAmB,gBAAgB,KAAK,GAAG;AAAA,QAAC;AAAA,MACzD;AAEA,YAAM,WAAW,KAAK,UAAU,SAAS,KAAK,WAAW,MAAM,aAAa,SAAS,KAAK,EAAE;AAE5F,YAAM,WAAW,gBAAgB,UAAU;AAC3C,YAAM,UAAU,aAAa;AAAA,QAC3B;AAAA,QAAU,MAAM;AAAA;AAAA;AAAA,QAGhB,cAAc,CAAC,IAAI,IAAI,QAAQ,EAAE,UAAU,WAAW,WAAW,EAAE,OAAO,OAAO;AAAA,QACjF,UAAU,EAAE;AAAA,QAAU,iBAAiB,EAAE;AAAA,MAC3C,CAAC;AAKD,YAAM,eAAuC;AAAA,QAC3C,GAAI,EAAE,cAAc,QAAQ,iBAAiB,MAAS,IAAI,CAAC;AAAA,QAC3D,GAAI,EAAE,iBAAiB,QAAQ,aAAa,QAAQ,IAAI,CAAC;AAAA,QACzD,kBAAkB,KAAK;AAAA,MACzB;AAEA,YAAM,eAAe;AAAA,QACnB,GAAG;AAAA,QACH,SAAS,EAAE,GAAI,KAAK,WAAW,CAAC,GAAI,GAAG,aAAa;AAAA,QACpD,QAAQ;AAAA,UACN,GAAG,cAAc,KAAK,MAAM;AAAA,UAC5B,CAAC,MAAM,MAAM,GAAG,KAAK;AAAA,UACrB,CAAC,MAAM,KAAK,GAAG,KAAK;AAAA,UACpB,CAAC,MAAM,OAAO,GAAG,OAAO;AAAA,UACxB,CAAC,MAAM,MAAM,GAAG;AAAA,UAChB,CAAC,MAAM,QAAQ,GAAG,OAAO,QAAQ;AAAA,UACjC,CAAC,MAAM,IAAI,GAAG;AAAA,UACd,CAAC,MAAM,UAAU,GAAG,WAAW;AAAA,QACjC;AAAA,QACA,GAAG;AAAA;AAAA;AAAA;AAAA,QAIH,kBAAkB;AAAA,QAClB,YAAY,KAAK,cAAc;AAAA,MACjC;AAEA,gBAAU,MAAM,KAAK,WAAW,cAA8B,OAAO;AAAA,IACvE,SAAS,OAAO;AACd,YAAM,YAAY;AAClB,UAAI,iBAAiB,WAAY,OAAM;AACvC,YAAM,IAAI,WAAW,iCAAiC;AAAA,QACpD,OAAO;AAAA,QAAkB,gBAAgB,KAAK;AAAA,QAAI;AAAA,MAAM,CAAC;AAAA,IAC7D;AAIA,QAAI;AACF,YAAM,UAAU,SAAS,WAAW,MAAM;AAC1C,YAAM,YAAY,SAAS,WAAW,aAAa,KAAK,EAAE;AAAA,IAC5D,SAAS,KAAK;AACZ,YAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACrC,YAAM,YAAY;AAClB,YAAM;AAAA,IACR;AAEA,WAAO,KAAK,OAAO,SAAS;AAAA,MAC1B;AAAA,MAAc,eAAe,KAAK;AAAA,MAAgB,QAAQ,KAAK;AAAA,MAC/D;AAAA,MAAQ;AAAA,MAAU,YAAY,WAAW;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAe,IAAI,iBAA2C;AAC5D,UAAM,UAAU,MAAM,MAAM,IAAI,eAAe;AAC/C,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA;AAAA,EAGS,KAAK,OAA4D;AACxE,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,UAAM,YAAY,CAAC,MAAe,KAAK,UAAU,CAAC;AAClD,YAAQ,mBAAmB;AACzB,uBAAiB,WAAW,MAAO,OAAM,UAAU,OAAO;AAAA,IAC5D,GAAG;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,UAAU,SAA2B;AAC3C,UAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,UAAM,SAAS,OAAO,MAAM,MAAM;AAClC,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,SAAS,KAAK,cAAc,UAAU,QAAQ,IAAI;AACxD,QAAI,CAAC,OAAQ,QAAO;AAIpB,UAAM,cAAc,KAAK,cAAc,WAAW,QAAQ,IAAI;AAC9D,UAAM,YAAY,OAAO,MAAM,OAAO;AACtC,QAAI,eAAe,aAAa,cAAc,aAAa;AACzD,YAAM,IAAI;AAAA,QACR,WAAW,QAAQ,EAAE,iDAAiD,SAAS,8BACxD,WAAW;AAAA,QAClC,EAAE,OAAO,SAAS;AAAA,MAAC;AAAA,IACvB;AACA,UAAM,UAAU,eAAe,aAAa;AAE5C,WAAO,KAAK,OAAO,SAAS;AAAA,MAC1B,cAAc,IAAI,aAAa,EAAE,QAAQ,SAAS,YAAY,YAAY,CAAC;AAAA,MAC3E,eAAe,OAAO,MAAM,KAAK,KAAK;AAAA,MACtC;AAAA;AAAA;AAAA,MAGA,YAAY,OAAO,MAAM,UAAU,KAAK;AAAA,MACxC,QAAS,OAAO,MAAM,MAAM,KAAgC;AAAA,MAC5D,UAAU,OAAO,MAAM,QAAQ,MAAM;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cACZ,cAA4B,GAAc,QAA6B,YACjD;AACtB,QAAI,EAAE,iBAAiB;AACrB,YAAM,WAAW,MAAM,aAAa,QAAQ,EAAE,eAAe;AAC7D,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,WAAW,iBAAiB,EAAE,eAAe,cAAc;AAAA,UACnE,OAAO;AAAA,UAAkB,gBAAgB,EAAE;AAAA,QAAgB,CAAC;AAAA,MAChE;AACA,aAAO,SAAS,WAAW,UAAU,WAAW,aAAa,UAAU,EAAE,iBAAiB,IAAO;AAAA,IACnG;AACA,QAAI,CAAC,OAAO,eAAe;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE,OAAO,cAAc;AAAA,MAAC;AAAA,IAC5B;AACA,UAAM,UAAU,MAAM,aAAa,WAAW,OAAO,eAAe,EAAE,WAAW,CAAC;AAClF,QAAI;AACF,aAAO,MAAM,aAAa,UAAU,QAAQ,IAAI,IAAO;AAAA,IACzD,SAAS,GAAG;AACV,YAAM,aAAa,WAAW,OAAO,eAAe,QAAQ,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC9E,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,OAAO,SAAkB,KAA6C;AAG5E,QAAI,eAAe,OAAO,EAAG,QAAO;AAEpC,UAAM,QAAQ,IAAI,aAAa,EAAE,GAAG,KAAK,QAAQ,CAAC;AAClD,UAAM,iBAAiB,QAAQ,OAAO,KAAK,OAAO;AAElD,WAAO,iBAAiB,SAAS;AAAA,MAC/B,OAAO,EAAE,OAAO,OAAO,YAAY,MAAM,cAAc,KAAK;AAAA,MAC5D,gBAAgB,EAAE,OAAO,IAAI,QAAQ,YAAY,MAAM,cAAc,KAAK;AAAA,MAC1E,QAAQ;AAAA,QACN,cAAc;AAAA,QACd,OAAO,OAAO,SAAkB,SAAkC;AAGhE,cAAI,IAAI,UAAU;AAChB,kBAAM,IAAI,aAAa,WAAW,IAAI,eAAe,IAAI,MAAM,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACjF;AACA,iBAAO,eAAe,SAAS,IAAI;AAAA,QACrC;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,WACN,QACA,SACkB;AAElB,WAAQ,MAAM,OAA6B,KAAK,MAAM,QAAQ,OAAO;AAAA,EACvE;AACF;AAEA,IAAO,kBAAQ;AAQf,SAAS,mBAAmB,GAAmC;AAC7D,QAAM,SAAS,EAAE,UAAU,QAAQ,IAAI;AACvC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MAEA,EAAE,OAAO,cAAc;AAAA,IAAC;AAAA,EAC5B;AACA,SAAO;AAAA,IACL;AAAA,IACA,eAAe,EAAE,iBAAiB,QAAQ,IAAI;AAAA,IAC9C,UAAU,EAAE,WAAW,QAAQ,IAAI,kBAAkB,4BAA4B,QAAQ,OAAO,EAAE;AAAA,EACpG;AACF;AAEA,SAAS,WAAW,QAA+D;AACjF,QAAM,EAAE,OAAO,QAAQ,GAAG,KAAK,IAAI,UAAU,CAAC;AAC9C,SAAO;AACT;AAGA,SAAS,cAAc,QAAoE;AACzF,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AACnD,QAAI,CAAC,iBAAiB,SAAS,CAAC,EAAG,KAAI,CAAC,IAAI;AAAA,EAC9C;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/daytona.ts","../src/errors.ts","../src/control-plane.ts","../src/run-receipt.ts","../src/receipt.ts","../src/service-control.ts","../src/network.ts","../src/gateway.ts","../src/trust.ts","../src/state.ts","../src/veris-api.ts","../src/profile.ts","../src/version.ts","../src/daytona-key.ts","../src/teardown.ts"],"sourcesContent":["// @veris-ai/daytona — Veris twin interception for Daytona sandboxes.\n//\n// This is the ENGINE integration, and it is deliberately generic: it knows\n// nothing about what you run in the sandbox, and needs no particular image.\n// Running an agent in there is one use of it (see @veris-ai/daytona-opencode)\n// rather than what it is for — the same relationship @veris-ai/e2b has to E2B.\n//\n// A drop-in for @daytona/sdk. The only difference is that `Daytona` is ours,\n// so every sandbox it creates comes up with a Veris twin already answering its\n// vendor API calls:\n//\n// import { Daytona } from '@veris-ai/daytona' // was '@daytona/sdk'\n// const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })\n// const sbx = await daytona.create()\n// await sbx.process.executeCommand('curl https://api.stripe.com/v1/charges')\n// await sbx.veris.assertTouched('stripe')\n// await sbx.delete() // deletes the twin too\n//\n// Everything else from @daytona/sdk is re-exported unchanged, so apps depend\n// only on this package.\n//\n// @daytona/sdk is a PEER dependency, deliberately. Consumers do\n// `err instanceof DaytonaNotFoundError` on errors that cross this boundary\n// (the OpenCode plugin branches on exactly that to tell \"sandbox is gone\" from\n// \"transient failure\"), and two copies of the SDK in one tree would make those\n// checks silently return false.\nexport * from '@daytona/sdk'\n\n// Ours wins the name. An explicit local export takes precedence over the star\n// above, which is the whole trick that makes the plugin fork a one-line diff.\nexport { Daytona, default } from './daytona'\nexport type { VerisOpts, VerisDaytonaConfig, VerisSandbox } from './daytona'\nexport { isVerisSandbox, verisOwnsTwin, verisTwinId } from './daytona'\n\nexport type { VerisApi, TouchMatcher, DeliverToOpts, VerisContext } from './veris-api'\nexport type { Receipt, ReceiptEntry, ReceiptRequest, ReceiptLeak } from './receipt'\nexport type { EgressMode, NetworkParams, NetworkPlan } from './network'\nexport { buildNetwork, vendorHosts, twinHosts, directTwinHosts, dataPlaneHosts } from './network'\nexport type { ServiceInfo as VerisServiceInfo, RouteEntry, TwinSandbox } from './control-plane'\nexport { ControlPlane } from './control-plane'\nexport {\n CA_CERT_PATH, SYSTEM_BUNDLE, VERIS_BUNDLE, VERIS_CA_FILE, NODE_TRUST_FLAG,\n BUNDLED_CA_FILES, BUNDLED_CA_PATCH_SCRIPT,\n nodeOptionsWithTrust, vendoredTrustEnv, trustPrelude,\n} from './trust'\nexport { gatewayIps, gatewayProxyUrl, patchBundledCas } from './gateway'\nexport {\n DEFAULT_API_BASE, profilePath, resolveVerisCredentials, requireVerisCredentials, missingKeyMessage,\n} from './profile'\nexport type { VerisCredentials, ResolveOpts, ProfileFile } from './profile'\nexport {\n DAYTONA_API_URL, DELETE_SANDBOXES, daytonaApiUrl, fetchDaytonaKey, canDeleteSandboxes, cannotTeardownWarning,\n} from './daytona-key'\nexport type { DaytonaKeyInfo } from './daytona-key'\nexport { isPermissionDenied, sandboxBrakes, teardownRefusedMessage } from './teardown'\nexport type { RefusedTeardown } from './teardown'\nexport { fetchManual, assertHttpControlPlane } from './state'\nexport {\n VerisError,\n MissingCredentialsError,\n VerisGatewayUnreachableError,\n VerisGatewayNotOfferedError,\n ReceiptIntegrityError,\n VerisUntouchedError,\n TwinExpiredError,\n SnapshotUnsupportedError,\n UnsupportedOperationError,\n} from './errors'\nexport type { VerisErrorPhase } from './errors'\nexport { SDK_VERSION } from './version'\n\nexport type { ReceiptBaseline } from './run-receipt'\nexport type { ControlResource, ControlOptions } from './service-control'\n","// The Veris Daytona client: a drop-in subclass of @daytona/sdk's Daytona whose\n// sandboxes come up with a Veris twin already answering their vendor calls.\n//\n// Everything the product needs happens inside create() — snapshot registration,\n// twin provisioning, the network allowlist, the CA, starting the proxy and\n// waiting for it to bind. That is deliberate: it keeps the OpenCode plugin's\n// diff to a single changed import, and it means create() resolving is a promise\n// that interception is live.\n//\n// Note we do NOT subclass Sandbox the way @veris-ai/e2b does. Daytona builds\n// Sandbox internally from seven arguments, six of them private SDK types, so\n// there is nothing to extend. We enrich the params, call super, and attach the\n// Veris surface to the instance that comes back.\nimport { Daytona as BaseDaytona } from '@daytona/sdk'\nimport type {\n CreateSandboxFromImageParams,\n CreateSandboxFromSnapshotParams,\n DaytonaConfig,\n Image,\n ListSandboxesQuery,\n Sandbox,\n} from '@daytona/sdk'\nimport { ControlPlane } from './control-plane'\nimport type { ServiceInfo, TwinSandbox } from './control-plane'\nimport { VerisApiImpl } from './veris-api'\nimport type { VerisApi, VerisContext } from './veris-api'\nimport { buildNetwork, dataPlaneEnv, isHttpUrl } from './network'\nimport type { EgressMode } from './network'\nimport { fetchWatermark } from './receipt'\nimport { CA_CERT_PATH, nodeOptionsWithTrust, sanitizeTrustEnv } from './trust'\nimport { gatewayIps, gatewayProxyUrl, installCa, probeCanary } from './gateway'\nimport { MissingCredentialsError, VerisError, VerisGatewayNotOfferedError } from './errors'\nimport { requireVerisCredentials, resolveVerisCredentials } from './profile'\nimport { SDK_VERSION } from './version'\n\nexport interface VerisOpts {\n /** Veris API key. Falls back to process.env.VERIS_API_KEY, then to the\n * profile `veris login` saved in ~/.veris/twin.yaml. Required. */\n apiKey?: string\n /** Veris environment the twin is deployed from. Falls back to process.env.VERIS_ENVIRONMENT_ID. */\n environmentId?: string\n /** Control plane base. Falls back to process.env.VERIS_API_BASE, then the\n * profile's api_base, then 'https://svc.api.veris.ai'. */\n apiBase?: string\n /** Attach to an EXISTING twin instead of provisioning one (advanced). delete() will NOT remove it. */\n attachSandboxId?: string\n /** Twin TTL backstop, minutes. Default 60, kept in step with the sandbox's ttlMinutes. */\n ttlMinutes?: number\n /** 'strict' (default): Daytona may reach the Veris gateway's address and\n * nothing else; everything the code dials goes through the gateway, which\n * answers vendor hostnames from the twin and passes registries and other\n * public hosts through. 'open': no Daytona allowlist — for a control plane\n * that has not published the gateway's addresses. Daytona blocks anything\n * that bypasses the proxy in both modes. */\n egress?: EgressMode\n /** Install the gateway CA into the sandbox trust store. Default true; without\n * it every HTTPS call to a vendor host fails certificate validation. */\n installCa?: boolean\n /** Inject { [env_hint]: dsn } for non-HTTP twin services. Default true. */\n dataPlaneEnv?: boolean\n /** Turn Veris off entirely for this create — a plain Daytona sandbox. */\n disabled?: boolean\n}\n\nexport interface VerisDaytonaConfig extends DaytonaConfig {\n veris?: VerisOpts\n}\n\ntype CreateParams = (CreateSandboxFromSnapshotParams | CreateSandboxFromImageParams) & { veris?: VerisOpts }\n\n/** Labels the class stamps so get() can rehydrate without re-asking. */\nconst LABEL = {\n twinId: 'veris_twin_id',\n envId: 'veris_env_id',\n apiBase: 'veris_api_base',\n mode: 'veris_mode',\n egress: 'veris_egress',\n ownsTwin: 'veris_owns_twin',\n canaryHost: 'veris_canary_host',\n /** Unique to ONE create() call, and the only way back to a sandbox whose\n * create threw before it could hand the object over — see reapFailedCreate.\n * The twin id will not do: an attached twin is shared by every sandbox on\n * it, and deleting the wrong one of those would be worse than the leak. */\n createId: 'veris_create_id',\n} as const\n\nconst VERIS_LABEL_KEYS: readonly string[] = Object.values(LABEL)\n\n/** A Daytona sandbox with the Veris surface attached. */\nexport type VerisSandbox = Sandbox & {\n /** Receipts, services, assertions. Everything Veris adds. */\n veris: VerisApi\n /** The Veris twin's id. Not to be confused with `sandbox.id`, the Daytona one. */\n verisSandboxId: string\n}\n\n/** Is this sandbox one of ours? Narrows for callers who hold a bare Sandbox. */\nexport function isVerisSandbox(sbx: Sandbox): sbx is VerisSandbox {\n return typeof (sbx as VerisSandbox).verisSandboxId === 'string'\n}\n\n/**\n * The twin id stamped on this sandbox at create, if it has one.\n *\n * Read from the labels rather than from `sandbox.verisSandboxId`, so it answers\n * for a sandbox whose Veris surface could NOT be rehydrated — no VERIS_API_KEY\n * in the environment, say. That is exactly the case where a caller about to\n * delete the sandbox needs telling that a twin exists and is out of reach.\n */\nexport function verisTwinId(sandbox: Sandbox): string | undefined {\n return sandbox.labels?.[LABEL.twinId]\n}\n\n/**\n * Does deleting this sandbox delete its twin too?\n *\n * True only for a twin this package created. A twin attached to with\n * `veris.attachSandboxId` belongs to whoever made it and outlives the sandbox,\n * and a sandbox with no twin at all has nothing to delete. This is the same\n * label the wrapped `delete()` reads, so the two can never disagree.\n */\nexport function verisOwnsTwin(sandbox: Sandbox): boolean {\n const labels = sandbox.labels ?? {}\n return labels[LABEL.twinId] !== undefined && labels[LABEL.ownsTwin] !== 'false'\n}\n\nexport class Daytona extends BaseDaytona {\n private readonly verisDefaults: VerisOpts\n\n constructor(config?: VerisDaytonaConfig) {\n super(config)\n this.verisDefaults = config?.veris ?? {}\n }\n\n // Both of the base class's overloads, redeclared so a caller passing either\n // params shape still type-checks against the subclass.\n override create(\n params?: CreateSandboxFromSnapshotParams & { veris?: VerisOpts },\n options?: { timeout?: number },\n ): Promise<Sandbox>\n override create(\n params?: CreateSandboxFromImageParams & { veris?: VerisOpts },\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox>\n override async create(\n params?: CreateParams,\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox> {\n const v: VerisOpts = { ...this.verisDefaults, ...(params?.veris ?? {}) }\n const rest = stripVeris(params)\n\n if (v.disabled) return this.baseCreate(rest, options)\n\n const coords = resolveCoordinates(v)\n const controlPlane = new ControlPlane({\n apiKey: coords.apiKey, apiBase: coords.apiBase, sdkVersion: SDK_VERSION,\n })\n const egress: EgressMode = v.egress ?? 'strict'\n const ttlMinutes = v.ttlMinutes ?? 60\n const ownsTwin = !v.attachSandboxId\n // Stamped on the sandbox in the same request that asks for it, so this\n // call can find what it made even when nothing was handed back.\n const createId = crypto.randomUUID()\n\n // 1. Provision the twin first: the allowlist needs the vendor hostnames it\n // answers for, and the egress credential is minted against it.\n const twin = await this.provisionTwin(controlPlane, v, coords, ttlMinutes)\n const cleanupTwin = async () => {\n if (ownsTwin) await controlPlane.deleteTwin(twin.environment_id, twin.id).catch(() => {})\n }\n\n let sandbox: Sandbox\n let credential\n let watermarks: Record<string, number> = {}\n // Everything before this line fails without Daytona having heard of us, so\n // there is nothing out there to reap and no call worth spending on looking.\n let daytonaAsked = false\n try {\n // 2. Mint the egress credential. Daytona accepts only http/https outbound\n // proxies, so a control plane that offers SOCKS alone cannot be used\n // here at all — say so plainly rather than failing later in TLS.\n credential = await controlPlane.mintEgressCredential(twin.environment_id, twin.id)\n if (!credential) {\n throw new VerisGatewayNotOfferedError(\n 'this Veris control plane does not offer egress credentials, so there is no gateway ' +\n 'for the sandbox to route through',\n { phase: 'credential-mint', verisSandboxId: twin.id })\n }\n if (!credential.connect_address && !credential.http_proxy_url) {\n throw new VerisGatewayNotOfferedError(\n 'the Veris gateway offers SOCKS5 but no HTTP CONNECT endpoint, and Daytona accepts ' +\n 'only http/https outbound proxies (\"Unsupported outbound proxy scheme\"). Upgrade the ' +\n 'control plane to one that returns connect_address.',\n { phase: 'credential-mint', verisSandboxId: twin.id })\n }\n\n const services = twin.services?.length ? twin.services : await controlPlane.services(twin.id)\n // Validated here, before it reaches Daytona.\n const proxyUrl = gatewayProxyUrl(credential)\n // Pinned to the gateway's ADDRESS, never a hostname list: a\n // domainAllowList beside the proxy URL turns Daytona's egress into a\n // TLS-inspecting proxy that rejects the gateway's leaf (see buildNetwork).\n const network = buildNetwork({ mode: egress, gatewayIps: await gatewayIps(credential, proxyUrl) })\n\n // Where each service's log stands BEFORE anything can have run in the\n // sandbox: the receipt counts from here, so an attached twin's earlier\n // traffic is not credited to this run.\n watermarks = await readWatermarks(services)\n\n // Veris-managed vars WIN over caller envs: a caller value for a\n // data-plane env_hint (e.g. DATABASE_URL) would silently point the code\n // under test at production.\n const verisManaged: Record<string, string> = {\n ...(v.installCa !== false ? sanitizeTrustEnv(undefined) : {}),\n // Node reads none of the variables above once Daytona has overwritten\n // them; the flag makes it read OpenSSL's store, which the CA install\n // fills. Appended, not replaced: a caller's own NODE_OPTIONS keep working.\n ...(v.installCa !== false ? { NODE_OPTIONS: nodeOptionsWithTrust(rest.envVars?.NODE_OPTIONS) } : {}),\n // Node ignores HTTPS_PROXY unless told to, and Daytona blocks anything\n // that dials out directly — so without this every plain `https.get`\n // and `fetch` in Node 24+ dies with ECONNRESET instead of reaching\n // the gateway. Older Node needs a proxy agent; the variable is inert there.\n NODE_USE_ENV_PROXY: '1',\n ...(v.dataPlaneEnv !== false ? dataPlaneEnv(services) : {}),\n VERIS_SANDBOX_ID: twin.id,\n }\n\n const createParams = {\n ...rest,\n envVars: { ...(rest.envVars ?? {}), ...verisManaged },\n labels: {\n ...reserveLabels(rest.labels),\n [LABEL.twinId]: twin.id,\n [LABEL.envId]: twin.environment_id,\n [LABEL.apiBase]: coords.apiBase,\n [LABEL.egress]: egress,\n [LABEL.ownsTwin]: String(ownsTwin),\n [LABEL.mode]: 'gateway',\n [LABEL.canaryHost]: credential.canary_host,\n [LABEL.createId]: createId,\n },\n ...network.params,\n // 3. Where Daytona forwards everything. Chained, not advisory: an\n // unreachable gateway makes traffic 502 rather than quietly going\n // direct.\n outboundProxyUrl: proxyUrl,\n ttlMinutes: rest.ttlMinutes ?? ttlMinutes,\n }\n\n daytonaAsked = true\n sandbox = await this.baseCreate(createParams as CreateParams, options)\n } catch (cause) {\n // Daytona has a sandbox from the moment it accepts the request, but the\n // SDK only hands one back once it has STARTED — so an image that fails\n // to build leaves a box behind in `build_failed` that nothing here ever\n // held a reference to. Reap it first: it also carries the only account\n // of what went wrong.\n const failed = daytonaAsked\n ? await reapFailedCreate((labels) => super.list({ labels }), createId)\n : undefined\n await cleanupTwin()\n if (cause instanceof VerisError) throw cause\n throw new VerisError(sandboxCreateMessage(cause, failed, rest as { image?: unknown }), {\n phase: 'sandbox-create', verisSandboxId: twin.id, cause })\n }\n\n // 4. Trust the gateway's CA, then prove the tunnel is live. Until the canary\n // answers, nothing about this sandbox is worth believing.\n try {\n await installCa(sandbox, credential.ca_pem)\n await probeCanary(sandbox, credential.canary_host, twin.id)\n } catch (err) {\n await sandbox.delete().catch(() => {})\n await cleanupTwin()\n throw err\n }\n\n return this.attach(sandbox, {\n controlPlane, environmentId: twin.environment_id, twinId: twin.id,\n egress, ownsTwin, canaryHost: credential.canary_host, watermarks,\n })\n }\n\n /**\n * Rehydrate the Veris surface on an existing sandbox.\n *\n * Not an optimisation — a necessity. The OpenCode plugin reconnects to a\n * sandbox with get() on every resumed session and deletes through get() too,\n * so a get() that returned a bare Sandbox would mean no receipts after any\n * restart and a leaked twin on every delete.\n */\n override async get(sandboxIdOrName: string): Promise<Sandbox> {\n const sandbox = await super.get(sandboxIdOrName)\n return this.rehydrate(sandbox)\n }\n\n /** Same rehydration for the sandboxes a list() streams. */\n override list(query?: ListSandboxesQuery): AsyncIterableIterator<Sandbox> {\n const inner = super.list(query)\n const rehydrate = (s: Sandbox) => this.rehydrate(s)\n return (async function* () {\n for await (const sandbox of inner) yield rehydrate(sandbox)\n })()\n }\n\n /**\n * Attach the Veris surface to a sandbox whose labels say it has a twin.\n * A sandbox without our labels is passed through untouched — callers can use\n * this client for ordinary Daytona work.\n */\n private rehydrate(sandbox: Sandbox): Sandbox {\n const labels = sandbox.labels ?? {}\n const twinId = labels[LABEL.twinId]\n if (!twinId) return sandbox\n\n // The same three layers create() reads — code, environment, the CLI's\n // login profile — so a sandbox made with a profile's key can be found\n // again with it.\n const creds = resolveVerisCredentials({ apiKey: this.verisDefaults.apiKey, apiBase: this.verisDefaults.apiBase })\n const apiKey = creds.apiKey\n if (!apiKey) return sandbox // no key: no Veris surface, but not an error\n\n // A trusted source decides where the API key is sent — NEVER the sandbox\n // labels, which a compromised sandbox could rewrite to exfiltrate the key.\n // The profile file counts as one: it is the user's own, mode 0600.\n const trustedBase = creds.baseSource === 'default' ? undefined : creds.apiBase\n const labelBase = labels[LABEL.apiBase]\n if (trustedBase && labelBase && labelBase !== trustedBase) {\n throw new VerisError(\n `sandbox ${sandbox.id} labels name a different Veris control plane (${labelBase}) than ` +\n `your configuration (${trustedBase}) — refusing to send the API key to an unverified host`,\n { phase: 'attach' })\n }\n const apiBase = trustedBase ?? labelBase ?? 'https://svc.api.veris.ai'\n\n return this.attach(sandbox, {\n controlPlane: new ControlPlane({ apiKey, apiBase, sdkVersion: SDK_VERSION }),\n environmentId: labels[LABEL.envId] ?? '',\n twinId,\n // Re-minted below when a receipt is actually asked for; the label only\n // has to survive the reconnect.\n canaryHost: labels[LABEL.canaryHost] ?? '',\n egress: (labels[LABEL.egress] as EgressMode | undefined) ?? 'strict',\n ownsTwin: labels[LABEL.ownsTwin] !== 'false',\n })\n }\n\n private async provisionTwin(\n controlPlane: ControlPlane, v: VerisOpts, coords: ResolvedCoordinates, ttlMinutes: number,\n ): Promise<TwinSandbox> {\n if (v.attachSandboxId) {\n const existing = await controlPlane.getTwin(v.attachSandboxId)\n if (!existing) {\n throw new VerisError(`attach target ${v.attachSandboxId} not found`, {\n phase: 'twin-provision', verisSandboxId: v.attachSandboxId })\n }\n return existing.status === 'ready' ? existing : controlPlane.waitReady(v.attachSandboxId, 240_000)\n }\n if (!coords.environmentId) {\n throw new MissingCredentialsError(\n 'no Veris environment: set VERIS_ENVIRONMENT_ID, or pass veris.environmentId',\n { phase: 'credentials' })\n }\n const created = await controlPlane.createTwin(coords.environmentId, { ttlMinutes })\n try {\n return await controlPlane.waitReady(created.id, 240_000)\n } catch (e) {\n await controlPlane.deleteTwin(coords.environmentId, created.id).catch(() => {})\n throw e\n }\n }\n\n /**\n * Hang the Veris surface off the instance, and wrap delete() so teardown is\n * automatic.\n *\n * Wrapping rather than asking callers to remember is the point: the OpenCode\n * plugin's existing `sandbox.delete()` then removes the twin too, with no\n * change to the plugin at all. A twin outlives its sandbox otherwise, until\n * its TTL reaps it — invisible until the bill arrives.\n */\n private attach(sandbox: Sandbox, ctx: Omit<VerisContext, 'sandbox'>): Sandbox {\n // Attaching twice would capture our own wrapper as `originalDelete` and\n // tear the twin down twice. Only the prototype's delete is ever wrapped.\n if (isVerisSandbox(sandbox)) return sandbox\n\n const veris = new VerisApiImpl({ ...ctx, sandbox })\n const originalDelete = sandbox.delete.bind(sandbox)\n\n Object.defineProperties(sandbox, {\n veris: { value: veris, enumerable: true, configurable: true },\n verisSandboxId: { value: ctx.twinId, enumerable: true, configurable: true },\n delete: {\n configurable: true,\n value: async (timeout?: number, wait?: boolean): Promise<void> => {\n // Drop the twin before the container goes. Nothing to stop inside\n // the sandbox — the gateway is ours and host-side.\n if (ctx.ownsTwin) {\n await ctx.controlPlane.deleteTwin(ctx.environmentId, ctx.twinId).catch(() => {})\n }\n return originalDelete(timeout, wait)\n },\n },\n })\n return sandbox\n }\n\n /** super.create through the overload the params actually match. */\n private baseCreate(\n params: CreateParams | undefined,\n options?: { onSnapshotCreateLogs?: (chunk: string) => void; timeout?: number },\n ): Promise<Sandbox> {\n type Create = (p?: CreateParams, o?: typeof options) => Promise<Sandbox>\n return (super.create as unknown as Create).call(this, params, options)\n }\n}\n\nexport default Daytona\n\ninterface ResolvedCoordinates {\n apiKey: string\n environmentId?: string\n apiBase: string\n}\n\n/**\n * Key and base from code, the environment, or the CLI's login profile, in that\n * order (profile.ts). Throws MissingCredentialsError naming every place a key\n * could have come from when none has one.\n */\nfunction resolveCoordinates(v: VerisOpts): ResolvedCoordinates {\n const creds = requireVerisCredentials({ apiKey: v.apiKey, apiBase: v.apiBase })\n return {\n apiKey: creds.apiKey,\n environmentId: v.environmentId ?? process.env.VERIS_ENVIRONMENT_ID,\n apiBase: creds.apiBase,\n }\n}\n\n/** What a create that threw left behind in Daytona, once it has been read back. */\nexport interface FailedSandbox {\n /** The DAYTONA sandbox id. Not the twin's. */\n id: string\n /** Daytona's own state for it — `build_failed` for an image that never built. */\n state?: string\n /** Daytona's account of what went wrong, when it kept one. */\n errorReason?: string\n /** Whether the delete actually went through. The message says either way,\n * because \"was deleted\" has to be true or it is worse than saying nothing. */\n deleted: boolean\n}\n\n/** The parts of a Daytona Sandbox the reaper touches. */\ninterface ReapableSandbox {\n id: string\n state?: string\n errorReason?: string\n labels?: Record<string, string>\n refreshData(): Promise<void>\n delete(): Promise<void>\n}\n\n/**\n * Delete the half-built sandbox a failed create() left in Daytona, and bring\n * back the reason Daytona recorded for it.\n *\n * The leak this exists for: `create({ image: 'only-on-my-laptop' })` builds\n * server-side and fails at build time, so the SDK throws instead of returning\n * a Sandbox — and a box sits in `build_failed` that nothing here can delete,\n * until an autoDeleteInterval eventually reaps it. Found by the create id\n * stamped in its labels, which is the one thing about it we know for certain.\n *\n * Best effort throughout: the create is already failing, and a reaper that\n * threw would replace the real reason with its own.\n */\nexport async function reapFailedCreate(\n list: (labels: Record<string, string>) => AsyncIterable<ReapableSandbox>,\n createId: string,\n): Promise<FailedSandbox | undefined> {\n try {\n for await (const sandbox of list({ [LABEL.createId]: createId })) {\n // Checked again on our side. A server-side filter that came back wider\n // than it was asked for must not turn into a delete of someone else's\n // sandbox — the one failure mode worse than the leak.\n if (sandbox.labels?.[LABEL.createId] !== createId) continue\n // The list row carries errorReason, but a row read the instant a build\n // failed can still be without one; one more fetch settles it. A failed\n // create is not a hot path.\n if (!sandbox.errorReason) await sandbox.refreshData().catch(() => {})\n const found = { id: sandbox.id, state: sandbox.state, errorReason: sandbox.errorReason }\n return { ...found, deleted: await sandbox.delete().then(() => true, () => false) }\n }\n } catch {\n // A list that cannot be read tells us nothing; the create's own error stands.\n }\n return undefined\n}\n\n/**\n * What a failed create says.\n *\n * Two things were missing from \"Daytona sandbox create failed: Sandbox 7ba4…\n * failed to start with status: build_failed, error reason: null\".\n *\n * The reason, first. Daytona's SDK renders `error reason: ${this.errorReason}`\n * off the Sandbox object it was polling, and the state change that ends the\n * wait arrives over the event stream, which carries the new state and not the\n * reason — so the field is still the null it started as, while Daytona's own\n * record for that sandbox says \"pull access denied, repository does not\n * exist\". Reading the record back is the whole fix.\n *\n * And, for the failure a first-timer actually hits, whose image it is. Daytona\n * resolves and builds it on its own machines, from a registry; the tag sitting\n * in the laptop's Docker daemon is not something it can see.\n *\n * The cause's own text is folded in HERE rather than left to VerisError, whose\n * fold would otherwise append it after the sentences that explain it.\n */\nexport function sandboxCreateMessage(\n cause: unknown,\n failed: FailedSandbox | undefined,\n params: { image?: unknown } = {},\n): string {\n const base = 'Daytona sandbox create failed'\n // Nothing was made, so there is nothing to add: the cause is the story, and\n // VerisError folds it in.\n if (!failed) return base\n\n const reason = failed.errorReason?.trim().replace(/[.\\s]+$/, '')\n const parts = [reason ? `${base}: ${reason}.` : `${base}.`]\n\n const image = typeof params.image === 'string' ? params.image : undefined\n if (image && failed.state === 'build_failed') {\n parts.push(\n `Daytona builds \"${image}\" on its own servers and pulls it from a registry, so an image ` +\n 'that exists only in your local Docker daemon is not one it can see.')\n }\n parts.push(failed.deleted\n ? `The half-built sandbox ${failed.id} was deleted.`\n : `The half-built sandbox ${failed.id} could not be deleted — remove it with ` +\n `\\`veris-daytona teardown ${failed.id}\\`.`)\n\n const raw = cause instanceof Error ? cause.message : ''\n if (raw) parts.push(`(Daytona SDK: ${raw})`)\n return parts.join(' ')\n}\n\n/**\n * Each service's newest request id right now, keyed by service name.\n *\n * Best-effort per service, on purpose: a mark that cannot be read falls back\n * to 0, which reads the whole log — the behaviour the receipt had before\n * watermarks existed. A twin whose log is briefly unreadable must not be a\n * failed create().\n */\nasync function readWatermarks(services: ServiceInfo[]): Promise<Record<string, number>> {\n const marks = await Promise.all(\n services.filter((s) => isHttpUrl(s.control_url)).map(async (svc) =>\n [svc.name, await fetchWatermark(svc).catch(() => 0)] as const))\n return Object.fromEntries(marks)\n}\n\nfunction stripVeris(params: CreateParams | undefined): Omit<CreateParams, 'veris'> {\n const { veris: _veris, ...rest } = params ?? {}\n return rest\n}\n\n/** Strip any Veris-reserved keys a caller tried to set in labels. */\nfunction reserveLabels(labels: Record<string, string> | undefined): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [k, val] of Object.entries(labels ?? {})) {\n if (!VERIS_LABEL_KEYS.includes(k)) out[k] = val\n }\n return out\n}\n\nexport { CA_CERT_PATH }\n","/**\n * Every failure phase a Veris error can name. Bring-up spans four systems\n * (control plane, Daytona API, the sandbox, the Veris gateway), so errors\n * carry a structured phase rather than a wall of logs.\n */\nexport type VerisErrorPhase =\n | 'credentials'\n | 'twin-provision'\n | 'gateway-preflight'\n | 'credential-mint'\n | 'sandbox-create'\n | 'ca-install'\n | 'canary'\n | 'receipt'\n | 'twin-state'\n | 'attach'\n\n/**\n * Base class for every error this package throws. Deliberately NOT a subclass\n * of any Daytona error: `e instanceof VerisError` cleanly separates Veris\n * failures from Daytona failures in one catch.\n */\n/**\n * Fold the wrapped error's own message into ours.\n *\n * `cause` is preserved either way, but almost nothing that shows an error to a\n * human walks the cause chain -- OpenCode prints `err.message` and stops. So\n * \"Daytona sandbox create failed\" was all anyone saw for what was really\n * \"Invalid credentials\": a message that says a thing went wrong and refuses to\n * say why, which is the most expensive kind of error to be handed.\n */\nfunction withCause(message: string, cause: unknown): string {\n const detail =\n cause instanceof Error ? cause.message : typeof cause === 'string' ? cause : ''\n // Already said, or nothing to add.\n if (!detail || message.includes(detail)) return message\n const trimmed = detail.length > 200 ? `${detail.slice(0, 200)}…` : detail\n return `${message}: ${trimmed}`\n}\n\nexport class VerisError extends Error {\n readonly phase?: VerisErrorPhase\n /** The Veris twin's sandbox id, when one exists yet. */\n readonly verisSandboxId?: string\n /** Verbatim control-plane response body, when the failure came from an API call. */\n readonly responseBody?: unknown\n\n constructor(\n message: string,\n opts: { phase?: VerisErrorPhase; verisSandboxId?: string; responseBody?: unknown; cause?: unknown } = {},\n ) {\n super(withCause(message, opts.cause), opts.cause !== undefined ? { cause: opts.cause } : undefined)\n this.name = new.target.name\n this.phase = opts.phase\n this.verisSandboxId = opts.verisSandboxId\n this.responseBody = opts.responseBody\n }\n}\n\n/** A required credential/coordinate is missing. Thrown before any network call, naming the exact variable. */\nexport class MissingCredentialsError extends VerisError {}\n\n/** The Veris gateway infrastructure is down (control-plane health said so). */\nexport class VerisGatewayUnreachableError extends VerisError {}\n\n/** The control plane does not offer gateway mode (endpoint absent, or this SDK version is below min_sdk). */\nexport class VerisGatewayNotOfferedError extends VerisError {\n /** Server-announced minimum SDK version, when the refusal carried one. */\n readonly minSdk?: string\n constructor(message: string, opts: ConstructorParameters<typeof VerisError>[1] & { minSdk?: string } = {}) {\n super(message, opts)\n this.minSdk = opts.minSdk\n }\n}\n\n/** The canary probe failed: egress is not (or no longer) reaching the twin. */\nexport class ReceiptIntegrityError extends VerisError {}\n\n/** assertTouched(): the named service saw zero intercepted requests — green without the receipt. */\nexport class VerisUntouchedError extends VerisError {\n readonly service: string\n constructor(message: string, service: string, opts: ConstructorParameters<typeof VerisError>[1] = {}) {\n super(message, opts)\n this.service = service\n }\n}\n\n/** The Daytona sandbox is alive but its Veris twin is gone (TTL expiry, delete, reset). */\nexport class TwinExpiredError extends VerisError {}\n\n/** The sandbox image cannot host the Veris layer — in practice, no\n * ca-certificates, so the gateway CA cannot be trusted. */\nexport class SnapshotUnsupportedError extends VerisError {}\n\n/** An inherited Daytona operation that would break the one-sandbox-one-twin invariant (e.g. fork). */\nexport class UnsupportedOperationError extends VerisError {}\n","// Typed client for the Veris control plane (svc.api.veris.ai). Only the routes\n// the SDK needs; shapes mirror the platform's public models.\nimport { VerisError, VerisGatewayNotOfferedError, VerisGatewayUnreachableError, TwinExpiredError } from './errors'\n\nexport interface RouteEntry {\n /** A real vendor hostname the service answers for. */\n host: string\n /** Path prefixes narrowing the claim when several services share the host. */\n paths?: string[] | null\n}\n\nexport interface ServiceInfo {\n name: string\n status: string\n /** What the code under test points at: gateway URL for http services, a DSN for e.g. postgres. */\n url: string\n /** Where /veris/* lives — always an http URL. */\n control_url: string\n env_hint?: string | null\n routes?: RouteEntry[] | null\n}\n\nexport interface TwinSandbox {\n id: string\n environment_id: string\n status: 'provisioning' | 'ready' | 'failed' | 'degraded' | 'terminating' | string\n created_at?: string | null\n expires_at?: string | null\n services: ServiceInfo[]\n failure_reason?: string | null\n metadata?: Record<string, string>\n}\n\n/** Response of POST /v1/sandboxes/{sid}/egress-credential (gateway mode). */\nexport interface EgressCredential {\n /** SOCKS5 endpoint. What @veris-ai/e2b uses; Daytona cannot (it accepts only\n * http/https outbound proxies). */\n socks_address: string\n /** HTTP CONNECT endpoint, host:port. Absent on a control plane that predates\n * the CONNECT listener — which is a hard error here, since Daytona has no\n * other way to reach the gateway. */\n connect_address?: string\n /** The CONNECT endpoint as a complete proxy URL, credentials included.\n * Preferred over building one from connect_address: the gateway owns its own\n * auth format, and guessing it is how you end up sending the wrong password. */\n http_proxy_url?: string\n username: string\n password: string\n ca_pem: string\n canary_host: string\n min_sdk?: string\n expires_at?: string\n /** Server-served CA trust env map; the SDK's vendored list is the fallback. */\n trust_env?: Record<string, string>\n /** IPv4 addresses the gateway listens on — what strict mode pins Daytona's\n * networkAllowList to. Absent on a control plane that predates the field;\n * the SDK then resolves the proxy host itself, once. */\n gateway_ips?: string[]\n}\n\n/**\n * Mutable fields of a running twin. An OMITTED key is left alone; an explicit\n * null is a value (client_base_url: null unregisters).\n *\n * There is deliberately no ttl_minutes. The server's UpdateSandboxRequest\n * declares client_base_url and nothing else, and pydantic ignores unknown\n * fields rather than refusing them — so a PATCH carrying a TTL answers 200 and\n * changes nothing. See the note where extendTtl used to be.\n */\nexport interface SandboxPatch {\n client_base_url?: string | null\n}\n\nexport interface ControlPlaneOpts {\n apiKey: string\n apiBase: string\n /** Sent as X-Veris-SDK on every request, so the server can version-gate. */\n sdkVersion: string\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms))\n\nexport class ControlPlane {\n readonly apiBase: string\n private readonly headers: Record<string, string>\n\n constructor(opts: ControlPlaneOpts) {\n this.apiBase = opts.apiBase.replace(/\\/$/, '')\n this.headers = {\n 'X-API-Key': opts.apiKey,\n 'X-Veris-SDK': opts.sdkVersion,\n 'Content-Type': 'application/json',\n }\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<Response> {\n let res: Response\n try {\n res = await fetch(`${this.apiBase}${path}`, {\n method,\n headers: this.headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (cause) {\n throw new VerisError(`Veris control plane unreachable (${method} ${path})`, { cause })\n }\n return res\n }\n\n private async json<T>(res: Response, context: string, phase?: import('./errors').VerisErrorPhase): Promise<T> {\n const text = await res.text()\n let parsed: unknown\n try { parsed = text ? JSON.parse(text) : undefined } catch { parsed = text }\n if (!res.ok) {\n throw new VerisError(`${context}: ${res.status}`, { phase, responseBody: parsed })\n }\n // A success with no body would surface downstream as an opaque\n // \"cannot read properties of undefined\" — turn it into a legible error here.\n if (parsed === undefined) {\n throw new VerisError(`${context}: empty response body`, { phase, responseBody: text })\n }\n return parsed as T\n }\n\n async createTwin(environmentId: string, opts: { ttlMinutes?: number; metadata?: Record<string, string> } = {}): Promise<TwinSandbox> {\n const res = await this.request('POST', `/v1/environments/${environmentId}/sandboxes`, {\n ttl_minutes: opts.ttlMinutes,\n metadata: opts.metadata,\n })\n // A 404 here is almost never a missing endpoint: environments are scoped to\n // one control plane, so the usual cause is an id from a DIFFERENT one --\n // a prod VERIS_ENVIRONMENT_ID against a dev VERIS_API_BASE, or the reverse.\n // The bare \"404\" sends people to check their key, which is fine, and their\n // network, which is fine, before they think to check the pairing.\n if (res.status === 404) {\n throw new VerisError(\n `environment '${environmentId}' does not exist on ${this.apiBase}. Environments belong ` +\n 'to one control plane: check that VERIS_ENVIRONMENT_ID and VERIS_API_BASE name the same ' +\n 'one (an id from the other environment gives exactly this 404).',\n { phase: 'twin-provision', responseBody: await res.text() })\n }\n return this.json<TwinSandbox>(res, `create sandbox in environment ${environmentId}`, 'twin-provision')\n }\n\n async getTwin(sandboxId: string): Promise<TwinSandbox | null> {\n const res = await this.request('GET', `/v1/sandboxes/${sandboxId}`)\n if (res.status === 404) return null\n return this.json<TwinSandbox>(res, `get sandbox ${sandboxId}`)\n }\n\n /** Poll until the twin reports ready. \"failed\" is terminal per the API docs. */\n async waitReady(sandboxId: string, timeoutMs: number): Promise<TwinSandbox> {\n const deadline = Date.now() + timeoutMs\n for (;;) {\n const twin = await this.getTwin(sandboxId)\n if (!twin) throw new TwinExpiredError(`Veris sandbox ${sandboxId} disappeared while provisioning`, { verisSandboxId: sandboxId })\n if (twin.status === 'ready') return twin\n if (twin.status === 'failed') {\n throw new VerisError(\n `Veris sandbox ${sandboxId} failed to provision: ${twin.failure_reason ?? 'no failure_reason'}`,\n { phase: 'twin-provision', verisSandboxId: sandboxId })\n }\n if (Date.now() > deadline) {\n throw new VerisError(\n `Veris sandbox ${sandboxId} not ready after ${timeoutMs}ms (status: ${twin.status})`,\n { phase: 'twin-provision', verisSandboxId: sandboxId })\n }\n await sleep(1500)\n }\n }\n\n async services(sandboxId: string): Promise<ServiceInfo[]> {\n const res = await this.request('GET', `/v1/sandboxes/${sandboxId}/services`)\n if (res.status === 404) {\n throw new TwinExpiredError(`Veris sandbox ${sandboxId} not found — expired or deleted`, { verisSandboxId: sandboxId })\n }\n return this.json<ServiceInfo[]>(res, `services of sandbox ${sandboxId}`, 'receipt')\n }\n\n async deleteTwin(environmentId: string, sandboxId: string): Promise<boolean> {\n const res = await this.request('DELETE', `/v1/environments/${environmentId}/sandboxes/${sandboxId}`)\n if (res.status === 404) return false\n if (!res.ok) await this.json(res, `delete sandbox ${sandboxId}`)\n return true\n }\n\n /**\n * Mint (or re-mint) the gateway egress credential for a twin. Returns null\n * when the control plane does not offer gateway mode at all (404 — route\n * absent), so `mode: 'auto'` can fall back; throws VerisGatewayNotOfferedError\n * on an explicit version refusal (409 sdk_too_old).\n */\n async mintEgressCredential(environmentId: string, sandboxId: string): Promise<EgressCredential | null> {\n const res = await this.request('POST', `/v1/environments/${environmentId}/sandboxes/${sandboxId}/egress-credential`)\n if (res.status === 404) return null\n if (res.status === 409) {\n const body = await res.json().catch(() => ({})) as { min_sdk?: string }\n throw new VerisGatewayNotOfferedError(\n `this SDK version is below the control plane's minimum for gateway mode${body.min_sdk ? ` (min_sdk ${body.min_sdk})` : ''} — upgrade @veris-ai/daytona`,\n { phase: 'credential-mint', verisSandboxId: sandboxId, minSdk: body.min_sdk, responseBody: body })\n }\n return this.json<EgressCredential>(res, `mint egress credential for ${sandboxId}`, 'credential-mint')\n }\n\n /** PATCH the twin resource. Omitted fields are untouched by the server. */\n async updateSandbox(environmentId: string, sandboxId: string, patch: SandboxPatch): Promise<void> {\n const res = await this.request('PATCH', `/v1/environments/${environmentId}/sandboxes/${sandboxId}`, patch)\n if (res.status === 404) {\n throw new TwinExpiredError(`Veris sandbox ${sandboxId} not found`, { verisSandboxId: sandboxId })\n }\n if (!res.ok) await this.json(res, `update sandbox ${sandboxId}`)\n }\n\n // There was an extendTtl() here, and it did nothing.\n //\n // It PATCHed { ttl_minutes } at the sandbox resource, and the server's\n // UpdateSandboxRequest declares only client_base_url. Pydantic ignores\n // unknown fields, so the route answered 200 having changed no TTL at all —\n // a call that reports success while doing nothing, which is worse than no\n // call, because the caller then believes the twin will outlive the run.\n // Nothing here called it; it was API surface promising a thing that could\n // not happen.\n //\n // Bring it back when a route exists to carry it. Until then a twin's TTL is\n // decided once, by ttl_minutes at create — where this SDK already keeps it\n // in step with the Daytona sandbox's own ttlMinutes.\n\n /** Create-time preflight: is the gateway infrastructure up, per the control plane? */\n async gatewayHealth(): Promise<void> {\n const res = await this.request('GET', '/v1/gateway/health')\n if (res.status === 404) return // control plane predates gateway mode; the credential probe decides\n if (!res.ok) {\n throw new VerisGatewayUnreachableError(\n `Veris gateway reported unhealthy (${res.status})`, { phase: 'gateway-preflight' })\n }\n }\n}\n","// A unique, read-only control request anchors history even across resets\n// that preserve numeric ids. No server generation endpoint is assumed.\nimport { randomUUID } from 'node:crypto'\nimport { VerisError } from './errors'\nimport type { ServiceInfo } from './control-plane'\nimport { readPage } from './receipt'\n\nexport interface ReceiptBaseline {\n version: 1\n twinId: string\n sandboxId: string\n services: Record<string, { controlUrl: string; id: number; marker: string }>\n}\nconst HEADER = 'x-veris-receipt-baseline'\nfunction markerOf(row: { [key: string]: unknown }): unknown {\n try {\n const headers = typeof row.request_headers === 'string' ? JSON.parse(row.request_headers) : row.request_headers\n return headers?.[HEADER]\n } catch { return undefined }\n}\n\nexport async function captureBaseline(twinId: string, sandboxId: string, services: ServiceInfo[]): Promise<ReceiptBaseline> {\n const marks = await Promise.all(services.map(async svc => {\n const marker = randomUUID()\n const res = await fetch(`${svc.control_url.replace(/\\/$/, '')}/veris/schema`, {\n headers: { [HEADER]: marker }, signal: AbortSignal.timeout(30_000), redirect: 'error',\n })\n await res.text()\n if (!res.ok) throw new VerisError(`could not establish baseline for '${svc.name}' (${res.status})`, { phase: 'receipt' })\n // Trace middleware commits after sending the response. A bounded retry\n // accommodates that commit without accepting an absent/ambiguous anchor.\n for (let attempt = 0; attempt < 5; attempt++) {\n const rows = await readPage(svc, new URLSearchParams({ limit: '1000', order: 'desc' }))\n const anchor = rows.find(r => markerOf(r) === marker && r.tier === 'control' && r.path === '/veris/schema')\n if (anchor) return [svc.name, { controlUrl: svc.control_url, id: anchor.id, marker }] as const\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n throw new VerisError(`baseline unavailable for '${svc.name}': trace must retain control request headers`, { phase: 'receipt' })\n }))\n return { version: 1, twinId, sandboxId, services: Object.fromEntries(marks) }\n}\n\nexport async function validateBaseline(baseline: ReceiptBaseline, twinId: string, sandboxId: string, services: ServiceInfo[]): Promise<void> {\n const invalid = () => new VerisError('receipt baseline invalid: session, services or history changed; take a new baseline before execution', { phase: 'receipt' })\n if (baseline.version !== 1 || baseline.twinId !== twinId || baseline.sandboxId !== sandboxId ||\n Object.keys(baseline.services).sort().join('\\0') !== services.map(s => s.name).sort().join('\\0')) throw invalid()\n await Promise.all(services.map(async svc => {\n const mark = baseline.services[svc.name]\n if (!mark || mark.controlUrl !== svc.control_url || !Number.isSafeInteger(mark.id) || mark.id <= 0) throw invalid()\n const rows = await readPage(svc, new URLSearchParams({ limit: '1', order: 'asc', since_id: String(mark.id - 1) }))\n if (rows.length !== 1 || rows[0]!.id !== mark.id || markerOf(rows[0]!) !== mark.marker) throw invalid()\n }))\n}\n","// The receipt: what the twin actually received, parsed from each service's\n// /veris/requests log — plus the integrity probe that keeps it honest.\n//\n// Two things the log does not hand over for free, and both change the number:\n//\n// the page GET /veris/requests defaults to limit=50 and caps it at\n// 1000. Asking with no query string is asking for 50, so a run\n// that made 200 calls reported 50 and said nothing about it.\n// Read here in pages of 1000 until the log runs out.\n// the watermark A twin that was ATTACHED rather than freshly created already\n// has a log. Counting all of it credits this run with traffic\n// from before it began, so the read starts at a mark taken\n// when the run did — see fetchWatermark.\nimport { VerisError } from './errors'\nimport type { ServiceInfo } from './control-plane'\n\n/** One intercepted request, from the twin's trace log. */\nexport interface ReceiptRequest {\n /** Row id. Monotonic per service, and what a later read resumes from. */\n id: number\n method: string\n path: string\n /** null = no response sent (fault hang). */\n status: number | null\n tier: string\n}\n\nexport interface ReceiptEntry {\n /** Vendor-surface requests the twin received since the watermark. A floor,\n * not a count, when `capped` is set. */\n requests: number\n /** The twin service's /veris/* control plane. */\n controlUrl: string\n /** Typed request list, newest first. */\n entries: ReceiptRequest[]\n /** The read stopped before the log did, so `requests` is \"at least this\n * many\". Never silent: a count that is quietly a floor is exactly the bug\n * this replaced. */\n capped: boolean\n /** Present when this is only a lower bound. */\n incompleteReason?: string\n sinceId?: number\n untilId?: number\n /** The /veris/requests rows read, verbatim as served, merged across pages. */\n raw: unknown\n}\n\nexport type ReceiptLeak = 'udp-quic-possible' | 'ech-possible'\n\nexport interface Receipt {\n /** Keyed by service name. Partial: indexing an absent service is a type\n * error to handle, not a runtime TypeError to discover. */\n services: Partial<Record<string, ReceiptEntry>>\n /** How the traffic was moved. One tier now: the Veris gateway. */\n mode: 'gateway'\n /** 'verified' iff the canary probe confirmed egress is still tunnelled\n * through the gateway and demuxed to THIS twin. */\n integrity: 'verified'\n /** Known blind spots of THIS receipt. */\n leaks: ReceiptLeak[]\n}\n\nexport interface RawRow extends ReceiptRequest {\n [key: string]: unknown\n}\nconst PAGE_LIMIT = 1000\nconst MAX_PAGES = 20\n\n/** Malformed reads are failures, never successful empty evidence. */\nexport function rowsOf(body: unknown): RawRow[] {\n if (!body || !Array.isArray((body as { requests?: unknown }).requests)) {\n throw new VerisError('invalid request log: expected requests array', { phase: 'receipt' })\n }\n const rows = (body as { requests: RawRow[] }).requests\n for (const r of rows) {\n if (!r || !Number.isSafeInteger(r.id) || r.id <= 0 || typeof r.method !== 'string' ||\n typeof r.path !== 'string' || typeof r.tier !== 'string' ||\n !(r.status === null || typeof r.status === 'number')) {\n throw new VerisError('invalid request log row: stable id, method, path, tier and status required', { phase: 'receipt' })\n }\n }\n return rows\n}\n\nexport function parseRequestsBody(body: unknown): { count: number; entries: ReceiptRequest[]; total: number } {\n const rows = rowsOf(body)\n const entries = rows.filter(r =>\n ['handler', 'fault', 'fallback', 'fallback-llm', 'fallback-replay'].includes(r.tier) &&\n !/^\\/veris(?:\\/|$)/.test(r.path)\n ).map(({ id, method, path, status, tier }) => ({ id, method, path, status, tier }))\n return { count: entries.length, entries, total: rows.length }\n}\n\nexport async function readPage(svc: ServiceInfo, query: URLSearchParams): Promise<RawRow[]> {\n const res = await fetch(`${svc.control_url.replace(/\\/$/, '')}/veris/requests?${query}`, {\n signal: AbortSignal.timeout(30_000), redirect: 'error',\n })\n const text = await res.text()\n if (!res.ok) throw new VerisError(`could not read receipt for service '${svc.name}' (${res.status})`, { phase: 'receipt' })\n let body: unknown\n try { body = JSON.parse(text) } catch {\n throw new VerisError(`service '${svc.name}' returned a non-JSON receipt body`, { phase: 'receipt' })\n }\n return rowsOf(body)\n}\n\nexport async function fetchWatermark(svc: ServiceInfo): Promise<number> {\n const rows = await readPage(svc, new URLSearchParams({ limit: '1', order: 'desc' }))\n if (rows.length > 1) throw new VerisError('request log ignored watermark limit', { phase: 'receipt' })\n return rows[0]?.id ?? 0\n}\n\n/** Read a finite window. The newest-id snapshot also detects servers that\n * silently cap pages below our requested limit. Never subtract row counts. */\nexport async function fetchReceiptEntry(svc: ServiceInfo, sinceId = 0): Promise<ReceiptEntry> {\n if (!Number.isSafeInteger(sinceId) || sinceId < 0) throw new VerisError('invalid receipt watermark', { phase: 'receipt' })\n const end = await fetchWatermark(svc)\n if (end < sinceId) throw new VerisError('receipt baseline invalid: log moved backwards; take a new baseline', { phase: 'receipt' })\n const entries: ReceiptRequest[] = []\n const raw: RawRow[] = []\n let mark = sinceId\n let incompleteReason: string | undefined\n for (let page = 0; mark < end; page++) {\n if (page >= MAX_PAGES) { incompleteReason = 'page-limit'; break }\n let rows: RawRow[]\n try {\n rows = await readPage(svc, new URLSearchParams({ limit: String(PAGE_LIMIT), order: 'asc', since_id: String(mark) }))\n } catch (error) {\n if (!raw.length) throw error\n incompleteReason = 'read-failed'; break\n }\n // Duplicate/backwards rows or an ignored cursor/order mean there may be\n // hidden entries. Do not credit that page or call its count exact.\n let previous = mark\n if (!rows.length || rows.some(r => { const bad = r.id <= previous; previous = r.id; return bad })) {\n incompleteReason = 'pagination-not-progressing'; break\n }\n const window = rows.filter(r => r.id <= end)\n raw.push(...window)\n entries.push(...parseRequestsBody({ requests: window }).entries)\n mark = rows[rows.length - 1]!.id\n }\n entries.sort((a, b) => b.id - a.id)\n return { requests: entries.length, controlUrl: svc.control_url, entries,\n sinceId, untilId: end, capped: Boolean(incompleteReason), ...(incompleteReason ? { incompleteReason } : {}), raw: { requests: raw } }\n}\n","// Resolve only advertised services and fixed control resources. Lifecycle and\n// arbitrary URLs are deliberately absent; the plugin owns the attached twin.\nimport type { ServiceInfo } from './control-plane'\nimport { VerisError } from './errors'\nexport type ControlResource = 'manual' | 'schema' | 'operations' | 'data' | 'requests'\nexport interface ControlOptions {\n method?: 'GET' | 'POST' | 'PATCH'\n query?: Record<string, string>\n body?: unknown\n}\nexport async function serviceControl(svc: ServiceInfo, resource: ControlResource, options: ControlOptions = {}): Promise<unknown> {\n const method = options.method ?? 'GET'\n if (!['manual', 'schema', 'operations', 'data', 'requests'].includes(resource) ||\n !['GET', 'POST', 'PATCH'].includes(method) || (method !== 'GET' && resource !== 'data') ||\n (method === 'GET' && options.body !== undefined) || !/^https?:\\/\\//.test(svc.control_url)) {\n throw new VerisError('unsupported service control operation')\n }\n const url = new URL(`${svc.control_url.replace(/\\/$/, '')}/veris/${resource}`)\n for (const [key, value] of Object.entries(options.query ?? {})) url.searchParams.set(key, value)\n const res = await fetch(url, { method, redirect: 'error', signal: AbortSignal.timeout(30_000),\n headers: { 'Content-Type': 'application/json' },\n body: options.body === undefined ? undefined : JSON.stringify(options.body) })\n const text = await res.text()\n if (!res.ok) throw new VerisError(`service '${svc.name}' ${method} /veris/${resource} failed (${res.status})`)\n try { return JSON.parse(text) } catch { throw new VerisError(`service '${svc.name}' returned invalid control JSON`) }\n}\n","// Builds the Daytona network params.\n//\n// networkAllowList the Veris gateway's IPv4 address(es), one /32 each, and\n// nothing else. Enforced at Daytona's runner: a process\n// that ignores the proxy variables cannot dial out at all.\n// outboundProxyUrl where Daytona forwards everything: the gateway, which\n// answers vendor hostnames from the twin and passes public\n// hosts (registries, git) through untouched.\n//\n// Together those two are the whole mechanism. Daytona never sees a hostname\n// list — see buildNetwork for why that is load-bearing, not a simplification.\nimport type { ServiceInfo } from './control-plane'\nimport { VerisError } from './errors'\n\nexport type EgressMode = 'strict' | 'open'\n\n/** A service whose `url` is an HTTP endpoint (vs a wire-protocol DSN). */\nexport const isHttpUrl = (u: string) => /^https?:/.test(u)\n\n/**\n * Vendor hostnames the twin answers for — the ones the gateway intercepts on\n * this sandbox's behalf. Informational: they are what a receipt is about, and\n * they are deliberately NOT handed to Daytona as an allowlist (see buildNetwork).\n */\nexport function vendorHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n for (const r of svc.routes ?? []) hosts.add(r.host)\n }\n return [...hosts].sort()\n}\n\n/** Hosts the twin itself lives at — the proxy must reach these or nothing works. */\nexport function twinHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n for (const u of [svc.control_url, svc.url]) {\n if (!u || !isHttpUrl(u)) continue\n try { hosts.add(new URL(u).hostname) } catch { /* skip unparseable */ }\n }\n }\n return [...hosts].sort()\n}\n\n/**\n * The twin hosts a sandbox genuinely cannot work without.\n *\n * A service with vendor routes needs nothing here: the code under test dials\n * `api.stripe.com` and the gateway answers it from the twin. A service with NO\n * routes has no vendor hostname to dial — yente is the one that measured it —\n * so its own twin URL is the only way in, and that URL resolves to a host that\n * was absent from every allowlist we built. Measured: the URL `services()`\n * hands you is unreachable from inside the sandbox, so a routeless twin cannot\n * be used at all.\n *\n * Narrow on purpose, and the narrowness is the point. Every http service of a\n * twin shares ONE hostname (`…/s/<twin>/<service>`), and that hostname also\n * serves `/veris/*` — including `/veris/reset`, which clears the log the\n * receipt is read from. Allowing it is a real cost, so it is paid only when a\n * service would otherwise be unreachable. See the note at the top of state.ts.\n */\nexport function directTwinHosts(services: ServiceInfo[]): string[] {\n return twinHosts(services.filter((s) => isHttpUrl(s.url) && !(s.routes ?? []).length))\n}\n\n/**\n * Endpoints of non-HTTP data planes (e.g. the pg-gateway a postgres DSN\n * targets). Handed over rather than intercepted, so they need plain\n * reachability on the allowlist or the data plane silently breaks.\n *\n * DSNs come in every shape — with/without credentials, with/without a trailing\n * path, redis/kafka/mongo, IPv6 in brackets, comma-separated multi-host — so we\n * parse with the URL parser (which handles all of them) and only fall back to a\n * regex for exotic non-URL forms. Every host in a multi-host DSN is allowed.\n */\nexport function dataPlaneHosts(services: ServiceInfo[]): string[] {\n const hosts = new Set<string>()\n for (const svc of services) {\n if (!svc.url || isHttpUrl(svc.url)) continue\n for (const h of hostsFromDsn(svc.url)) hosts.add(h)\n }\n return [...hosts].sort()\n}\n\nfunction hostsFromDsn(dsn: string): string[] {\n const out: string[] = []\n try {\n const u = new URL(dsn)\n // URL.hostname keeps IPv6 brackets; strip them for the allowlist entry.\n if (u.hostname) out.push(u.hostname.replace(/^\\[|\\]$/g, ''))\n } catch {\n // Not URL-parseable — fall through to the regex.\n }\n // Multi-host DSNs (mongodb://a:27017,b:27017/db) — the URL parser only sees\n // the first authority, so sweep the raw authority for the rest.\n const authority = dsn.replace(/^[^:]+:\\/\\//, '').split(/[/?]/)[0] ?? ''\n const afterAt = authority.includes('@') ? authority.slice(authority.lastIndexOf('@') + 1) : authority\n for (const part of afterAt.split(',')) {\n const m = part.match(/^\\[?([A-Za-z0-9_.:-]+?)\\]?(?::\\d+)?$/)\n if (m?.[1] && !/^\\d+$/.test(m[1])) out.push(m[1].replace(/^\\[|\\]$/g, ''))\n }\n return out\n}\n\n/**\n * `{ [env_hint]: dsn }` for the twin's non-HTTP data planes — the env the code\n * under test reads (e.g. DATABASE_URL). Sibling of dataPlaneHosts: same field,\n * one derivation, so a new service type changes one place.\n */\nexport function dataPlaneEnv(services: ServiceInfo[]): Record<string, string> {\n const envs: Record<string, string> = {}\n for (const svc of services) {\n if (!svc.env_hint || !svc.url || isHttpUrl(svc.url)) continue\n // The env NAME comes from the control plane and is injected into every\n // command, so it is shape-checked before use: a response naming PATH,\n // NODE_OPTIONS or BASH_ENV would otherwise steer the sandbox's processes.\n if (!isSafeEnvName(svc.env_hint)) continue\n envs[svc.env_hint] = svc.url\n }\n return envs\n}\n\n/** Env names a data-plane hint may claim: conventional SCREAMING_SNAKE, and\n * never one of the process-controlling variables. */\nconst PROCESS_CONTROLLING = new Set([\n 'PATH', 'LD_PRELOAD', 'LD_LIBRARY_PATH', 'NODE_OPTIONS', 'BASH_ENV', 'ENV',\n 'PYTHONPATH', 'PYTHONSTARTUP', 'SHELL', 'IFS', 'HOME', 'PROMPT_COMMAND',\n])\nexport function isSafeEnvName(name: string): boolean {\n return /^[A-Z][A-Z0-9_]{0,63}$/.test(name) && !PROCESS_CONTROLLING.has(name)\n}\n\nexport interface BuildNetworkArgs {\n mode: EgressMode\n /** IPv4 addresses the Veris gateway listens on, from the egress credential\n * (or one DNS lookup of the proxy host on an older control plane). */\n gatewayIps: string[]\n}\n\n/** The Daytona create params that decide what the sandbox may reach. */\nexport interface NetworkParams {\n networkAllowList?: string\n}\n\n/** What buildNetwork decided. */\nexport interface NetworkPlan {\n params: NetworkParams\n}\n\nconst IPV4_RE = /^(25[0-5]|2[0-4]\\d|1?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|1?\\d?\\d)){3}$/\n\n/**\n * Strict (the default) pins the sandbox to the gateway's addresses and nothing\n * else: `networkAllowList` is one /32 per gateway IP. Every hostname the code\n * under test dials — vendor, registry, anything — then travels as a CONNECT\n * through the gateway, which answers vendor hostnames from the twin and passes\n * public hosts through. A client that ignores the proxy variables cannot dial\n * out at all (Daytona blocks it), so it fails closed rather than reaching the\n * real vendor.\n *\n * Why an ADDRESS list and not the hostname list this used to build: measured\n * on Daytona, a `domainAllowList` set beside `outboundProxyUrl` switches its\n * egress proxy into TLS inspection. The client is shown a leaf signed by\n * Daytona's own CA, Daytona opens a second TLS session to the gateway and\n * rejects the Veris-signed leaf it gets back, and every vendor call ends as\n * `502 could not reach upstream host` whatever the sandbox trusts.\n * `networkAllowList` beside the same proxy URL leaves the tunnel untouched.\n * Pinning to the gateway also retires Daytona's 20-domain cap: what may be\n * reached is the gateway's decision, not a list assembled here.\n *\n * Open sets no allowlist at all. Daytona still blocks anything that bypasses\n * the proxy in this mode, so it is not a leak; it is the way to run against a\n * control plane that has not published its gateway addresses.\n */\nexport function buildNetwork(args: BuildNetworkArgs): NetworkPlan {\n const { mode, gatewayIps } = args\n if (mode === 'open') return { params: {} }\n const ips = [...new Set(gatewayIps)]\n if (!ips.length) {\n throw new VerisError(\n \"the control plane did not name the gateway's IP addresses (egress credential \" +\n '`gateway_ips`) and the gateway hostname could not be resolved, so the sandbox cannot ' +\n \"be pinned to it. Upgrade the control plane, or run with veris.egress: 'open' \" +\n '(Daytona still blocks anything that bypasses the proxy).',\n { phase: 'credential-mint' })\n }\n const bad = ips.filter((ip) => !IPV4_RE.test(ip))\n if (bad.length) {\n throw new VerisError(\n `the control plane returned gateway addresses that are not IPv4: ${JSON.stringify(bad)} ` +\n \"(Daytona's networkAllowList takes IPv4 CIDRs only)\",\n { phase: 'credential-mint' })\n }\n return { params: { networkAllowList: ips.map((ip) => `${ip}/32`).join(',') } }\n}\n","// Gateway mode: the sandbox's egress is routed through the Veris gateway, which\n// answers vendor hostnames from the twin. Nothing Veris runs inside the sandbox\n// but one CA file.\n//\n// This is the same tier @veris-ai/e2b uses (there via network.egressProxy), and\n// the reason Daytona can host it is that outboundProxyUrl is genuinely chained:\n// Daytona's proxy forwards allowed traffic to it and returns 502 when it cannot.\n//\n// Two things still have to happen inside the sandbox, and both are here:\n// install the gateway's CA so the forged vendor leaves validate, and prove the\n// tunnel is actually live before anyone trusts a receipt.\nimport { promises as dns } from 'node:dns'\nimport type { Sandbox } from '@daytona/sdk'\nimport { ReceiptIntegrityError, SnapshotUnsupportedError, VerisError } from './errors'\nimport {\n BUNDLED_CA_PATCHED_MARKER, BUNDLED_CA_PATCH_SCRIPT, CA_CERT_PATH, CA_INSTALL_CMD,\n SYSTEM_BUNDLE, VERIS_BUNDLE, VERIS_CA_FILE, bundledCaPatchScript,\n} from './trust'\n\n/** A canary hostname must look like a hostname before it goes in a shell command. */\nconst HOSTNAME_RE = /^[A-Za-z0-9.-]+$/\n/** host:port, the only shape an outbound proxy address may take. */\nconst HOSTPORT_RE = /^[A-Za-z0-9.-]+:\\d{1,5}$/\n\n/** Single-quote a string for POSIX sh. */\nexport function shellQuote(s: string): string {\n return `'${s.replace(/'/g, `'\\\\''`)}'`\n}\n\nconst sh = (sandbox: Sandbox, cmd: string, timeoutSec = 60) =>\n sandbox.process.executeCommand(`sh -lc ${shellQuote(cmd)}`, undefined, undefined, timeoutSec)\n\n/**\n * Build the proxy URL Daytona is handed.\n *\n * The username is the tenant demux key — the gateway reads the sandbox id out\n * of it. There is no separate secret: the id IS the capability, exactly as the\n * SOCKS path treats it, so the password is a placeholder the gateway ignores.\n *\n * RFC 3986 §3.2.1 notes that `user:password` in userinfo is deprecated. It is\n * also the only form HTTP proxy clients accept for RFC 7617 Basic credentials,\n * and it is what Daytona forwards, so it is what we emit.\n *\n * `encodeURIComponent` is exactly right for userinfo: everything it leaves raw\n * is unreserved or a sub-delim, and it escapes both separators — `:` to %3A and\n * `@` to %40 — so a username can never break out into the authority.\n *\n * The address is validated rather than interpolated: it arrives from the\n * control plane, and an unchecked value here would land in a URL and then in\n * every client's proxy configuration.\n */\nexport function gatewayProxyUrl(credential: {\n http_proxy_url?: string\n connect_address?: string\n username: string\n}): string {\n // The gateway's own URL wins when it serves one. It knows its auth format —\n // the password is the twin id, not a placeholder — and a locally built URL\n // that guesses wrong authenticates as nobody.\n if (credential.http_proxy_url) return assertProxyUrl(credential.http_proxy_url)\n\n if (!credential.connect_address || !HOSTPORT_RE.test(credential.connect_address)) {\n throw new VerisError(\n `the control plane returned a malformed gateway address: ` +\n `${JSON.stringify(credential.connect_address)} (expected host:port)`,\n { phase: 'credential-mint' })\n }\n return `http://${encodeURIComponent(credential.username)}:x@${credential.connect_address}`\n}\n\n/**\n * The gateway's IPv4 addresses, which strict mode pins Daytona to.\n *\n * The credential's own list wins: the control plane publishes the reserved\n * load-balancer address behind the gateway hostname, and that is the authority\n * on where the gateway is. A control plane that predates the field gets one\n * DNS lookup of the proxy host from here — the caller's resolver is a weaker\n * source, but it is what an older plane leaves. Empty when neither answers;\n * buildNetwork turns that into the error that names the fix.\n */\nexport async function gatewayIps(\n credential: { gateway_ips?: string[] },\n proxyUrl: string,\n): Promise<string[]> {\n if (credential.gateway_ips?.length) return credential.gateway_ips\n const host = new URL(proxyUrl).hostname\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(host)) return [host]\n try { return await dns.resolve4(host) } catch { return [] }\n}\n\n/**\n * A proxy URL from the control plane, before it becomes every client's egress\n * configuration. Untrusted input: it must parse, name a port, and speak a\n * scheme Daytona accepts — it rejects anything but http/https outright.\n */\nfunction assertProxyUrl(raw: string): string {\n let u: URL\n try { u = new URL(raw) } catch {\n throw new VerisError(\n `the control plane returned an unparseable gateway proxy URL: ${JSON.stringify(raw)}`,\n { phase: 'credential-mint' })\n }\n if (u.protocol !== 'http:' && u.protocol !== 'https:') {\n throw new VerisError(\n `the gateway proxy URL uses scheme \"${u.protocol.replace(':', '')}\", and Daytona accepts ` +\n `only http or https outbound proxies`,\n { phase: 'credential-mint' })\n }\n if (!u.hostname || !u.port) {\n throw new VerisError(\n `the gateway proxy URL is missing a host or port: ${JSON.stringify(raw)}`,\n { phase: 'credential-mint' })\n }\n return raw\n}\n\n/**\n * Make the gateway's CA trusted, without requiring anything of the image.\n *\n * Defensive rather than load-bearing on Daytona today, and the distinction is\n * worth recording. Daytona's own proxy terminates TLS with a certificate signed\n * by ITS CA — already trusted in the image — and re-originates to the gateway,\n * so the client never validates our forged leaf. Verified: a vendor call\n * succeeds with --cacert naming only Daytona's CA.\n *\n * We install ours regardless, because the day Daytona tunnels CONNECT\n * end-to-end (the ordinary behaviour for an HTTP proxy) the gateway's leaf\n * reaches the client directly and nothing works without it. One upload and one\n * shell command against a total outage is a trade worth making.\n *\n * The obvious approach — drop the cert in /usr/local/share/ca-certificates and\n * run update-ca-certificates — needs root AND that tool, and Daytona's default\n * image has neither. So the artefact is a bundle we build ourselves at a\n * world-writable path: the distribution's roots (when it has any) plus ours.\n *\n * Daytona overrides the best-known trust variables with its own CA, correctly\n * for its proxy. The dozen it does not set still point at this bundle, which\n * carries both CAs and every public root — so those tools verify rather than\n * break. Node is the exception that makes ours load-bearing today: it ignores\n * HTTPS_PROXY, is forwarded end to end, and validates OUR leaf with Daytona's\n * file. Its file is read-only, so the store install above is what carries\n * Node: NODE_TRUST_FLAG makes Node read the directory that install fills.\n *\n * The system-store install still runs when it can, for anything that reads the\n * store directly rather than honouring the variables. It is best-effort.\n */\nexport async function installCa(sandbox: Sandbox, caPem: string): Promise<void> {\n await sandbox.fs.uploadFile(Buffer.from(caPem, 'utf8'), VERIS_CA_FILE)\n // The bundled-CA patcher goes in now and runs later: the SDK bundles it\n // rewrites are installed by the run, not by the image, so there is nothing\n // for it to find at create time. Putting the script in the sandbox rather\n // than only in this SDK means anything with a shell can re-run it after an\n // install — see patchBundledCas below, and BUNDLED_CA_PATCH_SCRIPT.\n await sandbox.fs.uploadFile(Buffer.from(bundledCaPatchScript(), 'utf8'), BUNDLED_CA_PATCH_SCRIPT)\n\n const script = [\n `chmod 0644 ${VERIS_CA_FILE}`,\n // Public roots first so they keep working; ours appended. `cat` of a\n // missing file is tolerated — an image with no roots at all still gets a\n // bundle containing the one CA that matters here.\n `{ cat ${SYSTEM_BUNDLE} 2>/dev/null; cat ${VERIS_CA_FILE}; } > ${VERIS_BUNDLE}`,\n `chmod 0644 ${VERIS_BUNDLE}`,\n // Best-effort, for the stacks that read a store rather than a variable:\n // the system bundle, the JVM truststore, and NSS databases. All of it needs\n // root and tooling that may not be there, so none of it is load-bearing —\n // but a Java client honours no CA env var at all, so where we CAN do it,\n // we should.\n `SUDO=; [ \"$(id -u)\" = 0 ] || SUDO=\"sudo -n\"`,\n `($SUDO install -m 0644 -D ${VERIS_CA_FILE} ${CA_CERT_PATH} 2>/dev/null && ` +\n `$SUDO sh -c ${shellQuote(CA_INSTALL_CMD)} 2>/dev/null) || true`,\n // The bundle is the load-bearing one: fail loudly if it is not there.\n `[ -s ${VERIS_BUNDLE} ] && echo __VERIS_CA_OK__`,\n ].join('; ')\n\n const r = await sh(sandbox, script, 120).catch((e: unknown) => ({ exitCode: 1, result: String(e) }))\n if (!(r.result ?? '').includes('__VERIS_CA_OK__')) {\n throw new SnapshotUnsupportedError(\n `could not assemble a CA bundle at ${VERIS_BUNDLE}, so the gateway's certificates ` +\n `cannot be trusted (${(r.result ?? '').trim().slice(0, 200)})`,\n { phase: 'ca-install' })\n }\n}\n\n/**\n * Run the bundled-CA patcher installed above, and report what it changed.\n *\n * The gap it closes: an SDK that ships its own CA bundle and loads it by\n * explicit path reads none of the eighteen trust variables. stripe-python is\n * the measured case — `verify=stripe.ca_bundle_path`, and the first call fails\n * with \"Could not verify Stripe's SSL certificate\" in a sandbox where curl,\n * Node and `requests` are all fine. This is the Daytona equivalent of the veris\n * CLI's --patch-bundled-cas.\n *\n * Call it AFTER dependencies are installed. Idempotent, so calling it again\n * after installing more costs one filesystem scan and reports nothing new.\n *\n * Never fatal. A sandbox with no such bundle is the normal case, and a scan\n * that could not run is a missed optimisation, not a broken run — the failure\n * it prevents still announces itself clearly in the client's own error.\n */\nexport async function patchBundledCas(sandbox: Sandbox): Promise<string[]> {\n const r = await sh(sandbox, `sh ${BUNDLED_CA_PATCH_SCRIPT}`, 180)\n .catch((e: unknown) => ({ exitCode: 1, result: String(e) }))\n return (r.result ?? '')\n .split('\\n')\n .filter((line) => line.startsWith(BUNDLED_CA_PATCHED_MARKER))\n .map((line) => line.slice(BUNDLED_CA_PATCHED_MARKER.length).trim())\n .filter(Boolean)\n}\n\n/**\n * The canary probe: one HTTPS request from inside the sandbox to a reserved\n * hostname only the gateway answers, with the twin id in the body.\n *\n * Green proves three things in a single request — egress really is tunnelled\n * through the gateway, the credential demuxed to the right twin, and the CA\n * install worked. Dialled outside the tunnel the host has no listener, so this\n * cannot pass by accident, which is what makes a receipt worth reading.\n */\nexport async function probeCanary(\n sandbox: Sandbox,\n canaryHost: string,\n expectedTwinId: string,\n): Promise<void> {\n if (!HOSTNAME_RE.test(canaryHost)) {\n throw new ReceiptIntegrityError(\n `refusing to probe a malformed canary host from the control plane: ${JSON.stringify(canaryHost)}`,\n { phase: 'canary', verisSandboxId: expectedTwinId })\n }\n // A non-zero curl exit must surface as a ReceiptIntegrityError, not as the\n // raw command failure, so print a marker and inspect the output ourselves.\n const r = await sh(\n sandbox,\n `curl -sS --cacert ${VERIS_BUNDLE} --max-time 20 https://${canaryHost}/ || echo __VERIS_CANARY_FAIL__`,\n 45,\n ).catch((e: unknown) => ({ exitCode: 1, result: String(e) }))\n\n let body: { veris_sandbox_id?: string } = {}\n try { body = JSON.parse(r.result ?? '') } catch { /* handled below */ }\n if (body.veris_sandbox_id !== expectedTwinId) {\n throw new ReceiptIntegrityError(\n `canary probe failed: egress from this Daytona sandbox is not tunnelled through the ` +\n `Veris gateway (expected twin ${expectedTwinId}, canary answered: ` +\n `${(r.result || 'nothing').trim().slice(0, 200)})`,\n { phase: 'canary', verisSandboxId: expectedTwinId })\n }\n}\n","// CA trust: which env vars point which client stacks at the system bundle,\n// and the single tested install command.\n\n/** Where the Veris CA certificate lands in the Daytona sandbox. This is the\n * standard Debian drop-in directory, so any later `update-ca-certificates`\n * rebuilds the bundle with our cert still included. */\nexport const CA_CERT_PATH = '/usr/local/share/ca-certificates/veris-ca.crt'\n\n/** The distribution's own bundle, when it has one. */\nexport const SYSTEM_BUNDLE = '/etc/ssl/certs/ca-certificates.crt'\n\n/** Our CA alone, world-readable, written before anything needs it. */\nexport const VERIS_CA_FILE = '/tmp/veris-ca.crt'\n\n/**\n * The public roots plus ours, concatenated by us.\n *\n * Every path-valued trust var points here rather than at SYSTEM_BUNDLE, because\n * `update-ca-certificates` is not always present — Daytona's default image does\n * not ship it — and a var pointing at a bundle that was never rebuilt trusts\n * everything except the one CA that matters. We write this file ourselves, so\n * it is correct whether or not the distribution has the tooling.\n */\nexport const VERIS_BUNDLE = '/tmp/veris-ca-bundle.crt'\n\n/**\n * The trust variables injected into every sandbox at create time.\n *\n * This is the load-bearing half of CA trust: the gateway forges a leaf for each\n * vendor hostname, and a client that does not trust the Veris CA rejects it, so\n * without these (or the store install below) every HTTPS vendor call fails on\n * certificate validation.\n *\n * Every var is path-valued and points at VERIS_BUNDLE (public roots + ours, so\n * passthrough hosts keep verifying) — NODE_EXTRA_CA_CERTS included. That var is\n * additive, but only to Node's BAKED-IN Mozilla roots, never to the system\n * store — and on Daytona the leaf a client actually validates is signed by\n * Daytona's proxy CA (its proxy terminates TLS; see installCa's comment), which\n * lives in the system store and nowhere in Mozilla's roots. Point Node at the\n * single Veris cert and it can verify neither that leaf nor a directly served\n * gateway one behind it: UNABLE_TO_VERIFY_LEAF_SIGNATURE on every vendor call.\n * The bundle carries the system store (Daytona's CA with it) plus ours, so it\n * is the one file that works in both worlds.\n */\nexport function vendoredTrustEnv(): Record<string, string> {\n return {\n SSL_CERT_FILE: VERIS_BUNDLE,\n REQUESTS_CA_BUNDLE: VERIS_BUNDLE,\n CURL_CA_BUNDLE: VERIS_BUNDLE,\n GIT_SSL_CAINFO: VERIS_BUNDLE,\n AWS_CA_BUNDLE: VERIS_BUNDLE,\n CARGO_HTTP_CAINFO: VERIS_BUNDLE,\n DENO_CERT: VERIS_BUNDLE,\n PIP_CERT: VERIS_BUNDLE,\n npm_config_cafile: VERIS_BUNDLE,\n GRPC_DEFAULT_SSL_ROOTS_FILE_PATH: VERIS_BUNDLE,\n BUNDLE_SSL_CA_CERT: VERIS_BUNDLE,\n COMPOSER_CAFILE: VERIS_BUNDLE,\n HEX_CACERTS_PATH: VERIS_BUNDLE,\n JULIA_SSL_CA_ROOTS_PATH: VERIS_BUNDLE,\n NIX_SSL_CERT_FILE: VERIS_BUNDLE,\n PERL_LWP_SSL_CA_FILE: VERIS_BUNDLE,\n CLOUDSDK_CORE_CUSTOM_CA_CERTS_FILE: VERIS_BUNDLE,\n NODE_EXTRA_CA_CERTS: VERIS_BUNDLE,\n }\n}\n\n/**\n * The same variables as one POSIX `export` prelude, to prefix a command with.\n *\n * The map above is the right shape when you control the process's environment.\n * A caller that does not — anything handing a command to a shell whose env it\n * did not build — has nowhere to put a map, and the command inherits Daytona's\n * overwritten SSL_CERT_FILE / REQUESTS_CA_BUNDLE / CURL_CA_BUNDLE /\n * NODE_EXTRA_CA_CERTS instead. Measured with the inherited value: `uv sync`\n * dies with \"invalid peer certificate: UnknownIssuer\". Prefixing this makes\n * the command's own shell put the Veris bundle back:\n *\n * sandbox.process.executeCommand(`${trustPrelude()} ${yourCommand}`)\n *\n * Values are single-quoted, so the string stays one safe command line whatever\n * the control plane served.\n */\nexport function trustPrelude(env: Record<string, string> = vendoredTrustEnv()): string {\n return Object.entries(env)\n .map(([k, v]) => `export ${k}='${v.replace(/'/g, `'\\\\''`)}';`)\n .join(' ')\n}\n\n/**\n * CA bundles that SDKs ship INSIDE the code under test, as slash-anchored path\n * suffixes.\n *\n * No trust variable reaches these. stripe-python passes\n * `verify=stripe.ca_bundle_path` explicitly, so all eighteen variables above\n * are irrelevant to it and the first Stripe call dies with \"Could not verify\n * Stripe's SSL certificate\" — the gateway's forged leaf is signed by a CA that\n * file has never heard of. Appending our CA to the file keeps the SDK on the\n * code path that ships; the bundle merely holds one more root.\n *\n * The table is the veris CLI's (internal/bundlescan), for the reason it gives\n * there: matched as a path SUFFIX because site-packages prefixes vary per\n * image and the tail does not, and deliberately with no bare `cacert.pem`\n * rule, because that filename also names test fixtures and client-auth\n * material that must not quietly gain a root.\n */\nexport const BUNDLED_CA_FILES: readonly { sdk: string; suffix: string }[] = [\n { sdk: 'pip (vendored certifi)', suffix: 'pip/_vendor/certifi/cacert.pem' },\n { sdk: 'certifi', suffix: 'certifi/cacert.pem' },\n { sdk: 'botocore', suffix: 'botocore/cacert.pem' },\n // Matches both stripe-python's site-packages layout and the stripe-ruby gem.\n { sdk: 'stripe', suffix: 'stripe/data/ca-certificates.crt' },\n { sdk: 'httplib2', suffix: 'httplib2/cacerts.txt' },\n]\n\n/** Where the patch script is written inside the sandbox, so anything that can\n * run a shell command — a test harness, an agent, a person over ssh — can\n * re-run it after installing dependencies without holding this SDK. */\nexport const BUNDLED_CA_PATCH_SCRIPT = '/tmp/veris-patch-bundled-cas.sh'\n\n/**\n * What the script prints per patched file, so the caller can report what\n * happened rather than infer it from an exit code.\n *\n * A sentence rather than a machine marker, because both routes to this script\n * are read by a person. `provision` tells a caller to run `sh\n * /tmp/veris-patch-bundled-cas.sh` themselves, and whatever the script prints\n * is what they see — a bare `__VERIS_PATCHED__ /path` reads as debug output\n * that escaped. `patchBundledCas()` parses the paths back off this same\n * constant, and cli.ts prints the same sentence for the SDK route, so the\n * prose a human reads and the list a program gets cannot drift apart.\n */\nexport const BUNDLED_CA_PATCHED_MARKER = 'the Veris CA was appended to '\n\n/**\n * The script that finds those bundles and appends the Veris CA to each.\n *\n * Meant to run AFTER dependencies are installed, and to be re-run: the bundles\n * do not exist at create time, and an agent installs more of them mid-session,\n * so there is no create-time moment that covers either. Idempotent by\n * construction — a file already carrying our certificate is skipped, matched\n * on a line of its base64 body rather than on the BEGIN line every certificate\n * shares.\n *\n * Appending in place, where the CLI over-mounts a patched copy: a Daytona\n * sandbox offers no bind mounts and the container is disposable, so editing\n * the file is the equivalent move. Unwritable files are skipped rather than\n * sudo'd — a root-owned bundle in the system Python is rarely the one the\n * application's virtualenv reads, and silently rewriting system trust is a\n * larger act than this warrants.\n */\nexport function bundledCaPatchScript(): string {\n const find = BUNDLED_CA_FILES\n .map((f) =>\n `find / -xdev \\\\( -path /proc -o -path /sys -o -path /dev \\\\) -prune -o ` +\n `-path '*/${f.suffix}' -type f -print 2>/dev/null`)\n .join('; ')\n return [\n `marker=$(sed -n 2p ${VERIS_CA_FILE} 2>/dev/null)`,\n // No CA on disk means nothing to append, and appending nothing to every\n // bundle in the image would be the worst available no-op.\n `[ -n \"$marker\" ] || { echo \"no ${VERIS_CA_FILE} to append\" >&2; exit 1; }`,\n // The whole loop is one brace group at the end of the pipe so `n` survives\n // to the summary: a pipeline's last stage is a subshell, and a counter\n // incremented inside a bare `while` would be gone by the time we report it.\n `{ ${find}; } | sort -u | { n=0`,\n `while IFS= read -r f; do`,\n ` [ -w \"$f\" ] || continue`,\n ` grep -qF \"$marker\" \"$f\" && continue`,\n ` { printf '\\\\n'; cat ${VERIS_CA_FILE}; } >> \"$f\" || continue`,\n ` n=$((n+1))`,\n ` echo \"${BUNDLED_CA_PATCHED_MARKER}$f\"`,\n `done`,\n // Silence is the common case and it reads as \"did that even run?\", so say\n // so. patchBundledCas() keeps only the lines above, so this costs it\n // nothing.\n `if [ \"$n\" -gt 0 ]; then echo \"$n bundled CA file(s) patched\"`,\n `else echo \"no bundled CA file needed patching — no SDK that ships its own is installed here, or they already trust the Veris CA\"; fi`,\n `}`,\n ].join('\\n')\n}\n\n/**\n * Node is the one runtime the trust variables above cannot reach.\n *\n * Daytona overwrites NODE_EXTRA_CA_CERTS and SSL_CERT_FILE inside the sandbox\n * with its own CA file — right for clients that go through its proxy, which\n * terminates TLS with that CA. Node is not such a client: it ignores\n * HTTPS_PROXY, is forwarded to the gateway end to end, and the leaf it\n * validates is signed by the Veris CA, which Daytona's file lacks. Seen live:\n * plain `node` failed against a vendor host with UNABLE_TO_VERIFY_LEAF_SIGNATURE.\n */\n\n/**\n * Node's trust flag. NODE_EXTRA_CA_CERTS is Daytona's, and Node's baked-in\n * Mozilla roots know neither CA — so switch Node to OpenSSL's store:\n * --use-openssl-ca loads SSL_CERT_FILE (Daytona's file) AND the system\n * certificate directory, where CA_INSTALL_CMD puts our CA and the distribution\n * keeps the public roots. Injected as NODE_OPTIONS, which Daytona leaves alone.\n *\n * Verified live on Daytona's default image (uid 1001, passwordless sudo,\n * update-ca-certificates present): 200 from plain `node` with the flag and\n * our CA in /etc/ssl/certs; UNABLE_TO_VERIFY_LEAF_SIGNATURE without the flag.\n * So this leans on the store install succeeding. There is no second route:\n * Daytona's CA file is on a read-only mount, so appending our CA to it — the\n * obvious alternative — fails for root too.\n */\nexport const NODE_TRUST_FLAG = '--use-openssl-ca'\n\n/** NODE_OPTIONS with the trust flag appended to whatever the caller set. */\nexport function nodeOptionsWithTrust(existing?: string): string {\n const base = (existing ?? '').trim()\n if (base.split(/\\s+/).includes(NODE_TRUST_FLAG)) return base\n return base ? `${base} ${NODE_TRUST_FLAG}` : NODE_TRUST_FLAG\n}\n\n/**\n * The store-based install, for stacks that read a trust store rather than an\n * env var — a Java client honours no CA variable at all. Rebuilds the system\n * bundle with the Veris CA (already at CA_CERT_PATH), imports it into the JVM\n * cacerts (`|| true`: no Java → skipped), and adds it to NSS databases when\n * certutil exists.\n *\n * Entirely best-effort: it needs root and tooling the image may not have, which\n * is why VERIS_BUNDLE plus the trust variables — not this — is what actually\n * makes interception work.\n */\nexport const CA_INSTALL_CMD = [\n 'update-ca-certificates',\n `(keytool -importcert -noprompt -cacerts -storepass changeit -alias veris -file ${CA_CERT_PATH} 2>/dev/null || true)`,\n '(command -v certutil >/dev/null 2>&1 && ' +\n 'for db in $(find /home /root -maxdepth 4 -name \"cert9.db\" 2>/dev/null | xargs -r -n1 dirname); do ' +\n `certutil -A -n veris -t \"C,,\" -i ${CA_CERT_PATH} -d \"sql:$db\" 2>/dev/null || true; done || true)`,\n].join(' && ')\n\n/**\n * Sanitize a server-served trust_env map before injecting it into the sandbox.\n * A control-plane response must never become arbitrary env-var injection, so\n * only known trust variables survive, and every value is forced to a\n * path-shaped string (the vars are all CA *file paths*). Unknown keys and\n * non-path values are dropped. Returns the vendored map when nothing valid\n * remains.\n */\nexport function sanitizeTrustEnv(served: Record<string, unknown> | undefined): Record<string, string> {\n const vendored = vendoredTrustEnv()\n // Start from the vendored map so a single bad or absent served value falls\n // back PER KEY to the known-good default, rather than dropping that variable\n // and leaving (e.g.) Python's requests with no CA bundle.\n const out: Record<string, string> = { ...vendored }\n for (const [k, val] of Object.entries(served ?? {})) {\n if (!(k in vendored)) continue // unknown key: never injected\n if (typeof val !== 'string') continue\n // Absolute path; allow the common path characters (incl. + and ~).\n if (!/^\\/[\\w./+~-]+$/.test(val)) continue\n out[k] = val\n }\n return out\n}\n","// Reads of a twin service's own control plane that are not the receipt.\n//\n// Same shape and same reasoning as receipt.ts: these run HOST-SIDE, never from\n// inside the sandbox. A sandbox that can reach /veris/* can also reach\n// /veris/reset — and an agent that can clear request history can make its own\n// receipt say anything. The twin's host used to be kept off the sandbox's\n// Daytona allowlist for that reason; with Daytona pinned to the gateway's\n// address instead (see network.ts) the twin's public URL passes through the\n// gateway like any other public host, and the data plane's /veris/* routes\n// take no key (measured: GET /veris/requests and POST /veris/reset both 200\n// with no credential). Keeping the twin's control routes out of the\n// sandbox's reach is now the gateway's job, not this package's — the same\n// position @veris-ai/e2b has always been in. directTwinHosts names the twins a\n// sandbox must reach by their own URL (no vendor routes to intercept).\nimport { VerisError } from './errors'\nimport type { ServiceInfo } from './control-plane'\nimport { isHttpUrl } from './network'\n\n/** Guard shared by every control-plane read: a DSN-only service (postgres and\n * friends) has no /veris/* surface, and saying so beats a TypeError. */\nexport function assertHttpControlPlane(svc: ServiceInfo): void {\n if (!svc.control_url || !isHttpUrl(svc.control_url)) {\n throw new VerisError(\n `service '${svc.name}' has no HTTP control plane, so there is nothing to read`,\n { phase: 'twin-state' },\n )\n }\n}\n\n/**\n * The service's manual: what this twin models, which endpoints it answers, and\n * the conventions its data follows. Prose, not JSON — it is written to be read\n * before designing anything against the service.\n */\nexport async function fetchManual(svc: ServiceInfo): Promise<string> {\n assertHttpControlPlane(svc)\n const res = await fetch(`${svc.control_url}/veris/manual`)\n const text = await res.text()\n if (!res.ok) {\n throw new VerisError(`could not read the manual for service '${svc.name}' (${res.status})`, {\n phase: 'twin-state', responseBody: text.slice(0, 500) })\n }\n return text\n}\n","// The namespaced Veris surface: everything this package adds hangs off\n// `sbx.veris`, matching Daytona's own `sbx.fs` / `sbx.process` idiom so a\n// future @daytona/sdk minor can never collide with a generic method name.\nimport { captureBaseline, validateBaseline } from './run-receipt'\nimport type { ReceiptBaseline } from './run-receipt'\nimport { serviceControl } from './service-control'\nimport type { ControlOptions, ControlResource } from './service-control'\nimport type { Sandbox } from '@daytona/sdk'\nimport type { ControlPlane, ServiceInfo } from './control-plane'\nimport { fetchReceiptEntry } from './receipt'\nimport type { Receipt, ReceiptEntry, ReceiptLeak } from './receipt'\nimport { VerisUntouchedError, VerisError } from './errors'\nimport { dataPlaneEnv, isHttpUrl } from './network'\nimport type { EgressMode } from './network'\nimport { patchBundledCas, probeCanary } from './gateway'\nimport { fetchManual } from './state'\nimport { trustPrelude, vendoredTrustEnv } from './trust'\n\n/** Everything needed to answer Veris queries about a live sandbox. */\nexport interface VerisContext {\n sandbox: Sandbox\n controlPlane: ControlPlane\n environmentId: string\n twinId: string\n egress: EgressMode\n /** The reserved host the canary probe dials to prove the tunnel is live. */\n canaryHost: string\n /** Whether this twin is owned (delete removes it) or attached (caller owns it). */\n ownsTwin: boolean\n /** Newest request id per service when this run began, so a receipt counts\n * what the run caused rather than what an attached twin already held. Set by\n * create(); a sandbox rehydrated by get() has none and reads the log from\n * the start, as the receipt always did. Not persisted in a label on\n * purpose — the sandbox can rewrite its own labels, and a watermark it\n * chose would let it hide its own traffic from the receipt. */\n watermarks?: Record<string, number>\n}\n\n/** Narrow assertTouched to specific requests. All fields AND together. */\nexport interface TouchMatcher {\n method?: string\n /** Substring match against the request path. */\n path?: string\n /** Minimum matching requests required (default 1). */\n minRequests?: number\n}\n\nexport interface VerisApi {\n /** Whether provider teardown owns this twin. */\n readonly ownsTwin: boolean\n /** The Veris twin's sandbox id — NOT the Daytona sandbox id. */\n readonly sandboxId: string\n /** The Veris environment the twin was deployed from. Every control-plane\n * route that acts on a twin is scoped to it, so a caller that wants to talk\n * to the twin itself needs it and has nowhere else to read it from. */\n readonly environmentId: string\n readonly mode: 'gateway'\n services(): Promise<ServiceInfo[]>\n /** The service's own manual: what it models and how its data is shaped. */\n manual(service: string): Promise<string>\n receiptBaseline(): Promise<ReceiptBaseline>\n receiptSince(baseline: ReceiptBaseline, service?: string): Promise<Receipt>\n control(service: string, resource: ControlResource, options?: ControlOptions): Promise<unknown>\n receipt(): Promise<Receipt>\n receipt(service: string): Promise<ReceiptEntry>\n assertTouched(service: string, match?: TouchMatcher): Promise<void>\n getDataPlaneEnv(): Promise<Record<string, string>>\n getTrustEnv(): Record<string, string>\n /** The same trust variables as a shell `export` prelude, for a caller that\n * can only prefix a command line. */\n trustPrelude(): string\n /** Append the Veris CA to the CA bundles SDKs ship with them. Run it after\n * installing dependencies; returns the files it changed. */\n patchBundledCas(): Promise<string[]>\n deliverTo(port: number, opts?: DeliverToOpts): Promise<string>\n deliverTo(url: string | null, opts?: DeliverToOpts): Promise<string | null>\n}\n\nexport interface DeliverToOpts {\n /** Verify the destination is actually reachable from the twin before\n * returning, via each service's /veris/client/probe. Default true. */\n probe?: boolean\n}\n\nexport class VerisApiImpl implements VerisApi {\n constructor(private readonly ctx: VerisContext) {}\n\n get ownsTwin(): boolean { return this.ctx.ownsTwin }\n get sandboxId(): string { return this.ctx.twinId }\n get environmentId(): string { return this.ctx.environmentId }\n get mode(): 'gateway' { return 'gateway' }\n\n services(): Promise<ServiceInfo[]> {\n return this.ctx.controlPlane.services(this.ctx.twinId)\n }\n\n /** Resolve a service by name. A typo and a service that exists but saw\n * nothing are different failures, so this throws rather than returning\n * undefined and letting the caller report an empty result. */\n private async resolveService(service: string): Promise<ServiceInfo> {\n const services = await this.services()\n const svc = services.find((s) => s.name === service)\n if (!svc) {\n throw new VerisError(\n `unknown service '${service}' — the twin has no service by that name (available: ${services.map((s) => s.name).join(', ') || 'none'})`,\n { verisSandboxId: this.ctx.twinId })\n }\n return svc\n }\n\n async manual(service: string): Promise<string> {\n return fetchManual(await this.resolveService(service))\n }\n\n receipt(): Promise<Receipt>\n receipt(service: string): Promise<ReceiptEntry>\n async receipt(service?: string): Promise<Receipt | ReceiptEntry> {\n // Prove egress is STILL tunnelled before trusting any count. A receipt read\n // from a sandbox whose egress was detached would be a confident lie, which\n // is worse than no receipt at all.\n await probeCanary(this.ctx.sandbox, this.ctx.canaryHost, this.ctx.twinId)\n\n if (service !== undefined) {\n const svc = await this.resolveService(service)\n return fetchReceiptEntry(svc, this.watermark(svc.name))\n }\n\n const services = await this.services()\n const entries = await Promise.all(\n services.filter((s) => isHttpUrl(s.control_url)).map(async (svc) =>\n [svc.name, await fetchReceiptEntry(svc, this.watermark(svc.name))] as const))\n return {\n services: Object.fromEntries(entries),\n mode: 'gateway',\n integrity: 'verified',\n leaks: this.leaks(),\n }\n }\n\n /**\n * What this receipt cannot see. The gateway relays TCP, so QUIC/HTTP3 and ECH\n * ride around it — named rather than rounded off.\n */\n private leaks(): ReceiptLeak[] {\n return ['udp-quic-possible', 'ech-possible']\n }\n\n /** Where this service's log was when the run began. 0 reads all of it. */\n private watermark(service: string): number {\n return this.ctx.watermarks?.[service] ?? 0\n }\n\n private async verifyIntegrity(): Promise<void> {\n await probeCanary(this.ctx.sandbox, this.ctx.canaryHost, this.ctx.twinId)\n }\n\n async receiptBaseline(): Promise<ReceiptBaseline> {\n await this.verifyIntegrity()\n return captureBaseline(this.ctx.twinId, this.ctx.sandbox.id,\n (await this.services()).filter(s => isHttpUrl(s.control_url)))\n }\n\n async receiptSince(baseline: ReceiptBaseline, service?: string): Promise<Receipt> {\n await this.verifyIntegrity()\n const services = (await this.services()).filter(s => isHttpUrl(s.control_url))\n if (service !== undefined && !services.some(s => s.name === service)) {\n throw new VerisError(`unknown HTTP service '${service}'`, { phase: 'receipt' })\n }\n await validateBaseline(baseline, this.ctx.twinId, this.ctx.sandbox.id, services)\n const selected = service === undefined ? services : services.filter(s => s.name === service)\n const entries = await Promise.all(selected.map(async svc =>\n [svc.name, await fetchReceiptEntry(svc, baseline.services[svc.name]!.id)] as const))\n // Reset during the read invalidates the whole measurement, including any\n // pages fetched before history disappeared.\n await validateBaseline(baseline, this.ctx.twinId, this.ctx.sandbox.id, await this.services().then(s => s.filter(v => isHttpUrl(v.control_url))))\n return { services: Object.fromEntries(entries), mode: 'gateway', integrity: 'verified', leaks: this.leaks() }\n }\n\n async control(service: string, resource: ControlResource, options?: ControlOptions): Promise<unknown> {\n const svc = (await this.services()).find(s => s.name === service)\n if (!svc) throw new VerisError(`unknown service '${service}'`)\n return serviceControl(svc, resource, options)\n }\n\n async assertTouched(service: string, match?: TouchMatcher): Promise<void> {\n // Throws VerisError (not VerisUntouchedError) for an unknown service — a\n // typo is a different failure from a service that saw zero traffic.\n const entry: ReceiptEntry = await this.receipt(service)\n const need = match?.minRequests ?? 1\n const matched = match\n ? entry.entries.filter((r) =>\n (match.method === undefined || r.method.toUpperCase() === match.method.toUpperCase()) &&\n (match.path === undefined || r.path.includes(match.path)))\n : entry.entries\n if (matched.length < need && entry.capped) {\n throw new VerisError(`receipt for '${service}' is incomplete; insufficient evidence`, { phase: 'receipt' })\n }\n if (matched.length < need) {\n const what = match\n ? `matching ${match.method ?? 'ANY'} ${match.path ?? '*'} (${matched.length}/${need})`\n : 'any intercepted requests'\n throw new VerisUntouchedError(\n `service '${service}' saw no ${what} — the code under test never reached it ` +\n `(a green run that skipped its dependency looks identical to a working one)`,\n service, { verisSandboxId: this.ctx.twinId })\n }\n }\n\n async getDataPlaneEnv(): Promise<Record<string, string>> {\n return dataPlaneEnv(await this.services())\n }\n\n /** The CA trust vars injected at create, for callers building their own env. */\n getTrustEnv(): Record<string, string> {\n return vendoredTrustEnv()\n }\n\n /**\n * The same variables as a shell prelude, for a caller that has no env map to\n * fill — anything running a command through a session or a shell it did not\n * build the environment for. Daytona resets SSL_CERT_FILE,\n * REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE and NODE_EXTRA_CA_CERTS to its own CA\n * file inside the sandbox, and that file cannot verify the gateway's leaf, so\n * a command that inherits them fails on certificate validation:\n * `uv sync` dies with \"invalid peer certificate: UnknownIssuer\".\n *\n * sbx.process.executeCommand(`${sbx.veris.trustPrelude()} uv sync`)\n */\n trustPrelude(): string {\n return trustPrelude(this.getTrustEnv())\n }\n\n /**\n * Append the Veris CA to the CA bundles the code under test's own SDKs ship.\n *\n * The variables above reach every client that reads one. stripe-python does\n * not: it passes `verify=stripe.ca_bundle_path`, so the first Stripe call\n * fails with \"Could not verify Stripe's SSL certificate\" in a sandbox where\n * curl, Node and `requests` all succeed. This patches the file itself, which\n * is the Daytona-shaped version of the veris CLI's --patch-bundled-cas.\n *\n * Call it AFTER installing dependencies — the bundles arrive with them, so\n * there is nothing to patch at create time. Safe to call again; it returns\n * only the files it actually changed.\n */\n patchBundledCas(): Promise<string[]> {\n return patchBundledCas(this.ctx.sandbox)\n }\n\n /**\n * Point every mocked vendor's callbacks/webhooks at this sandbox.\n *\n * Pass a PORT your app listens on and it resolves the sandbox's own preview\n * URL — the address a vendor would POST to in production. Pass a full URL to\n * use that instead, or null to unregister.\n *\n * One call covers every service: a twin has ONE client, so the control plane\n * fans the destination out to all of them.\n */\n deliverTo(port: number, opts?: DeliverToOpts): Promise<string>\n deliverTo(url: string | null, opts?: DeliverToOpts): Promise<string | null>\n async deliverTo(target: number | string | null, opts: DeliverToOpts = {}): Promise<string | null> {\n const url = typeof target === 'number'\n ? (await this.ctx.sandbox.getPreviewLink(target)).url\n : target\n await this.ctx.controlPlane.updateSandbox(\n this.ctx.environmentId, this.ctx.twinId, { client_base_url: url })\n if (url !== null && opts.probe !== false) await this.probeDelivery(url)\n return url\n }\n\n /** Ask each service to re-probe the registered destination; throw if none can reach it. */\n private async probeDelivery(url: string): Promise<void> {\n const services = (await this.services()).filter((s) => isHttpUrl(s.control_url))\n if (!services.length) return\n const probes = await Promise.all(services.map(async (svc) => {\n try {\n const res = await fetch(`${svc.control_url}/veris/client/probe`, { method: 'POST' })\n return res.ok ? await res.json() as { answered?: boolean } : null\n } catch { return null }\n }))\n if (!probes.some((p) => p?.answered)) {\n throw new VerisError(\n `no service could reach ${url} — is your app listening on that port inside the Daytona sandbox?`,\n { phase: 'receipt', verisSandboxId: this.ctx.twinId, responseBody: probes })\n }\n }\n}\n","// Where the Veris key and control plane come from when nothing in the shell\n// says: the `veris` CLI's own login profile.\n//\n// `veris login` saves the key to ~/.veris/twin.yaml (mode 0600) under a\n// profile, and a customer who signed in that way has nothing in their\n// environment. Reading only process.env here meant `provision` failed with a\n// missing-key error on a machine the CLI was perfectly happy on — and exporting\n// the key by hand to get past it made `veris doctor` warn that the shell key\n// now overrides the profile.\n//\n// The precedence is the CLI's, from its README (\"Profiles and CI\") and\n// internal/cfg/resolve.go, minus the flags this package does not have:\n//\n// key: VERIS_API_KEY → the profile's api_key\n// base: VERIS_API_BASE → the profile's api_base → https://svc.api.veris.ai\n// profile: VERIS_PROFILE → active_profile in the file → \"default\"\n//\n// VERIS_API_KEY beats the profile on every command, and when it is set the\n// profile's key is never read. The file's own api_base still applies then,\n// exactly as the CLI does it.\n//\n// The file is the same on macOS, Linux and Windows: the CLI's Go code joins\n// os.UserHomeDir() with \".veris\", and Node's os.homedir() resolves the same\n// directory on all three ($HOME, or %USERPROFILE% on Windows).\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { parse } from 'yaml'\nimport { MissingCredentialsError, VerisError } from './errors'\n\nexport const DEFAULT_API_BASE = 'https://svc.api.veris.ai'\n\n/** The profile file's shape, as the CLI writes it (internal/cfg/global.go). */\nexport interface ProfileFile {\n active_profile?: string\n profiles?: Record<string, { api_base?: string; api_key?: string } | null>\n}\n\n/** Where a key and a control plane were finally found. */\nexport interface VerisCredentials {\n apiKey?: string\n apiBase: string\n /** Which layer answered for the key. `none` when nothing did. */\n keySource: 'option' | 'env' | 'profile' | 'none'\n /** Which layer answered for the base. `default` means nobody named one —\n * which matters to a caller deciding whether the base is a trusted source. */\n baseSource: 'option' | 'env' | 'profile' | 'default'\n /** The profile that was (or would have been) read, and whether it exists. */\n profile: { name: string; path: string; found: boolean }\n}\n\nexport interface ResolveOpts {\n /** A key given in code, which wins over everything. */\n apiKey?: string\n /** A base given in code, which wins over everything. */\n apiBase?: string\n /** The environment to read; defaults to process.env. */\n env?: NodeJS.ProcessEnv\n /** The profile file's path; defaults to ~/.veris/twin.yaml. */\n path?: string\n /** Reads the file, or returns undefined when it does not exist. Injected\n * so the resolution is testable without touching the home directory. */\n readFile?: (path: string) => string | undefined\n}\n\n/** ~/.veris/twin.yaml, resolved the way the CLI resolves it. */\nexport function profilePath(home: string = homedir()): string {\n return join(home, '.veris', 'twin.yaml')\n}\n\nfunction readOrUndefined(path: string): string | undefined {\n try {\n return readFileSync(path, 'utf8')\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw e\n }\n}\n\n/**\n * Parse the profile file. A missing file is not an error: a fresh machine has\n * none, and the caller says what to do about that. A file that exists but\n * does not parse IS an error naming the path, because silently treating it as\n * empty would send the user to log in again over a stray tab — the CLI's own\n * rule, kept so the two agree about the same file.\n */\nexport function parseProfileFile(text: string | undefined, path: string): ProfileFile | undefined {\n if (text === undefined) return undefined\n let parsed: unknown\n try {\n parsed = parse(text)\n } catch (cause) {\n throw new VerisError(`${path} is not valid YAML`, { phase: 'credentials', cause })\n }\n if (parsed === null || parsed === undefined) return {}\n if (typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new VerisError(`${path} is not a profile file (expected a mapping)`, { phase: 'credentials' })\n }\n return parsed as ProfileFile\n}\n\n/** Which profile a command uses: VERIS_PROFILE → active_profile → default. */\nexport function selectProfileName(env: NodeJS.ProcessEnv, file: ProfileFile | undefined): string {\n return env.VERIS_PROFILE || file?.active_profile || 'default'\n}\n\n/**\n * The key and control plane this process should use, and where each came\n * from. Never throws for a missing key — that is a decision for the caller,\n * which knows whether it needs one — but does throw for a file it cannot read.\n */\nexport function resolveVerisCredentials(opts: ResolveOpts = {}): VerisCredentials {\n const env = opts.env ?? process.env\n const path = opts.path ?? profilePath()\n const file = parseProfileFile((opts.readFile ?? readOrUndefined)(path), path)\n const name = selectProfileName(env, file)\n const profile = file?.profiles?.[name] ?? undefined\n const found = profile !== undefined && profile !== null\n\n const apiKey = opts.apiKey || env.VERIS_API_KEY || (found ? profile.api_key : undefined) || undefined\n const keySource: VerisCredentials['keySource'] =\n opts.apiKey ? 'option' : env.VERIS_API_KEY ? 'env' : apiKey ? 'profile' : 'none'\n const profileBase = found ? profile.api_base : undefined\n const apiBase = (opts.apiBase || env.VERIS_API_BASE || profileBase || DEFAULT_API_BASE).replace(/\\/$/, '')\n const baseSource: VerisCredentials['baseSource'] =\n opts.apiBase ? 'option' : env.VERIS_API_BASE ? 'env' : profileBase ? 'profile' : 'default'\n\n return { apiKey, apiBase, keySource, baseSource, profile: { name, path, found } }\n}\n\n/** \"VERIS_API_KEY is not set, and …\" — the two places a key was looked for. */\nexport function missingKeyWhere(c: VerisCredentials): string {\n const where = c.profile.found\n ? `profile '${c.profile.name}' in ${c.profile.path} has no api_key`\n : `${c.profile.path} has no profile '${c.profile.name}'`\n return `VERIS_API_KEY is not set, and ${where}`\n}\n\n/** \"Run `veris login` … or set VERIS_API_KEY\" — where a key can come from. */\nexport const KEY_SOURCES_HINT =\n 'Run `veris login` (the veris CLI saves the key there; `--profile <name>` for another plane, ' +\n 'and VERIS_PROFILE picks it here), or set VERIS_API_KEY in the environment. ' +\n 'Get a key at https://studio.veris.ai'\n\n/**\n * What to say when no key was found anywhere: name every place one could\n * have come from, so the fix is on the screen. `veris login` is first because\n * it is the route that needs nothing typed into a shell.\n */\nexport function missingKeyMessage(c: VerisCredentials): string {\n return `no Veris API key: ${missingKeyWhere(c)}. ${KEY_SOURCES_HINT}`\n}\n\n/** resolveVerisCredentials, or a MissingCredentialsError that says where a key can come from. */\nexport function requireVerisCredentials(opts: ResolveOpts = {}): VerisCredentials & { apiKey: string } {\n const c = resolveVerisCredentials(opts)\n if (!c.apiKey) throw new MissingCredentialsError(missingKeyMessage(c), { phase: 'credentials' })\n return c as VerisCredentials & { apiKey: string }\n}\n","// The SDK version sent to the control plane as X-Veris-SDK (it version-gates\n// gateway mode on it). Injected from package.json at build time by tsup's\n// `define`; the fallback keeps `tsx`/vitest runs working from source.\ndeclare const __SDK_VERSION__: string | undefined\n\nexport const SDK_VERSION: string =\n typeof __SDK_VERSION__ === 'string' ? __SDK_VERSION__ : '0.0.0-dev'\n","// What the DAYTONA_API_KEY may do, read from Daytona itself.\n//\n// A key made with only \"write sandboxes\" creates boxes it can never delete:\n// DELETE /api/sandbox/<id> answers 403, which the SDK surfaced as a bare\n// `FAILED Access denied` from `teardown`, after the box existed and was\n// billing. GET /api/api-keys/current says which permissions a key holds, so\n// `provision` and `run` can say up front that teardown will not be possible —\n// before creating a box rather than after.\n//\n// Everything here is best effort. A permissions read that fails must not stop\n// a create that would have worked: the answer is a warning, never a gate.\n\nexport const DAYTONA_API_URL = 'https://app.daytona.io/api'\n\n/** The permission DELETE /api/sandbox/<id> checks for. */\nexport const DELETE_SANDBOXES = 'delete:sandboxes'\n\n/** The part of GET /api/api-keys/current this package reads. */\nexport interface DaytonaKeyInfo {\n name: string\n permissions: string[]\n}\n\n/** Where the Daytona API is, resolved the way @daytona/sdk resolves it. */\nexport function daytonaApiUrl(env: NodeJS.ProcessEnv = process.env): string {\n return (env.DAYTONA_API_URL || env.DAYTONA_SERVER_URL || DAYTONA_API_URL).replace(/\\/$/, '')\n}\n\n/**\n * The key's own record, or undefined when Daytona would not say — a network\n * error, a non-2xx, a body without a permissions list. Undefined means\n * \"unknown\", and a caller must not read it as \"cannot delete\".\n */\nexport async function fetchDaytonaKey(apiKey: string, apiUrl: string = daytonaApiUrl()): Promise<DaytonaKeyInfo | undefined> {\n try {\n const res = await fetch(`${apiUrl}/api-keys/current`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n })\n if (!res.ok) return undefined\n const body = await res.json() as { name?: unknown; permissions?: unknown }\n if (!Array.isArray(body.permissions)) return undefined\n return {\n name: typeof body.name === 'string' ? body.name : '',\n permissions: body.permissions.filter((p): p is string => typeof p === 'string'),\n }\n } catch {\n return undefined\n }\n}\n\n/** True, false, or undefined when the key's permissions are not known. */\nexport function canDeleteSandboxes(key: DaytonaKeyInfo | undefined): boolean | undefined {\n return key === undefined ? undefined : key.permissions.includes(DELETE_SANDBOXES)\n}\n\n/** `\"ci-key\" (permissions: write:sandboxes)` — how a message names the key. */\nexport function describeKey(key: DaytonaKeyInfo): string {\n const name = key.name ? `\"${key.name}\" ` : ''\n return `${name}(permissions: ${key.permissions.join(', ') || 'none'})`\n}\n\n/** How to get a key that can delete. One sentence, used wherever the lack is reported. */\nexport const DELETE_PERMISSION_FIX =\n 'create a key with the \"delete sandboxes\" permission at https://app.daytona.io/dashboard/keys'\n\n/**\n * The warning `provision` and `run` print before creating a box with a key\n * that cannot delete one. Says what will happen instead — the box's own\n * brakes — so the reader can decide whether that is good enough.\n */\nexport function cannotTeardownWarning(key: DaytonaKeyInfo, autoStopMinutes: number, autoDeleteMinutes: number): string {\n return (\n `DAYTONA_API_KEY ${describeKey(key)} lacks \\`${DELETE_SANDBOXES}\\`, so \\`veris-daytona teardown\\` ` +\n `will be refused for the sandbox about to be created, and \\`run\\` cannot delete its own. ` +\n `The box still stops after ${autoStopMinutes} idle minutes and is deleted ${autoDeleteMinutes} ` +\n `minutes after it stops. For a teardown that works, ${DELETE_PERMISSION_FIX} and use it instead.`\n )\n}\n","// `veris-daytona teardown <daytona-sandbox-id>`: delete a sandbox `provision`\n// (or `run --keep`) left behind.\n//\n// veris-daytona teardown 7f3c1e0a-…\n//\n// The twin is a separate question, and the answer is written on the sandbox:\n// a twin this package created goes with it, a twin it merely attached to is\n// the caller's and is left running. That is the same rule `sandbox.delete()`\n// has always followed — see verisOwnsTwin in daytona.ts — so teardown reads it\n// rather than restating it.\n//\n// Parsing and the refusal message are pure, so they are unit tested without a\n// Daytona account. Everything that touches the network is in cli.ts.\nimport { UsageError } from './run'\nimport { DELETE_PERMISSION_FIX, DELETE_SANDBOXES, describeKey } from './daytona-key'\nimport type { DaytonaKeyInfo } from './daytona-key'\n\nexport interface TeardownOptions {\n /** The Daytona sandbox id. Not the twin's. */\n sandboxId: string\n}\n\nexport const TEARDOWN_USAGE = `usage: veris-daytona teardown <daytona-sandbox-id>\n\nDeletes the Daytona sandbox. The id is the one \\`veris-daytona provision\\`\nprinted as daytonaSandboxId — not the Veris twin's id.\n\nThe twin follows the rule it was created under: one this package created is\ndeleted with the sandbox, one it attached to (\\`provision\\`, or \\`run --sandbox\\`)\nis yours and is left running. Which of the two happened is printed.\n\nneeds: DAYTONA_API_KEY with the ${DELETE_SANDBOXES} permission — a key made with\n\"write sandboxes\" alone is refused, and the refusal says when Daytona will stop\nand delete the box on its own. To reach a twin that must be deleted, a Veris\nkey too: VERIS_API_KEY, or the profile \\`veris login\\` saved.\n\nexit code: 0 when the sandbox is deleted; 1 when there is no such sandbox, or\nthe key may not delete one.`\n\n/** The facts a refused delete is described from. Intervals are the sandbox's own. */\nexport interface RefusedTeardown {\n /** The Daytona sandbox id. */\n sandboxId: string\n twinId?: string\n /** Whether the wrapped delete removed the twin before Daytona refused the\n * sandbox — it deletes the twin first, so an owned twin is already gone. */\n ownsTwin: boolean\n /** Daytona's `autoStopInterval`: idle minutes before it stops. 0 is off. */\n autoStopMinutes?: number\n /** Daytona's `autoDeleteInterval`: minutes after stopping before it is\n * deleted. 0 is at once; negative or unset is never. */\n autoDeleteMinutes?: number\n /** Daytona's `autoDestroyAt`, when a TTL was set. */\n expiresAt?: string\n /** The key's record, when GET /api/api-keys/current answered. */\n key?: DaytonaKeyInfo\n}\n\n/**\n * Was this Daytona's \"you may not\" — HTTP 403 — rather than any other failure?\n * Read off the status the SDK stamps rather than a class, so the check holds\n * across the SDK's own renamings (DaytonaAuthorizationError became\n * DaytonaForbiddenError) and for an error that crossed a package boundary.\n */\nexport function isPermissionDenied(e: unknown): boolean {\n return typeof e === 'object' && e !== null && (e as { statusCode?: unknown }).statusCode === 403\n}\n\n/**\n * What Daytona will do to the box on its own, in one clause: \"stops after 30\n * idle minutes and is deleted 60 minutes after it stops, and is destroyed at\n * <time> whatever state it is in\". This is the substance of a refusal — the\n * reader's real question is whether the box bills forever, and the answer is\n * on the sandbox object.\n */\nexport function sandboxBrakes(r: Pick<RefusedTeardown, 'autoStopMinutes' | 'autoDeleteMinutes' | 'expiresAt'>): string {\n const stop = r.autoStopMinutes && r.autoStopMinutes > 0\n ? `stops after ${r.autoStopMinutes} idle minutes`\n : 'never stops on its own'\n const del = r.autoDeleteMinutes === undefined || r.autoDeleteMinutes < 0\n ? 'is never auto-deleted'\n : r.autoDeleteMinutes === 0\n ? 'is deleted as soon as it stops'\n : `is deleted ${r.autoDeleteMinutes} minutes after it stops`\n const destroy = r.expiresAt ? `, and is destroyed at ${r.expiresAt} whatever state it is in` : ''\n return `${stop} and ${del}${destroy}`\n}\n\n/**\n * What `teardown` says when Daytona answered 403.\n *\n * The bare \"FAILED Access denied\" this replaces named neither the cause nor the\n * consequence. The cause is a key without `delete:sandboxes` — the one\n * permission DELETE /api/sandbox/<id> checks, and one a key made with \"write\n * sandboxes\" alone does not have. The consequence is a box that is still there\n * and still billing, so the message says exactly when Daytona will stop and\n * delete it by itself, what happened to the twin, and how to delete it sooner.\n */\nexport function teardownRefusedMessage(r: RefusedTeardown): string {\n const key = r.key\n ? `this DAYTONA_API_KEY ${describeKey(r.key)} lacks the \\`${DELETE_SANDBOXES}\\` permission`\n : `Daytona answered 403 (Access denied), which is what a DAYTONA_API_KEY without the ` +\n `\\`${DELETE_SANDBOXES}\\` permission gets — the key's own record could not be read to confirm it`\n const twin = r.twinId === undefined\n ? ''\n : r.ownsTwin\n ? ` Its twin ${r.twinId} was deleted before Daytona refused, so nothing is left on the Veris side.`\n : ` Twin ${r.twinId} is yours and was not touched.`\n return (\n `Daytona refused to delete sandbox ${r.sandboxId}: ${key}. ` +\n `The sandbox is still there: it ${sandboxBrakes(r)}.${twin} ` +\n `To delete it sooner, ${DELETE_PERMISSION_FIX}, then run \\`veris-daytona teardown ${r.sandboxId}\\` ` +\n `with it — or delete the sandbox in the Daytona dashboard.`\n )\n}\n\n/** Parse everything after `teardown`. Pure; throws UsageError with a human message. */\nexport function parseTeardownArgs(argv: readonly string[]): TeardownOptions {\n const ids: string[] = []\n for (const arg of argv) {\n if (arg === '-h' || arg === '--help') throw new UsageError(TEARDOWN_USAGE)\n if (arg.startsWith('-')) throw new UsageError(`unknown option '${arg}'\\n\\n${TEARDOWN_USAGE}`)\n ids.push(arg)\n }\n if (ids.length === 0) throw new UsageError(`no sandbox id given\\n\\n${TEARDOWN_USAGE}`)\n // One at a time, on purpose: the message says which twin was and was not\n // touched, and that sentence is only true of a single sandbox.\n if (ids.length > 1) {\n throw new UsageError(`teardown takes one sandbox id, got ${ids.length}: ${ids.join(' ')}`)\n }\n return { sandboxId: ids[0]! }\n}\n"],"mappings":";AA0BA,cAAc;;;ACbd,SAAS,WAAW,mBAAmB;;;ACkBvC,SAAS,UAAU,SAAiB,OAAwB;AAC1D,QAAM,SACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,UAAU,WAAW,QAAQ;AAE/E,MAAI,CAAC,UAAU,QAAQ,SAAS,MAAM,EAAG,QAAO;AAChD,QAAM,UAAU,OAAO,SAAS,MAAM,GAAG,OAAO,MAAM,GAAG,GAAG,CAAC,WAAM;AACnE,SAAO,GAAG,OAAO,KAAK,OAAO;AAC/B;AAEO,IAAM,aAAN,cAAyB,MAAM;AAAA,EAC3B;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,OAAsG,CAAC,GACvG;AACA,UAAM,UAAU,SAAS,KAAK,KAAK,GAAG,KAAK,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,IAAI,MAAS;AAClG,SAAK,OAAO,WAAW;AACvB,SAAK,QAAQ,KAAK;AAClB,SAAK,iBAAiB,KAAK;AAC3B,SAAK,eAAe,KAAK;AAAA,EAC3B;AACF;AAGO,IAAM,0BAAN,cAAsC,WAAW;AAAC;AAGlD,IAAM,+BAAN,cAA2C,WAAW;AAAC;AAGvD,IAAM,8BAAN,cAA0C,WAAW;AAAA;AAAA,EAEjD;AAAA,EACT,YAAY,SAAiB,OAA0E,CAAC,GAAG;AACzG,UAAM,SAAS,IAAI;AACnB,SAAK,SAAS,KAAK;AAAA,EACrB;AACF;AAGO,IAAM,wBAAN,cAAoC,WAAW;AAAC;AAGhD,IAAM,sBAAN,cAAkC,WAAW;AAAA,EACzC;AAAA,EACT,YAAY,SAAiB,SAAiB,OAAoD,CAAC,GAAG;AACpG,UAAM,SAAS,IAAI;AACnB,SAAK,UAAU;AAAA,EACjB;AACF;AAGO,IAAM,mBAAN,cAA+B,WAAW;AAAC;AAI3C,IAAM,2BAAN,cAAuC,WAAW;AAAC;AAGnD,IAAM,4BAAN,cAAwC,WAAW;AAAC;;;ACf3D,IAAM,QAAQ,CAAC,OAAe,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAE3D,IAAM,eAAN,MAAmB;AAAA,EACf;AAAA,EACQ;AAAA,EAEjB,YAAY,MAAwB;AAClC,SAAK,UAAU,KAAK,QAAQ,QAAQ,OAAO,EAAE;AAC7C,SAAK,UAAU;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,eAAe,KAAK;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAc,QAAQ,QAAgB,MAAc,MAAmC;AACrF,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,QAC1C;AAAA,QACA,SAAS,KAAK;AAAA,QACd,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,MAC5D,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,IAAI,WAAW,oCAAoC,MAAM,IAAI,IAAI,KAAK,EAAE,MAAM,CAAC;AAAA,IACvF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,KAAQ,KAAe,SAAiB,OAAwD;AAC5G,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI;AACJ,QAAI;AAAE,eAAS,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,IAAU,QAAQ;AAAE,eAAS;AAAA,IAAK;AAC3E,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,WAAW,GAAG,OAAO,KAAK,IAAI,MAAM,IAAI,EAAE,OAAO,cAAc,OAAO,CAAC;AAAA,IACnF;AAGA,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,WAAW,GAAG,OAAO,yBAAyB,EAAE,OAAO,cAAc,KAAK,CAAC;AAAA,IACvF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,eAAuB,OAAmE,CAAC,GAAyB;AACnI,UAAM,MAAM,MAAM,KAAK,QAAQ,QAAQ,oBAAoB,aAAa,cAAc;AAAA,MACpF,aAAa,KAAK;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB,CAAC;AAMD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI;AAAA,QACR,gBAAgB,aAAa,uBAAuB,KAAK,OAAO;AAAA,QAGhE,EAAE,OAAO,kBAAkB,cAAc,MAAM,IAAI,KAAK,EAAE;AAAA,MAAC;AAAA,IAC/D;AACA,WAAO,KAAK,KAAkB,KAAK,iCAAiC,aAAa,IAAI,gBAAgB;AAAA,EACvG;AAAA,EAEA,MAAM,QAAQ,WAAgD;AAC5D,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,iBAAiB,SAAS,EAAE;AAClE,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,WAAO,KAAK,KAAkB,KAAK,eAAe,SAAS,EAAE;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,UAAU,WAAmB,WAAyC;AAC1E,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,eAAS;AACP,YAAM,OAAO,MAAM,KAAK,QAAQ,SAAS;AACzC,UAAI,CAAC,KAAM,OAAM,IAAI,iBAAiB,iBAAiB,SAAS,mCAAmC,EAAE,gBAAgB,UAAU,CAAC;AAChI,UAAI,KAAK,WAAW,QAAS,QAAO;AACpC,UAAI,KAAK,WAAW,UAAU;AAC5B,cAAM,IAAI;AAAA,UACR,iBAAiB,SAAS,yBAAyB,KAAK,kBAAkB,mBAAmB;AAAA,UAC7F,EAAE,OAAO,kBAAkB,gBAAgB,UAAU;AAAA,QAAC;AAAA,MAC1D;AACA,UAAI,KAAK,IAAI,IAAI,UAAU;AACzB,cAAM,IAAI;AAAA,UACR,iBAAiB,SAAS,oBAAoB,SAAS,eAAe,KAAK,MAAM;AAAA,UACjF,EAAE,OAAO,kBAAkB,gBAAgB,UAAU;AAAA,QAAC;AAAA,MAC1D;AACA,YAAM,MAAM,IAAI;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,WAA2C;AACxD,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,iBAAiB,SAAS,WAAW;AAC3E,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,SAAS,wCAAmC,EAAE,gBAAgB,UAAU,CAAC;AAAA,IACvH;AACA,WAAO,KAAK,KAAoB,KAAK,uBAAuB,SAAS,IAAI,SAAS;AAAA,EACpF;AAAA,EAEA,MAAM,WAAW,eAAuB,WAAqC;AAC3E,UAAM,MAAM,MAAM,KAAK,QAAQ,UAAU,oBAAoB,aAAa,cAAc,SAAS,EAAE;AACnG,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,KAAK,kBAAkB,SAAS,EAAE;AAC/D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,qBAAqB,eAAuB,WAAqD;AACrG,UAAM,MAAM,MAAM,KAAK,QAAQ,QAAQ,oBAAoB,aAAa,cAAc,SAAS,oBAAoB;AACnH,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC9C,YAAM,IAAI;AAAA,QACR,yEAAyE,KAAK,UAAU,aAAa,KAAK,OAAO,MAAM,EAAE;AAAA,QACzH,EAAE,OAAO,mBAAmB,gBAAgB,WAAW,QAAQ,KAAK,SAAS,cAAc,KAAK;AAAA,MAAC;AAAA,IACrG;AACA,WAAO,KAAK,KAAuB,KAAK,8BAA8B,SAAS,IAAI,iBAAiB;AAAA,EACtG;AAAA;AAAA,EAGA,MAAM,cAAc,eAAuB,WAAmB,OAAoC;AAChG,UAAM,MAAM,MAAM,KAAK,QAAQ,SAAS,oBAAoB,aAAa,cAAc,SAAS,IAAI,KAAK;AACzG,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,IAAI,iBAAiB,iBAAiB,SAAS,cAAc,EAAE,gBAAgB,UAAU,CAAC;AAAA,IAClG;AACA,QAAI,CAAC,IAAI,GAAI,OAAM,KAAK,KAAK,KAAK,kBAAkB,SAAS,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,gBAA+B;AACnC,UAAM,MAAM,MAAM,KAAK,QAAQ,OAAO,oBAAoB;AAC1D,QAAI,IAAI,WAAW,IAAK;AACxB,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI;AAAA,QACR,qCAAqC,IAAI,MAAM;AAAA,QAAK,EAAE,OAAO,oBAAoB;AAAA,MAAC;AAAA,IACtF;AAAA,EACF;AACF;;;AC1OA,SAAS,kBAAkB;;;AC+D3B,IAAM,aAAa;AACnB,IAAM,YAAY;AAGX,SAAS,OAAO,MAAyB;AAC9C,MAAI,CAAC,QAAQ,CAAC,MAAM,QAAS,KAAgC,QAAQ,GAAG;AACtE,UAAM,IAAI,WAAW,gDAAgD,EAAE,OAAO,UAAU,CAAC;AAAA,EAC3F;AACA,QAAM,OAAQ,KAAgC;AAC9C,aAAW,KAAK,MAAM;AACpB,QAAI,CAAC,KAAK,CAAC,OAAO,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,EAAE,WAAW,YACtE,OAAO,EAAE,SAAS,YAAY,OAAO,EAAE,SAAS,YAChD,EAAE,EAAE,WAAW,QAAQ,OAAO,EAAE,WAAW,WAAW;AACxD,YAAM,IAAI,WAAW,8EAA8E,EAAE,OAAO,UAAU,CAAC;AAAA,IACzH;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,MAA4E;AAC5G,QAAM,OAAO,OAAO,IAAI;AACxB,QAAM,UAAU,KAAK;AAAA,IAAO,OAC1B,CAAC,WAAW,SAAS,YAAY,gBAAgB,iBAAiB,EAAE,SAAS,EAAE,IAAI,KACnF,CAAC,mBAAmB,KAAK,EAAE,IAAI;AAAA,EACjC,EAAE,IAAI,CAAC,EAAE,IAAI,QAAQ,MAAM,QAAQ,KAAK,OAAO,EAAE,IAAI,QAAQ,MAAM,QAAQ,KAAK,EAAE;AAClF,SAAO,EAAE,OAAO,QAAQ,QAAQ,SAAS,OAAO,KAAK,OAAO;AAC9D;AAEA,eAAsB,SAAS,KAAkB,OAA2C;AAC1F,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,YAAY,QAAQ,OAAO,EAAE,CAAC,mBAAmB,KAAK,IAAI;AAAA,IACvF,QAAQ,YAAY,QAAQ,GAAM;AAAA,IAAG,UAAU;AAAA,EACjD,CAAC;AACD,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,WAAW,uCAAuC,IAAI,IAAI,MAAM,IAAI,MAAM,KAAK,EAAE,OAAO,UAAU,CAAC;AAC1H,MAAI;AACJ,MAAI;AAAE,WAAO,KAAK,MAAM,IAAI;AAAA,EAAE,QAAQ;AACpC,UAAM,IAAI,WAAW,YAAY,IAAI,IAAI,sCAAsC,EAAE,OAAO,UAAU,CAAC;AAAA,EACrG;AACA,SAAO,OAAO,IAAI;AACpB;AAEA,eAAsB,eAAe,KAAmC;AACtE,QAAM,OAAO,MAAM,SAAS,KAAK,IAAI,gBAAgB,EAAE,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC;AACnF,MAAI,KAAK,SAAS,EAAG,OAAM,IAAI,WAAW,uCAAuC,EAAE,OAAO,UAAU,CAAC;AACrG,SAAO,KAAK,CAAC,GAAG,MAAM;AACxB;AAIA,eAAsB,kBAAkB,KAAkB,UAAU,GAA0B;AAC5F,MAAI,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,EAAG,OAAM,IAAI,WAAW,6BAA6B,EAAE,OAAO,UAAU,CAAC;AACzH,QAAM,MAAM,MAAM,eAAe,GAAG;AACpC,MAAI,MAAM,QAAS,OAAM,IAAI,WAAW,sEAAsE,EAAE,OAAO,UAAU,CAAC;AAClI,QAAM,UAA4B,CAAC;AACnC,QAAM,MAAgB,CAAC;AACvB,MAAI,OAAO;AACX,MAAI;AACJ,WAAS,OAAO,GAAG,OAAO,KAAK,QAAQ;AACrC,QAAI,QAAQ,WAAW;AAAE,yBAAmB;AAAc;AAAA,IAAM;AAChE,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,SAAS,KAAK,IAAI,gBAAgB,EAAE,OAAO,OAAO,UAAU,GAAG,OAAO,OAAO,UAAU,OAAO,IAAI,EAAE,CAAC,CAAC;AAAA,IACrH,SAAS,OAAO;AACd,UAAI,CAAC,IAAI,OAAQ,OAAM;AACvB,yBAAmB;AAAe;AAAA,IACpC;AAGA,QAAI,WAAW;AACf,QAAI,CAAC,KAAK,UAAU,KAAK,KAAK,OAAK;AAAE,YAAM,MAAM,EAAE,MAAM;AAAU,iBAAW,EAAE;AAAI,aAAO;AAAA,IAAI,CAAC,GAAG;AACjG,yBAAmB;AAA8B;AAAA,IACnD;AACA,UAAM,SAAS,KAAK,OAAO,OAAK,EAAE,MAAM,GAAG;AAC3C,QAAI,KAAK,GAAG,MAAM;AAClB,YAAQ,KAAK,GAAG,kBAAkB,EAAE,UAAU,OAAO,CAAC,EAAE,OAAO;AAC/D,WAAO,KAAK,KAAK,SAAS,CAAC,EAAG;AAAA,EAChC;AACA,UAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;AAClC,SAAO;AAAA,IAAE,UAAU,QAAQ;AAAA,IAAQ,YAAY,IAAI;AAAA,IAAa;AAAA,IAC9D;AAAA,IAAS,SAAS;AAAA,IAAK,QAAQ,QAAQ,gBAAgB;AAAA,IAAG,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,IAAI,KAAK,EAAE,UAAU,IAAI;AAAA,EAAE;AACxI;;;ADpIA,IAAM,SAAS;AACf,SAAS,SAAS,KAA0C;AAC1D,MAAI;AACF,UAAM,UAAU,OAAO,IAAI,oBAAoB,WAAW,KAAK,MAAM,IAAI,eAAe,IAAI,IAAI;AAChG,WAAO,UAAU,MAAM;AAAA,EACzB,QAAQ;AAAE,WAAO;AAAA,EAAU;AAC7B;AAEA,eAAsB,gBAAgB,QAAgB,WAAmB,UAAmD;AAC1H,QAAM,QAAQ,MAAM,QAAQ,IAAI,SAAS,IAAI,OAAM,QAAO;AACxD,UAAM,SAAS,WAAW;AAC1B,UAAM,MAAM,MAAM,MAAM,GAAG,IAAI,YAAY,QAAQ,OAAO,EAAE,CAAC,iBAAiB;AAAA,MAC5E,SAAS,EAAE,CAAC,MAAM,GAAG,OAAO;AAAA,MAAG,QAAQ,YAAY,QAAQ,GAAM;AAAA,MAAG,UAAU;AAAA,IAChF,CAAC;AACD,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,IAAI,GAAI,OAAM,IAAI,WAAW,qCAAqC,IAAI,IAAI,MAAM,IAAI,MAAM,KAAK,EAAE,OAAO,UAAU,CAAC;AAGxH,aAAS,UAAU,GAAG,UAAU,GAAG,WAAW;AAC5C,YAAM,OAAO,MAAM,SAAS,KAAK,IAAI,gBAAgB,EAAE,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC;AACtF,YAAM,SAAS,KAAK,KAAK,OAAK,SAAS,CAAC,MAAM,UAAU,EAAE,SAAS,aAAa,EAAE,SAAS,eAAe;AAC1G,UAAI,OAAQ,QAAO,CAAC,IAAI,MAAM,EAAE,YAAY,IAAI,aAAa,IAAI,OAAO,IAAI,OAAO,CAAC;AACpF,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AAAA,IACtD;AACA,UAAM,IAAI,WAAW,6BAA6B,IAAI,IAAI,gDAAgD,EAAE,OAAO,UAAU,CAAC;AAAA,EAChI,CAAC,CAAC;AACF,SAAO,EAAE,SAAS,GAAG,QAAQ,WAAW,UAAU,OAAO,YAAY,KAAK,EAAE;AAC9E;AAEA,eAAsB,iBAAiB,UAA2B,QAAgB,WAAmB,UAAwC;AAC3I,QAAM,UAAU,MAAM,IAAI,WAAW,wGAAwG,EAAE,OAAO,UAAU,CAAC;AACjK,MAAI,SAAS,YAAY,KAAK,SAAS,WAAW,UAAU,SAAS,cAAc,aAC/E,OAAO,KAAK,SAAS,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,MAAM,SAAS,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,EAAG,OAAM,QAAQ;AACpH,QAAM,QAAQ,IAAI,SAAS,IAAI,OAAM,QAAO;AAC1C,UAAM,OAAO,SAAS,SAAS,IAAI,IAAI;AACvC,QAAI,CAAC,QAAQ,KAAK,eAAe,IAAI,eAAe,CAAC,OAAO,cAAc,KAAK,EAAE,KAAK,KAAK,MAAM,EAAG,OAAM,QAAQ;AAClH,UAAM,OAAO,MAAM,SAAS,KAAK,IAAI,gBAAgB,EAAE,OAAO,KAAK,OAAO,OAAO,UAAU,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;AACjH,QAAI,KAAK,WAAW,KAAK,KAAK,CAAC,EAAG,OAAO,KAAK,MAAM,SAAS,KAAK,CAAC,CAAE,MAAM,KAAK,OAAQ,OAAM,QAAQ;AAAA,EACxG,CAAC,CAAC;AACJ;;;AE1CA,eAAsB,eAAe,KAAkB,UAA2B,UAA0B,CAAC,GAAqB;AAChI,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,CAAC,UAAU,UAAU,cAAc,QAAQ,UAAU,EAAE,SAAS,QAAQ,KACzE,CAAC,CAAC,OAAO,QAAQ,OAAO,EAAE,SAAS,MAAM,KAAM,WAAW,SAAS,aAAa,UAC/E,WAAW,SAAS,QAAQ,SAAS,UAAc,CAAC,eAAe,KAAK,IAAI,WAAW,GAAG;AAC7F,UAAM,IAAI,WAAW,uCAAuC;AAAA,EAC9D;AACA,QAAM,MAAM,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,OAAO,EAAE,CAAC,UAAU,QAAQ,EAAE;AAC7E,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAAG,KAAI,aAAa,IAAI,KAAK,KAAK;AAC/F,QAAM,MAAM,MAAM,MAAM,KAAK;AAAA,IAAE;AAAA,IAAQ,UAAU;AAAA,IAAS,QAAQ,YAAY,QAAQ,GAAM;AAAA,IAC1F,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,QAAQ,SAAS,SAAY,SAAY,KAAK,UAAU,QAAQ,IAAI;AAAA,EAAE,CAAC;AAC/E,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,WAAW,YAAY,IAAI,IAAI,KAAK,MAAM,WAAW,QAAQ,YAAY,IAAI,MAAM,GAAG;AAC7G,MAAI;AAAE,WAAO,KAAK,MAAM,IAAI;AAAA,EAAE,QAAQ;AAAE,UAAM,IAAI,WAAW,YAAY,IAAI,IAAI,iCAAiC;AAAA,EAAE;AACtH;;;ACRO,IAAM,YAAY,CAAC,MAAc,WAAW,KAAK,CAAC;AAOlD,SAAS,YAAY,UAAmC;AAC7D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,eAAW,KAAK,IAAI,UAAU,CAAC,EAAG,OAAM,IAAI,EAAE,IAAI;AAAA,EACpD;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAGO,SAAS,UAAU,UAAmC;AAC3D,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,eAAW,KAAK,CAAC,IAAI,aAAa,IAAI,GAAG,GAAG;AAC1C,UAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAG;AACzB,UAAI;AAAE,cAAM,IAAI,IAAI,IAAI,CAAC,EAAE,QAAQ;AAAA,MAAE,QAAQ;AAAA,MAAyB;AAAA,IACxE;AAAA,EACF;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAmBO,SAAS,gBAAgB,UAAmC;AACjE,SAAO,UAAU,SAAS,OAAO,CAAC,MAAM,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC;AACvF;AAYO,SAAS,eAAe,UAAmC;AAChE,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,IAAI,OAAO,UAAU,IAAI,GAAG,EAAG;AACpC,eAAW,KAAK,aAAa,IAAI,GAAG,EAAG,OAAM,IAAI,CAAC;AAAA,EACpD;AACA,SAAO,CAAC,GAAG,KAAK,EAAE,KAAK;AACzB;AAEA,SAAS,aAAa,KAAuB;AAC3C,QAAM,MAAgB,CAAC;AACvB,MAAI;AACF,UAAM,IAAI,IAAI,IAAI,GAAG;AAErB,QAAI,EAAE,SAAU,KAAI,KAAK,EAAE,SAAS,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC7D,QAAQ;AAAA,EAER;AAGA,QAAM,YAAY,IAAI,QAAQ,eAAe,EAAE,EAAE,MAAM,MAAM,EAAE,CAAC,KAAK;AACrE,QAAM,UAAU,UAAU,SAAS,GAAG,IAAI,UAAU,MAAM,UAAU,YAAY,GAAG,IAAI,CAAC,IAAI;AAC5F,aAAW,QAAQ,QAAQ,MAAM,GAAG,GAAG;AACrC,UAAM,IAAI,KAAK,MAAM,sCAAsC;AAC3D,QAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,EAAG,KAAI,KAAK,EAAE,CAAC,EAAE,QAAQ,YAAY,EAAE,CAAC;AAAA,EAC1E;AACA,SAAO;AACT;AAOO,SAAS,aAAa,UAAiD;AAC5E,QAAM,OAA+B,CAAC;AACtC,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,IAAI,YAAY,CAAC,IAAI,OAAO,UAAU,IAAI,GAAG,EAAG;AAIrD,QAAI,CAAC,cAAc,IAAI,QAAQ,EAAG;AAClC,SAAK,IAAI,QAAQ,IAAI,IAAI;AAAA,EAC3B;AACA,SAAO;AACT;AAIA,IAAM,sBAAsB,oBAAI,IAAI;AAAA,EAClC;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAmB;AAAA,EAAgB;AAAA,EAAY;AAAA,EACrE;AAAA,EAAc;AAAA,EAAiB;AAAA,EAAS;AAAA,EAAO;AAAA,EAAQ;AACzD,CAAC;AACM,SAAS,cAAc,MAAuB;AACnD,SAAO,yBAAyB,KAAK,IAAI,KAAK,CAAC,oBAAoB,IAAI,IAAI;AAC7E;AAmBA,IAAM,UAAU;AAyBT,SAAS,aAAa,MAAqC;AAChE,QAAM,EAAE,MAAM,YAAAA,YAAW,IAAI;AAC7B,MAAI,SAAS,OAAQ,QAAO,EAAE,QAAQ,CAAC,EAAE;AACzC,QAAM,MAAM,CAAC,GAAG,IAAI,IAAIA,WAAU,CAAC;AACnC,MAAI,CAAC,IAAI,QAAQ;AACf,UAAM,IAAI;AAAA,MACR;AAAA,MAIA,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,QAAM,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;AAChD,MAAI,IAAI,QAAQ;AACd,UAAM,IAAI;AAAA,MACR,mEAAmE,KAAK,UAAU,GAAG,CAAC;AAAA,MAEtF,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,SAAO,EAAE,QAAQ,EAAE,kBAAkB,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG,EAAE,EAAE;AAC/E;;;ACvLA,SAAS,YAAY,WAAW;;;ACLzB,IAAM,eAAe;AAGrB,IAAM,gBAAgB;AAGtB,IAAM,gBAAgB;AAWtB,IAAM,eAAe;AAqBrB,SAAS,mBAA2C;AACzD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,mBAAmB;AAAA,IACnB,kCAAkC;AAAA,IAClC,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,yBAAyB;AAAA,IACzB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,oCAAoC;AAAA,IACpC,qBAAqB;AAAA,EACvB;AACF;AAkBO,SAAS,aAAa,MAA8B,iBAAiB,GAAW;AACrF,SAAO,OAAO,QAAQ,GAAG,EACtB,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,QAAQ,MAAM,OAAO,CAAC,IAAI,EAC5D,KAAK,GAAG;AACb;AAmBO,IAAM,mBAA+D;AAAA,EAC1E,EAAE,KAAK,0BAA0B,QAAQ,iCAAiC;AAAA,EAC1E,EAAE,KAAK,WAAW,QAAQ,qBAAqB;AAAA,EAC/C,EAAE,KAAK,YAAY,QAAQ,sBAAsB;AAAA;AAAA,EAEjD,EAAE,KAAK,UAAU,QAAQ,kCAAkC;AAAA,EAC3D,EAAE,KAAK,YAAY,QAAQ,uBAAuB;AACpD;AAKO,IAAM,0BAA0B;AAchC,IAAM,4BAA4B;AAmBlC,SAAS,uBAA+B;AAC7C,QAAM,OAAO,iBACV,IAAI,CAAC,MACJ,mFACY,EAAE,MAAM,8BAA8B,EACnD,KAAK,IAAI;AACZ,SAAO;AAAA,IACL,sBAAsB,aAAa;AAAA;AAAA;AAAA,IAGnC,kCAAkC,aAAa;AAAA;AAAA;AAAA;AAAA,IAI/C,KAAK,IAAI;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,yBAAyB,aAAa;AAAA,IACtC;AAAA,IACA,WAAW,yBAAyB;AAAA,IACpC;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AA2BO,IAAM,kBAAkB;AAGxB,SAAS,qBAAqB,UAA2B;AAC9D,QAAM,QAAQ,YAAY,IAAI,KAAK;AACnC,MAAI,KAAK,MAAM,KAAK,EAAE,SAAS,eAAe,EAAG,QAAO;AACxD,SAAO,OAAO,GAAG,IAAI,IAAI,eAAe,KAAK;AAC/C;AAaO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA,kFAAkF,YAAY;AAAA,EAC9F,8KAEsC,YAAY;AACpD,EAAE,KAAK,MAAM;AAUN,SAAS,iBAAiB,QAAqE;AACpG,QAAM,WAAW,iBAAiB;AAIlC,QAAM,MAA8B,EAAE,GAAG,SAAS;AAClD,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AACnD,QAAI,EAAE,KAAK,UAAW;AACtB,QAAI,OAAO,QAAQ,SAAU;AAE7B,QAAI,CAAC,iBAAiB,KAAK,GAAG,EAAG;AACjC,QAAI,CAAC,IAAI;AAAA,EACX;AACA,SAAO;AACT;;;AD7OA,IAAM,cAAc;AAEpB,IAAM,cAAc;AAGb,SAAS,WAAW,GAAmB;AAC5C,SAAO,IAAI,EAAE,QAAQ,MAAM,OAAO,CAAC;AACrC;AAEA,IAAM,KAAK,CAAC,SAAkB,KAAa,aAAa,OACtD,QAAQ,QAAQ,eAAe,UAAU,WAAW,GAAG,CAAC,IAAI,QAAW,QAAW,UAAU;AAqBvF,SAAS,gBAAgB,YAIrB;AAIT,MAAI,WAAW,eAAgB,QAAO,eAAe,WAAW,cAAc;AAE9E,MAAI,CAAC,WAAW,mBAAmB,CAAC,YAAY,KAAK,WAAW,eAAe,GAAG;AAChF,UAAM,IAAI;AAAA,MACR,2DACG,KAAK,UAAU,WAAW,eAAe,CAAC;AAAA,MAC7C,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,SAAO,UAAU,mBAAmB,WAAW,QAAQ,CAAC,MAAM,WAAW,eAAe;AAC1F;AAYA,eAAsB,WACpB,YACA,UACmB;AACnB,MAAI,WAAW,aAAa,OAAQ,QAAO,WAAW;AACtD,QAAM,OAAO,IAAI,IAAI,QAAQ,EAAE;AAC/B,MAAI,uBAAuB,KAAK,IAAI,EAAG,QAAO,CAAC,IAAI;AACnD,MAAI;AAAE,WAAO,MAAM,IAAI,SAAS,IAAI;AAAA,EAAE,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAE;AAC5D;AAOA,SAAS,eAAe,KAAqB;AAC3C,MAAI;AACJ,MAAI;AAAE,QAAI,IAAI,IAAI,GAAG;AAAA,EAAE,QAAQ;AAC7B,UAAM,IAAI;AAAA,MACR,gEAAgE,KAAK,UAAU,GAAG,CAAC;AAAA,MACnF,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,MAAI,EAAE,aAAa,WAAW,EAAE,aAAa,UAAU;AACrD,UAAM,IAAI;AAAA,MACR,sCAAsC,EAAE,SAAS,QAAQ,KAAK,EAAE,CAAC;AAAA,MAEjE,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,MAAI,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM;AAC1B,UAAM,IAAI;AAAA,MACR,oDAAoD,KAAK,UAAU,GAAG,CAAC;AAAA,MACvE,EAAE,OAAO,kBAAkB;AAAA,IAAC;AAAA,EAChC;AACA,SAAO;AACT;AAgCA,eAAsB,UAAU,SAAkB,OAA8B;AAC9E,QAAM,QAAQ,GAAG,WAAW,OAAO,KAAK,OAAO,MAAM,GAAG,aAAa;AAMrE,QAAM,QAAQ,GAAG,WAAW,OAAO,KAAK,qBAAqB,GAAG,MAAM,GAAG,uBAAuB;AAEhG,QAAM,SAAS;AAAA,IACb,cAAc,aAAa;AAAA;AAAA;AAAA;AAAA,IAI3B,SAAS,aAAa,qBAAqB,aAAa,SAAS,YAAY;AAAA,IAC7E,cAAc,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM1B;AAAA,IACA,6BAA6B,aAAa,IAAI,YAAY,+BACzC,WAAW,cAAc,CAAC;AAAA;AAAA,IAE3C,QAAQ,YAAY;AAAA,EACtB,EAAE,KAAK,IAAI;AAEX,QAAM,IAAI,MAAM,GAAG,SAAS,QAAQ,GAAG,EAAE,MAAM,CAAC,OAAgB,EAAE,UAAU,GAAG,QAAQ,OAAO,CAAC,EAAE,EAAE;AACnG,MAAI,EAAE,EAAE,UAAU,IAAI,SAAS,iBAAiB,GAAG;AACjD,UAAM,IAAI;AAAA,MACR,qCAAqC,YAAY,uDAC1B,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,MAC3D,EAAE,OAAO,aAAa;AAAA,IAAC;AAAA,EAC3B;AACF;AAmBA,eAAsB,gBAAgB,SAAqC;AACzE,QAAM,IAAI,MAAM,GAAG,SAAS,MAAM,uBAAuB,IAAI,GAAG,EAC7D,MAAM,CAAC,OAAgB,EAAE,UAAU,GAAG,QAAQ,OAAO,CAAC,EAAE,EAAE;AAC7D,UAAQ,EAAE,UAAU,IACjB,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAK,WAAW,yBAAyB,CAAC,EAC3D,IAAI,CAAC,SAAS,KAAK,MAAM,0BAA0B,MAAM,EAAE,KAAK,CAAC,EACjE,OAAO,OAAO;AACnB;AAWA,eAAsB,YACpB,SACA,YACA,gBACe;AACf,MAAI,CAAC,YAAY,KAAK,UAAU,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,qEAAqE,KAAK,UAAU,UAAU,CAAC;AAAA,MAC/F,EAAE,OAAO,UAAU,gBAAgB,eAAe;AAAA,IAAC;AAAA,EACvD;AAGA,QAAM,IAAI,MAAM;AAAA,IACd;AAAA,IACA,qBAAqB,YAAY,0BAA0B,UAAU;AAAA,IACrE;AAAA,EACF,EAAE,MAAM,CAAC,OAAgB,EAAE,UAAU,GAAG,QAAQ,OAAO,CAAC,EAAE,EAAE;AAE5D,MAAI,OAAsC,CAAC;AAC3C,MAAI;AAAE,WAAO,KAAK,MAAM,EAAE,UAAU,EAAE;AAAA,EAAE,QAAQ;AAAA,EAAsB;AACtE,MAAI,KAAK,qBAAqB,gBAAgB;AAC5C,UAAM,IAAI;AAAA,MACR,mHACgC,cAAc,uBAC1C,EAAE,UAAU,WAAW,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;AAAA,MAC/C,EAAE,OAAO,UAAU,gBAAgB,eAAe;AAAA,IAAC;AAAA,EACvD;AACF;;;AElOO,SAAS,uBAAuB,KAAwB;AAC7D,MAAI,CAAC,IAAI,eAAe,CAAC,UAAU,IAAI,WAAW,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,YAAY,IAAI,IAAI;AAAA,MACpB,EAAE,OAAO,aAAa;AAAA,IACxB;AAAA,EACF;AACF;AAOA,eAAsB,YAAY,KAAmC;AACnE,yBAAuB,GAAG;AAC1B,QAAM,MAAM,MAAM,MAAM,GAAG,IAAI,WAAW,eAAe;AACzD,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,WAAW,0CAA0C,IAAI,IAAI,MAAM,IAAI,MAAM,KAAK;AAAA,MAC1F,OAAO;AAAA,MAAc,cAAc,KAAK,MAAM,GAAG,GAAG;AAAA,IAAE,CAAC;AAAA,EAC3D;AACA,SAAO;AACT;;;ACyCO,IAAM,eAAN,MAAuC;AAAA,EAC5C,YAA6B,KAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA,EAE7B,IAAI,WAAoB;AAAE,WAAO,KAAK,IAAI;AAAA,EAAS;AAAA,EACnD,IAAI,YAAoB;AAAE,WAAO,KAAK,IAAI;AAAA,EAAO;AAAA,EACjD,IAAI,gBAAwB;AAAE,WAAO,KAAK,IAAI;AAAA,EAAc;AAAA,EAC5D,IAAI,OAAkB;AAAE,WAAO;AAAA,EAAU;AAAA,EAEzC,WAAmC;AACjC,WAAO,KAAK,IAAI,aAAa,SAAS,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAe,SAAuC;AAClE,UAAM,WAAW,MAAM,KAAK,SAAS;AACrC,UAAM,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AACnD,QAAI,CAAC,KAAK;AACR,YAAM,IAAI;AAAA,QACR,oBAAoB,OAAO,6DAAwD,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,MAAM;AAAA,QACnI,EAAE,gBAAgB,KAAK,IAAI,OAAO;AAAA,MAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,SAAkC;AAC7C,WAAO,YAAY,MAAM,KAAK,eAAe,OAAO,CAAC;AAAA,EACvD;AAAA,EAIA,MAAM,QAAQ,SAAmD;AAI/D,UAAM,YAAY,KAAK,IAAI,SAAS,KAAK,IAAI,YAAY,KAAK,IAAI,MAAM;AAExE,QAAI,YAAY,QAAW;AACzB,YAAM,MAAM,MAAM,KAAK,eAAe,OAAO;AAC7C,aAAO,kBAAkB,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC;AAAA,IACxD;AAEA,UAAM,WAAW,MAAM,KAAK,SAAS;AACrC,UAAM,UAAU,MAAM,QAAQ;AAAA,MAC5B,SAAS,OAAO,CAAC,MAAM,UAAU,EAAE,WAAW,CAAC,EAAE,IAAI,OAAO,QAC1D,CAAC,IAAI,MAAM,MAAM,kBAAkB,KAAK,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,CAAU;AAAA,IAAC;AAChF,WAAO;AAAA,MACL,UAAU,OAAO,YAAY,OAAO;AAAA,MACpC,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,KAAK,MAAM;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,QAAuB;AAC7B,WAAO,CAAC,qBAAqB,cAAc;AAAA,EAC7C;AAAA;AAAA,EAGQ,UAAU,SAAyB;AACzC,WAAO,KAAK,IAAI,aAAa,OAAO,KAAK;AAAA,EAC3C;AAAA,EAEA,MAAc,kBAAiC;AAC7C,UAAM,YAAY,KAAK,IAAI,SAAS,KAAK,IAAI,YAAY,KAAK,IAAI,MAAM;AAAA,EAC1E;AAAA,EAEA,MAAM,kBAA4C;AAChD,UAAM,KAAK,gBAAgB;AAC3B,WAAO;AAAA,MAAgB,KAAK,IAAI;AAAA,MAAQ,KAAK,IAAI,QAAQ;AAAA,OACtD,MAAM,KAAK,SAAS,GAAG,OAAO,OAAK,UAAU,EAAE,WAAW,CAAC;AAAA,IAAC;AAAA,EACjE;AAAA,EAEA,MAAM,aAAa,UAA2B,SAAoC;AAChF,UAAM,KAAK,gBAAgB;AAC3B,UAAM,YAAY,MAAM,KAAK,SAAS,GAAG,OAAO,OAAK,UAAU,EAAE,WAAW,CAAC;AAC7E,QAAI,YAAY,UAAa,CAAC,SAAS,KAAK,OAAK,EAAE,SAAS,OAAO,GAAG;AACpE,YAAM,IAAI,WAAW,yBAAyB,OAAO,KAAK,EAAE,OAAO,UAAU,CAAC;AAAA,IAChF;AACA,UAAM,iBAAiB,UAAU,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ,IAAI,QAAQ;AAC/E,UAAM,WAAW,YAAY,SAAY,WAAW,SAAS,OAAO,OAAK,EAAE,SAAS,OAAO;AAC3F,UAAM,UAAU,MAAM,QAAQ,IAAI,SAAS,IAAI,OAAM,QACnD,CAAC,IAAI,MAAM,MAAM,kBAAkB,KAAK,SAAS,SAAS,IAAI,IAAI,EAAG,EAAE,CAAC,CAAU,CAAC;AAGrF,UAAM,iBAAiB,UAAU,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ,IAAI,MAAM,KAAK,SAAS,EAAE,KAAK,OAAK,EAAE,OAAO,OAAK,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAC/I,WAAO,EAAE,UAAU,OAAO,YAAY,OAAO,GAAG,MAAM,WAAW,WAAW,YAAY,OAAO,KAAK,MAAM,EAAE;AAAA,EAC9G;AAAA,EAEA,MAAM,QAAQ,SAAiB,UAA2B,SAA4C;AACpG,UAAM,OAAO,MAAM,KAAK,SAAS,GAAG,KAAK,OAAK,EAAE,SAAS,OAAO;AAChE,QAAI,CAAC,IAAK,OAAM,IAAI,WAAW,oBAAoB,OAAO,GAAG;AAC7D,WAAO,eAAe,KAAK,UAAU,OAAO;AAAA,EAC9C;AAAA,EAEA,MAAM,cAAc,SAAiB,OAAqC;AAGxE,UAAM,QAAsB,MAAM,KAAK,QAAQ,OAAO;AACtD,UAAM,OAAO,OAAO,eAAe;AACnC,UAAM,UAAU,QACZ,MAAM,QAAQ,OAAO,CAAC,OACnB,MAAM,WAAW,UAAa,EAAE,OAAO,YAAY,MAAM,MAAM,OAAO,YAAY,OAClF,MAAM,SAAS,UAAa,EAAE,KAAK,SAAS,MAAM,IAAI,EAAE,IAC3D,MAAM;AACV,QAAI,QAAQ,SAAS,QAAQ,MAAM,QAAQ;AACzC,YAAM,IAAI,WAAW,gBAAgB,OAAO,0CAA0C,EAAE,OAAO,UAAU,CAAC;AAAA,IAC5G;AACA,QAAI,QAAQ,SAAS,MAAM;AACzB,YAAM,OAAO,QACT,YAAY,MAAM,UAAU,KAAK,IAAI,MAAM,QAAQ,GAAG,KAAK,QAAQ,MAAM,IAAI,IAAI,MACjF;AACJ,YAAM,IAAI;AAAA,QACR,YAAY,OAAO,YAAY,IAAI;AAAA,QAEnC;AAAA,QAAS,EAAE,gBAAgB,KAAK,IAAI,OAAO;AAAA,MAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,kBAAmD;AACvD,WAAO,aAAa,MAAM,KAAK,SAAS,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGA,cAAsC;AACpC,WAAO,iBAAiB;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,eAAuB;AACrB,WAAO,aAAa,KAAK,YAAY,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,kBAAqC;AACnC,WAAO,gBAAgB,KAAK,IAAI,OAAO;AAAA,EACzC;AAAA,EAcA,MAAM,UAAU,QAAgC,OAAsB,CAAC,GAA2B;AAChG,UAAM,MAAM,OAAO,WAAW,YACzB,MAAM,KAAK,IAAI,QAAQ,eAAe,MAAM,GAAG,MAChD;AACJ,UAAM,KAAK,IAAI,aAAa;AAAA,MAC1B,KAAK,IAAI;AAAA,MAAe,KAAK,IAAI;AAAA,MAAQ,EAAE,iBAAiB,IAAI;AAAA,IAAC;AACnE,QAAI,QAAQ,QAAQ,KAAK,UAAU,MAAO,OAAM,KAAK,cAAc,GAAG;AACtE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAc,cAAc,KAA4B;AACtD,UAAM,YAAY,MAAM,KAAK,SAAS,GAAG,OAAO,CAAC,MAAM,UAAU,EAAE,WAAW,CAAC;AAC/E,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,SAAS,MAAM,QAAQ,IAAI,SAAS,IAAI,OAAO,QAAQ;AAC3D,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,GAAG,IAAI,WAAW,uBAAuB,EAAE,QAAQ,OAAO,CAAC;AACnF,eAAO,IAAI,KAAK,MAAM,IAAI,KAAK,IAA8B;AAAA,MAC/D,QAAQ;AAAE,eAAO;AAAA,MAAK;AAAA,IACxB,CAAC,CAAC;AACF,QAAI,CAAC,OAAO,KAAK,CAAC,MAAM,GAAG,QAAQ,GAAG;AACpC,YAAM,IAAI;AAAA,QACR,0BAA0B,GAAG;AAAA,QAC7B,EAAE,OAAO,WAAW,gBAAgB,KAAK,IAAI,QAAQ,cAAc,OAAO;AAAA,MAAC;AAAA,IAC/E;AAAA,EACF;AACF;;;ACvQA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,aAAa;AAGf,IAAM,mBAAmB;AAoCzB,SAAS,YAAY,OAAe,QAAQ,GAAW;AAC5D,SAAO,KAAK,MAAM,UAAU,WAAW;AACzC;AAEA,SAAS,gBAAgB,MAAkC;AACzD,MAAI;AACF,WAAO,aAAa,MAAM,MAAM;AAAA,EAClC,SAAS,GAAG;AACV,QAAK,EAA4B,SAAS,SAAU,QAAO;AAC3D,UAAM;AAAA,EACR;AACF;AASO,SAAS,iBAAiB,MAA0B,MAAuC;AAChG,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI;AACJ,MAAI;AACF,aAAS,MAAM,IAAI;AAAA,EACrB,SAAS,OAAO;AACd,UAAM,IAAI,WAAW,GAAG,IAAI,sBAAsB,EAAE,OAAO,eAAe,MAAM,CAAC;AAAA,EACnF;AACA,MAAI,WAAW,QAAQ,WAAW,OAAW,QAAO,CAAC;AACrD,MAAI,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AACvD,UAAM,IAAI,WAAW,GAAG,IAAI,+CAA+C,EAAE,OAAO,cAAc,CAAC;AAAA,EACrG;AACA,SAAO;AACT;AAGO,SAAS,kBAAkB,KAAwB,MAAuC;AAC/F,SAAO,IAAI,iBAAiB,MAAM,kBAAkB;AACtD;AAOO,SAAS,wBAAwB,OAAoB,CAAC,GAAqB;AAChF,QAAM,MAAM,KAAK,OAAO,QAAQ;AAChC,QAAM,OAAO,KAAK,QAAQ,YAAY;AACtC,QAAM,OAAO,kBAAkB,KAAK,YAAY,iBAAiB,IAAI,GAAG,IAAI;AAC5E,QAAM,OAAO,kBAAkB,KAAK,IAAI;AACxC,QAAM,UAAU,MAAM,WAAW,IAAI,KAAK;AAC1C,QAAM,QAAQ,YAAY,UAAa,YAAY;AAEnD,QAAM,SAAS,KAAK,UAAU,IAAI,kBAAkB,QAAQ,QAAQ,UAAU,WAAc;AAC5F,QAAM,YACJ,KAAK,SAAS,WAAW,IAAI,gBAAgB,QAAQ,SAAS,YAAY;AAC5E,QAAM,cAAc,QAAQ,QAAQ,WAAW;AAC/C,QAAM,WAAW,KAAK,WAAW,IAAI,kBAAkB,eAAe,kBAAkB,QAAQ,OAAO,EAAE;AACzG,QAAM,aACJ,KAAK,UAAU,WAAW,IAAI,iBAAiB,QAAQ,cAAc,YAAY;AAEnF,SAAO,EAAE,QAAQ,SAAS,WAAW,YAAY,SAAS,EAAE,MAAM,MAAM,MAAM,EAAE;AAClF;AAGO,SAAS,gBAAgB,GAA6B;AAC3D,QAAM,QAAQ,EAAE,QAAQ,QACpB,YAAY,EAAE,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI,oBAChD,GAAG,EAAE,QAAQ,IAAI,oBAAoB,EAAE,QAAQ,IAAI;AACvD,SAAO,iCAAiC,KAAK;AAC/C;AAGO,IAAM,mBACX;AASK,SAAS,kBAAkB,GAA6B;AAC7D,SAAO,qBAAqB,gBAAgB,CAAC,CAAC,KAAK,gBAAgB;AACrE;AAGO,SAAS,wBAAwB,OAAoB,CAAC,GAA0C;AACrG,QAAM,IAAI,wBAAwB,IAAI;AACtC,MAAI,CAAC,EAAE,OAAQ,OAAM,IAAI,wBAAwB,kBAAkB,CAAC,GAAG,EAAE,OAAO,cAAc,CAAC;AAC/F,SAAO;AACT;;;ACzJO,IAAM,cACX,OAAsC,UAAkB;;;AZiE1D,IAAM,QAAQ;AAAA,EACZ,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,UAAU;AACZ;AAEA,IAAM,mBAAsC,OAAO,OAAO,KAAK;AAWxD,SAAS,eAAe,KAAmC;AAChE,SAAO,OAAQ,IAAqB,mBAAmB;AACzD;AAUO,SAAS,YAAY,SAAsC;AAChE,SAAO,QAAQ,SAAS,MAAM,MAAM;AACtC;AAUO,SAAS,cAAc,SAA2B;AACvD,QAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,SAAO,OAAO,MAAM,MAAM,MAAM,UAAa,OAAO,MAAM,QAAQ,MAAM;AAC1E;AAEO,IAAM,UAAN,cAAsB,YAAY;AAAA,EACtB;AAAA,EAEjB,YAAY,QAA6B;AACvC,UAAM,MAAM;AACZ,SAAK,gBAAgB,QAAQ,SAAS,CAAC;AAAA,EACzC;AAAA,EAYA,MAAe,OACb,QACA,SACkB;AAClB,UAAM,IAAe,EAAE,GAAG,KAAK,eAAe,GAAI,QAAQ,SAAS,CAAC,EAAG;AACvE,UAAM,OAAO,WAAW,MAAM;AAE9B,QAAI,EAAE,SAAU,QAAO,KAAK,WAAW,MAAM,OAAO;AAEpD,UAAM,SAAS,mBAAmB,CAAC;AACnC,UAAM,eAAe,IAAI,aAAa;AAAA,MACpC,QAAQ,OAAO;AAAA,MAAQ,SAAS,OAAO;AAAA,MAAS,YAAY;AAAA,IAC9D,CAAC;AACD,UAAM,SAAqB,EAAE,UAAU;AACvC,UAAM,aAAa,EAAE,cAAc;AACnC,UAAM,WAAW,CAAC,EAAE;AAGpB,UAAM,WAAW,OAAO,WAAW;AAInC,UAAM,OAAO,MAAM,KAAK,cAAc,cAAc,GAAG,QAAQ,UAAU;AACzE,UAAM,cAAc,YAAY;AAC9B,UAAI,SAAU,OAAM,aAAa,WAAW,KAAK,gBAAgB,KAAK,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC1F;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI,aAAqC,CAAC;AAG1C,QAAI,eAAe;AACnB,QAAI;AAIF,mBAAa,MAAM,aAAa,qBAAqB,KAAK,gBAAgB,KAAK,EAAE;AACjF,UAAI,CAAC,YAAY;AACf,cAAM,IAAI;AAAA,UACR;AAAA,UAEA,EAAE,OAAO,mBAAmB,gBAAgB,KAAK,GAAG;AAAA,QAAC;AAAA,MACzD;AACA,UAAI,CAAC,WAAW,mBAAmB,CAAC,WAAW,gBAAgB;AAC7D,cAAM,IAAI;AAAA,UACR;AAAA,UAGA,EAAE,OAAO,mBAAmB,gBAAgB,KAAK,GAAG;AAAA,QAAC;AAAA,MACzD;AAEA,YAAM,WAAW,KAAK,UAAU,SAAS,KAAK,WAAW,MAAM,aAAa,SAAS,KAAK,EAAE;AAE5F,YAAM,WAAW,gBAAgB,UAAU;AAI3C,YAAM,UAAU,aAAa,EAAE,MAAM,QAAQ,YAAY,MAAM,WAAW,YAAY,QAAQ,EAAE,CAAC;AAKjG,mBAAa,MAAM,eAAe,QAAQ;AAK1C,YAAM,eAAuC;AAAA,QAC3C,GAAI,EAAE,cAAc,QAAQ,iBAAiB,MAAS,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,QAI3D,GAAI,EAAE,cAAc,QAAQ,EAAE,cAAc,qBAAqB,KAAK,SAAS,YAAY,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,QAKlG,oBAAoB;AAAA,QACpB,GAAI,EAAE,iBAAiB,QAAQ,aAAa,QAAQ,IAAI,CAAC;AAAA,QACzD,kBAAkB,KAAK;AAAA,MACzB;AAEA,YAAM,eAAe;AAAA,QACnB,GAAG;AAAA,QACH,SAAS,EAAE,GAAI,KAAK,WAAW,CAAC,GAAI,GAAG,aAAa;AAAA,QACpD,QAAQ;AAAA,UACN,GAAG,cAAc,KAAK,MAAM;AAAA,UAC5B,CAAC,MAAM,MAAM,GAAG,KAAK;AAAA,UACrB,CAAC,MAAM,KAAK,GAAG,KAAK;AAAA,UACpB,CAAC,MAAM,OAAO,GAAG,OAAO;AAAA,UACxB,CAAC,MAAM,MAAM,GAAG;AAAA,UAChB,CAAC,MAAM,QAAQ,GAAG,OAAO,QAAQ;AAAA,UACjC,CAAC,MAAM,IAAI,GAAG;AAAA,UACd,CAAC,MAAM,UAAU,GAAG,WAAW;AAAA,UAC/B,CAAC,MAAM,QAAQ,GAAG;AAAA,QACpB;AAAA,QACA,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,QAIX,kBAAkB;AAAA,QAClB,YAAY,KAAK,cAAc;AAAA,MACjC;AAEA,qBAAe;AACf,gBAAU,MAAM,KAAK,WAAW,cAA8B,OAAO;AAAA,IACvE,SAAS,OAAO;AAMd,YAAM,SAAS,eACX,MAAM,iBAAiB,CAAC,WAAW,MAAM,KAAK,EAAE,OAAO,CAAC,GAAG,QAAQ,IACnE;AACJ,YAAM,YAAY;AAClB,UAAI,iBAAiB,WAAY,OAAM;AACvC,YAAM,IAAI,WAAW,qBAAqB,OAAO,QAAQ,IAA2B,GAAG;AAAA,QACrF,OAAO;AAAA,QAAkB,gBAAgB,KAAK;AAAA,QAAI;AAAA,MAAM,CAAC;AAAA,IAC7D;AAIA,QAAI;AACF,YAAM,UAAU,SAAS,WAAW,MAAM;AAC1C,YAAM,YAAY,SAAS,WAAW,aAAa,KAAK,EAAE;AAAA,IAC5D,SAAS,KAAK;AACZ,YAAM,QAAQ,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACrC,YAAM,YAAY;AAClB,YAAM;AAAA,IACR;AAEA,WAAO,KAAK,OAAO,SAAS;AAAA,MAC1B;AAAA,MAAc,eAAe,KAAK;AAAA,MAAgB,QAAQ,KAAK;AAAA,MAC/D;AAAA,MAAQ;AAAA,MAAU,YAAY,WAAW;AAAA,MAAa;AAAA,IACxD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAe,IAAI,iBAA2C;AAC5D,UAAM,UAAU,MAAM,MAAM,IAAI,eAAe;AAC/C,WAAO,KAAK,UAAU,OAAO;AAAA,EAC/B;AAAA;AAAA,EAGS,KAAK,OAA4D;AACxE,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,UAAM,YAAY,CAAC,MAAe,KAAK,UAAU,CAAC;AAClD,YAAQ,mBAAmB;AACzB,uBAAiB,WAAW,MAAO,OAAM,UAAU,OAAO;AAAA,IAC5D,GAAG;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,UAAU,SAA2B;AAC3C,UAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,UAAM,SAAS,OAAO,MAAM,MAAM;AAClC,QAAI,CAAC,OAAQ,QAAO;AAKpB,UAAM,QAAQ,wBAAwB,EAAE,QAAQ,KAAK,cAAc,QAAQ,SAAS,KAAK,cAAc,QAAQ,CAAC;AAChH,UAAM,SAAS,MAAM;AACrB,QAAI,CAAC,OAAQ,QAAO;AAKpB,UAAM,cAAc,MAAM,eAAe,YAAY,SAAY,MAAM;AACvE,UAAM,YAAY,OAAO,MAAM,OAAO;AACtC,QAAI,eAAe,aAAa,cAAc,aAAa;AACzD,YAAM,IAAI;AAAA,QACR,WAAW,QAAQ,EAAE,iDAAiD,SAAS,8BACxD,WAAW;AAAA,QAClC,EAAE,OAAO,SAAS;AAAA,MAAC;AAAA,IACvB;AACA,UAAM,UAAU,eAAe,aAAa;AAE5C,WAAO,KAAK,OAAO,SAAS;AAAA,MAC1B,cAAc,IAAI,aAAa,EAAE,QAAQ,SAAS,YAAY,YAAY,CAAC;AAAA,MAC3E,eAAe,OAAO,MAAM,KAAK,KAAK;AAAA,MACtC;AAAA;AAAA;AAAA,MAGA,YAAY,OAAO,MAAM,UAAU,KAAK;AAAA,MACxC,QAAS,OAAO,MAAM,MAAM,KAAgC;AAAA,MAC5D,UAAU,OAAO,MAAM,QAAQ,MAAM;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cACZ,cAA4B,GAAc,QAA6B,YACjD;AACtB,QAAI,EAAE,iBAAiB;AACrB,YAAM,WAAW,MAAM,aAAa,QAAQ,EAAE,eAAe;AAC7D,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,WAAW,iBAAiB,EAAE,eAAe,cAAc;AAAA,UACnE,OAAO;AAAA,UAAkB,gBAAgB,EAAE;AAAA,QAAgB,CAAC;AAAA,MAChE;AACA,aAAO,SAAS,WAAW,UAAU,WAAW,aAAa,UAAU,EAAE,iBAAiB,IAAO;AAAA,IACnG;AACA,QAAI,CAAC,OAAO,eAAe;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE,OAAO,cAAc;AAAA,MAAC;AAAA,IAC5B;AACA,UAAM,UAAU,MAAM,aAAa,WAAW,OAAO,eAAe,EAAE,WAAW,CAAC;AAClF,QAAI;AACF,aAAO,MAAM,aAAa,UAAU,QAAQ,IAAI,IAAO;AAAA,IACzD,SAAS,GAAG;AACV,YAAM,aAAa,WAAW,OAAO,eAAe,QAAQ,EAAE,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC9E,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,OAAO,SAAkB,KAA6C;AAG5E,QAAI,eAAe,OAAO,EAAG,QAAO;AAEpC,UAAM,QAAQ,IAAI,aAAa,EAAE,GAAG,KAAK,QAAQ,CAAC;AAClD,UAAM,iBAAiB,QAAQ,OAAO,KAAK,OAAO;AAElD,WAAO,iBAAiB,SAAS;AAAA,MAC/B,OAAO,EAAE,OAAO,OAAO,YAAY,MAAM,cAAc,KAAK;AAAA,MAC5D,gBAAgB,EAAE,OAAO,IAAI,QAAQ,YAAY,MAAM,cAAc,KAAK;AAAA,MAC1E,QAAQ;AAAA,QACN,cAAc;AAAA,QACd,OAAO,OAAO,SAAkB,SAAkC;AAGhE,cAAI,IAAI,UAAU;AAChB,kBAAM,IAAI,aAAa,WAAW,IAAI,eAAe,IAAI,MAAM,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACjF;AACA,iBAAO,eAAe,SAAS,IAAI;AAAA,QACrC;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,WACN,QACA,SACkB;AAElB,WAAQ,MAAM,OAA6B,KAAK,MAAM,QAAQ,OAAO;AAAA,EACvE;AACF;AAEA,IAAO,kBAAQ;AAaf,SAAS,mBAAmB,GAAmC;AAC7D,QAAM,QAAQ,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,SAAS,EAAE,QAAQ,CAAC;AAC9E,SAAO;AAAA,IACL,QAAQ,MAAM;AAAA,IACd,eAAe,EAAE,iBAAiB,QAAQ,IAAI;AAAA,IAC9C,SAAS,MAAM;AAAA,EACjB;AACF;AAsCA,eAAsB,iBACpB,MACA,UACoC;AACpC,MAAI;AACF,qBAAiB,WAAW,KAAK,EAAE,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG;AAIhE,UAAI,QAAQ,SAAS,MAAM,QAAQ,MAAM,SAAU;AAInD,UAAI,CAAC,QAAQ,YAAa,OAAM,QAAQ,YAAY,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACpE,YAAM,QAAQ,EAAE,IAAI,QAAQ,IAAI,OAAO,QAAQ,OAAO,aAAa,QAAQ,YAAY;AACvF,aAAO,EAAE,GAAG,OAAO,SAAS,MAAM,QAAQ,OAAO,EAAE,KAAK,MAAM,MAAM,MAAM,KAAK,EAAE;AAAA,IACnF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAsBO,SAAS,qBACd,OACA,QACA,SAA8B,CAAC,GACvB;AACR,QAAM,OAAO;AAGb,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS,OAAO,aAAa,KAAK,EAAE,QAAQ,WAAW,EAAE;AAC/D,QAAM,QAAQ,CAAC,SAAS,GAAG,IAAI,KAAK,MAAM,MAAM,GAAG,IAAI,GAAG;AAE1D,QAAM,QAAQ,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAChE,MAAI,SAAS,OAAO,UAAU,gBAAgB;AAC5C,UAAM;AAAA,MACJ,mBAAmB,KAAK;AAAA,IAC6C;AAAA,EACzE;AACA,QAAM,KAAK,OAAO,UACd,0BAA0B,OAAO,EAAE,kBACnC,0BAA0B,OAAO,EAAE,wEACP,OAAO,EAAE,KAAK;AAE9C,QAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU;AACrD,MAAI,IAAK,OAAM,KAAK,iBAAiB,GAAG,GAAG;AAC3C,SAAO,MAAM,KAAK,GAAG;AACvB;AAUA,eAAe,eAAe,UAA0D;AACtF,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,SAAS,OAAO,CAAC,MAAM,UAAU,EAAE,WAAW,CAAC,EAAE,IAAI,OAAO,QAC1D,CAAC,IAAI,MAAM,MAAM,eAAe,GAAG,EAAE,MAAM,MAAM,CAAC,CAAC,CAAU;AAAA,EAAC;AAClE,SAAO,OAAO,YAAY,KAAK;AACjC;AAEA,SAAS,WAAW,QAA+D;AACjF,QAAM,EAAE,OAAO,QAAQ,GAAG,KAAK,IAAI,UAAU,CAAC;AAC9C,SAAO;AACT;AAGA,SAAS,cAAc,QAAoE;AACzF,QAAM,MAA8B,CAAC;AACrC,aAAW,CAAC,GAAG,GAAG,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC,GAAG;AACnD,QAAI,CAAC,iBAAiB,SAAS,CAAC,EAAG,KAAI,CAAC,IAAI;AAAA,EAC9C;AACA,SAAO;AACT;;;AaljBO,IAAM,kBAAkB;AAGxB,IAAM,mBAAmB;AASzB,SAAS,cAAc,MAAyB,QAAQ,KAAa;AAC1E,UAAQ,IAAI,mBAAmB,IAAI,sBAAsB,iBAAiB,QAAQ,OAAO,EAAE;AAC7F;AAOA,eAAsB,gBAAgB,QAAgB,SAAiB,cAAc,GAAwC;AAC3H,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,MAAM,qBAAqB;AAAA,MACpD,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,IAC/C,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,QAAO;AACpB,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,CAAC,MAAM,QAAQ,KAAK,WAAW,EAAG,QAAO;AAC7C,WAAO;AAAA,MACL,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,MAClD,aAAa,KAAK,YAAY,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,IAChF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,mBAAmB,KAAsD;AACvF,SAAO,QAAQ,SAAY,SAAY,IAAI,YAAY,SAAS,gBAAgB;AAClF;AAGO,SAAS,YAAY,KAA6B;AACvD,QAAM,OAAO,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO;AAC3C,SAAO,GAAG,IAAI,iBAAiB,IAAI,YAAY,KAAK,IAAI,KAAK,MAAM;AACrE;AAGO,IAAM,wBACX;AAOK,SAAS,sBAAsB,KAAqB,iBAAyB,mBAAmC;AACrH,SACE,mBAAmB,YAAY,GAAG,CAAC,YAAY,gBAAgB,uJAElC,eAAe,gCAAgC,iBAAiB,uDACvC,qBAAqB;AAE/E;;;ACvDO,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCASI,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiC3C,SAAS,mBAAmB,GAAqB;AACtD,SAAO,OAAO,MAAM,YAAY,MAAM,QAAS,EAA+B,eAAe;AAC/F;AASO,SAAS,cAAc,GAAyF;AACrH,QAAM,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,IAClD,eAAe,EAAE,eAAe,kBAChC;AACJ,QAAM,MAAM,EAAE,sBAAsB,UAAa,EAAE,oBAAoB,IACnE,0BACA,EAAE,sBAAsB,IACtB,mCACA,cAAc,EAAE,iBAAiB;AACvC,QAAM,UAAU,EAAE,YAAY,yBAAyB,EAAE,SAAS,6BAA6B;AAC/F,SAAO,GAAG,IAAI,QAAQ,GAAG,GAAG,OAAO;AACrC;AAYO,SAAS,uBAAuB,GAA4B;AACjE,QAAM,MAAM,EAAE,MACV,wBAAwB,YAAY,EAAE,GAAG,CAAC,gBAAgB,gBAAgB,kBAC1E,uFACK,gBAAgB;AACzB,QAAM,OAAO,EAAE,WAAW,SACtB,KACA,EAAE,WACA,aAAa,EAAE,MAAM,+EACrB,SAAS,EAAE,MAAM;AACvB,SACE,qCAAqC,EAAE,SAAS,KAAK,GAAG,oCACtB,cAAc,CAAC,CAAC,IAAI,IAAI,yBAClC,qBAAqB,uCAAuC,EAAE,SAAS;AAGnG;","names":["gatewayIps"]}