{"version":3,"file":"telemetry-system-Dc78ohSl.cjs","names":["propagation","WebSocket","ExportResultCode","JsonTraceSerializer","ExportResultCode","JsonMetricsSerializer","ExportResultCode","JsonLogsSerializer","trace","context","propagation","SpanKind","context","SpanStatusCode","trace","SpanStatusCode","ATTR_SERVICE_NAME","NodeTracerProvider","BatchSpanProcessor","CompositePropagator","W3CTraceContextPropagator","W3CBaggagePropagator","trace","MeterProvider","PeriodicExportingMetricReader","LoggerProvider","BatchLogRecordProcessor","context","SpanKind","SpanStatusCode"],"sources":["../src/observability/telemetry-system/baggage-span-processor.ts","../src/observability/telemetry-system/types.ts","../src/observability/telemetry-system/connection.ts","../src/observability/telemetry-system/span-exporter.ts","../src/observability/telemetry-system/metrics-exporter.ts","../src/observability/telemetry-system/log-exporter.ts","../src/observability/telemetry-system/context.ts","../src/observability/telemetry-system/fetch-instrumentation.ts","../src/observability/telemetry-system/utils.ts","../src/observability/telemetry-system/span-ops.ts","../src/observability/telemetry-system/payload.ts","../src/observability/telemetry-system/index.ts"],"sourcesContent":["// Baggage -> span attribute processor.\n//\n// Copies EVERY baggage entry onto every span started in its scope,\n// unconditionally — the same contract as the upstream OTel contrib\n// BaggageSpanProcessor. There is deliberately no key filtering here: a\n// filtering policy baked into worker binaries has to be kept in lockstep\n// across every SDK language and every deployed worker, and a stale binary\n// silently drops newer keys. Which attributes *mean* something (e.g. the\n// `iii.tag.*` trace-tag namespace, `iii.session.*`) is a query-side\n// convention owned by the engine's traces API, where it can evolve without\n// touching workers.\n\nimport type { Context } from '@opentelemetry/api'\nimport { propagation } from '@opentelemetry/api'\nimport type { ReadableSpan, Span, SpanProcessor } from '@opentelemetry/sdk-trace-base'\n\n/**\n * OpenTelemetry span processor that copies OTel baggage entries onto each\n * started span as attributes.\n */\nexport class BaggageSpanProcessor implements SpanProcessor {\n  onStart(span: Span, parentContext: Context): void {\n    // NoOp guard: skip allocation when sampler drops the span.\n    if (!span.isRecording()) {\n      return\n    }\n\n    const baggage = propagation.getBaggage(parentContext)\n    if (!baggage) {\n      return\n    }\n\n    for (const [key, entry] of baggage.getAllEntries()) {\n      span.setAttribute(key, entry.value)\n    }\n  }\n\n  onEnd(_span: ReadableSpan): void {\n    /* no-op */\n  }\n\n  async shutdown(): Promise<void> {\n    /* no-op */\n  }\n\n  async forceFlush(): Promise<void> {\n    /* no-op */\n  }\n}\n","/**\n * Types, interfaces, and constants for the OpenTelemetry module.\n */\n\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\n\n// Semantic convention constants for compatibility across versions\nexport const ATTR_SERVICE_VERSION = 'service.version'\nexport const ATTR_SERVICE_NAMESPACE = 'service.namespace'\nexport const ATTR_SERVICE_INSTANCE_ID = 'service.instance.id'\n\n/** Magic prefixes for binary frames over WebSocket */\nexport const PREFIX_TRACES = 'OTLP'\nexport const PREFIX_METRICS = 'MTRC'\nexport const PREFIX_LOGS = 'LOGS'\n\n/** Connection state for the shared WebSocket */\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface ReconnectionConfig {\n  /** Starting delay in milliseconds (default: 1000ms) */\n  initialDelayMs: number\n  /** Maximum delay cap in milliseconds (default: 30000ms) */\n  maxDelayMs: number\n  /** Exponential backoff multiplier (default: 2) */\n  backoffMultiplier: number\n  /** Random jitter factor 0-1 (default: 0.3) */\n  jitterFactor: number\n  /** Maximum retry attempts, -1 for infinite (default: -1) */\n  maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_RECONNECTION_CONFIG: ReconnectionConfig = {\n  initialDelayMs: 1000,\n  maxDelayMs: 30000,\n  backoffMultiplier: 2,\n  jitterFactor: 0.3,\n  maxRetries: -1,\n}\n\n/** Configuration for OpenTelemetry initialization. */\nexport interface OtelConfig {\n  /** Whether OpenTelemetry export is enabled. Defaults to true. Set to false or OTEL_ENABLED=false/0/no/off to disable. */\n  enabled?: boolean\n  /** The service name to report. Defaults to OTEL_SERVICE_NAME or \"iii-node\". */\n  serviceName?: string\n  /** The service version to report. Defaults to SERVICE_VERSION env var or \"unknown\". */\n  serviceVersion?: string\n  /** The service namespace to report. Defaults to SERVICE_NAMESPACE env var. */\n  serviceNamespace?: string\n  /** The service instance ID to report. Defaults to SERVICE_INSTANCE_ID env var or auto-generated UUID. */\n  serviceInstanceId?: string\n  /** III Engine WebSocket URL. Defaults to III_URL or \"ws://localhost:49134\". */\n  engineWsUrl?: string\n  /** HTTP headers sent on the telemetry WebSocket handshake (e.g. `Authorization`). */\n  engineWsHeaders?: Record<string, string>\n  /** OpenTelemetry instrumentations to register (e.g., PrismaInstrumentation). */\n  instrumentations?: Instrumentation[]\n  /** Whether OpenTelemetry metrics export is enabled. Defaults to true. Set to false or OTEL_METRICS_ENABLED=false/0/no/off to disable. */\n  metricsEnabled?: boolean\n  /** Metrics export interval in milliseconds. Defaults to 60000 (60 seconds). */\n  metricsExportIntervalMs?: number\n  /**\n   * Span processor flush delay in milliseconds. Defaults to 100ms. This is how\n   * long an ended span waits in the batch buffer before it is flushed to the\n   * engine, the OpenTelemetry default of 5000ms is what makes traces appear\n   * seconds after the action. Env override: OTEL_SPANS_FLUSH_INTERVAL_MS.\n   */\n  spansFlushIntervalMs?: number\n  /** Log processor flush delay in milliseconds. Defaults to 100ms. Env override: OTEL_LOGS_FLUSH_INTERVAL_MS. */\n  logsFlushIntervalMs?: number\n  /** Maximum number of log records exported per batch. Defaults to 1. */\n  logsBatchSize?: number\n  /** Whether to auto-instrument globalThis.fetch calls. Defaults to true. Works on Node.js, Bun, and Deno. Set to false to disable. */\n  fetchInstrumentationEnabled?: boolean\n  /** Optional reconnection configuration for the WebSocket connection. */\n  reconnectionConfig?: Partial<ReconnectionConfig>\n}\n\n/** Default configuration values for OpenTelemetry initialization. */\nexport const DEFAULT_OTEL_CONFIG = {\n  enabled: true,\n  serviceName: 'iii-node',\n  serviceVersion: 'unknown',\n  engineWsUrl: 'ws://localhost:49134',\n  metricsEnabled: true,\n  metricsExportIntervalMs: 60000,\n  spansFlushIntervalMs: 100,\n  logsFlushIntervalMs: 100,\n  logsBatchSize: 1,\n  fetchInstrumentationEnabled: true,\n} as const satisfies Partial<OtelConfig>\n\n/** Parse a boolean environment variable, recognizing 'false', '0', 'no', 'off' as false. */\nexport function parseBoolEnv(value: string | undefined, defaultValue: boolean): boolean {\n  if (value === undefined) return defaultValue\n  const lower = value.toLowerCase()\n  return lower !== 'false' && lower !== '0' && lower !== 'no' && lower !== 'off'\n}\n","/**\n * Shared WebSocket connection for OpenTelemetry exporters.\n */\n\nimport { WebSocket } from 'ws'\nimport { type ConnectionState, type ReconnectionConfig, DEFAULT_RECONNECTION_CONFIG } from './types'\n\n/**\n * Shared WebSocket connection for all OTEL exporters (traces, metrics, logs).\n * Uses a single connection with message prefixes to identify signal type.\n */\nexport class SharedEngineConnection {\n  private static readonly MAX_PENDING_MESSAGES = 1000\n  private ws: WebSocket | null = null\n  private wsUrl: string\n  private connecting = false\n  private shuttingDown = false\n  private pendingMessages: Array<{ frame: Buffer; callback?: (err?: Error) => void }> = []\n  private reconnectAttempt = 0\n  private reconnectTimeout: NodeJS.Timeout | null = null\n  private config: ReconnectionConfig\n  private state: ConnectionState = 'disconnected'\n  private onConnectedCallbacks: Array<() => void> = []\n  private onFailedCallbacks: Array<() => void> = []\n\n  constructor(\n    wsUrl: string,\n    config: Partial<ReconnectionConfig> = {},\n    private readonly headers?: Record<string, string>,\n  ) {\n    this.wsUrl = wsUrl\n    this.config = { ...DEFAULT_RECONNECTION_CONFIG, ...config }\n    this.connect()\n  }\n\n  private connect(): void {\n    if (this.connecting || (this.ws && this.ws.readyState === WebSocket.OPEN)) {\n      return\n    }\n\n    this.connecting = true\n    this.state = 'connecting'\n\n    try {\n      // 10s handshake cap, parity with iii-sdk / Rust SDK (MOT-3857/MOT-3968)\n      this.ws = new WebSocket(this.wsUrl, { handshakeTimeout: 10000, headers: this.headers })\n\n      this.ws.on('open', () => {\n        this.connecting = false\n        this.state = 'connected'\n        console.log(`[OTel] Connected to engine at ${this.wsUrl}`)\n\n        // Reset reconnection state\n        if (this.reconnectAttempt > 0) {\n          console.log('[OTel] Successfully reconnected')\n        }\n        this.reconnectAttempt = 0\n\n        // Clear any pending reconnect timer to prevent race conditions\n        if (this.reconnectTimeout) {\n          clearTimeout(this.reconnectTimeout)\n          this.reconnectTimeout = null\n        }\n\n        // Flush pending messages\n        const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n        for (const { frame, callback } of pending) {\n          this.ws?.send(frame, err => callback?.(err))\n        }\n\n        // Notify callbacks\n        for (const cb of this.onConnectedCallbacks) {\n          cb()\n        }\n      })\n\n      this.ws.on('close', () => {\n        this.connecting = false\n        this.ws = null\n\n        // Skip reconnection if we're shutting down intentionally\n        if (this.shuttingDown) {\n          this.state = 'disconnected'\n          console.log('[OTel] Connection closed during shutdown')\n          return\n        }\n\n        this.state = 'disconnected'\n        console.log('[OTel] Disconnected from engine, will reconnect...')\n        this.scheduleReconnect()\n      })\n\n      this.ws.on('error', err => {\n        this.connecting = false\n\n        // Skip error handling if we're shutting down intentionally\n        if (this.shuttingDown) {\n          return\n        }\n\n        console.error('[OTel] WebSocket error:', err.message)\n      })\n    } catch (err) {\n      this.connecting = false\n      console.error('[OTel] Connection failed:', err)\n      this.scheduleReconnect()\n    }\n  }\n\n  private scheduleReconnect(): void {\n    if (this.config.maxRetries !== -1 && this.reconnectAttempt >= this.config.maxRetries) {\n      this.state = 'failed'\n      console.error(`[OTel] Max retries (${this.config.maxRetries}) reached, giving up`)\n\n      // Notify pending message callbacks that they won't be delivered\n      const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n      const failedError = new Error('Connection failed after max retries')\n      for (const { callback } of pending) {\n        callback?.(failedError)\n      }\n\n      // Notify failed callbacks so exporters can drain their own queues\n      for (const cb of this.onFailedCallbacks) {\n        try {\n          cb()\n        } catch (err) {\n          console.error('[OTel] onFailed callback threw:', err)\n        }\n      }\n      return\n    }\n\n    if (this.reconnectTimeout) {\n      return // Already scheduled\n    }\n\n    const exponentialDelay =\n      this.config.initialDelayMs * this.config.backoffMultiplier ** this.reconnectAttempt\n    const cappedDelay = Math.min(exponentialDelay, this.config.maxDelayMs)\n    const jitter = cappedDelay * this.config.jitterFactor * (2 * Math.random() - 1)\n    const delay = Math.max(0, Math.floor(cappedDelay + jitter))\n\n    this.state = 'reconnecting'\n    console.log(`[OTel] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n    this.reconnectTimeout = setTimeout(() => {\n      this.reconnectTimeout = null\n      this.reconnectAttempt++\n      this.connect()\n    }, delay)\n  }\n\n  /**\n   * Send a message with a signal prefix.\n   */\n  send(prefix: string, data: Uint8Array, callback?: (err?: Error) => void): void {\n    const prefixBytes = Buffer.from(prefix, 'utf-8')\n    const frame = Buffer.concat([prefixBytes, Buffer.from(data)])\n\n    if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n      this.ws.send(frame, callback)\n    } else {\n      // Queue for later with bounded size to prevent memory exhaustion\n      if (this.pendingMessages.length >= SharedEngineConnection.MAX_PENDING_MESSAGES) {\n        console.warn('[OTel] Pending message queue full, dropping oldest message')\n        const dropped = this.pendingMessages.shift()\n        dropped?.callback?.(new Error('Message dropped due to queue overflow'))\n      }\n      this.pendingMessages.push({ frame, callback })\n      this.connect()\n    }\n  }\n\n  /**\n   * Register a callback to be called when connected.\n   */\n  onConnected(callback: () => void): void {\n    this.onConnectedCallbacks.push(callback)\n    if (this.state === 'connected') {\n      callback()\n    }\n  }\n\n  /**\n   * Register a callback to be called when the connection enters the failed\n   * terminal state (max retries reached). Exporters use this to drain their\n   * own pending queues so in-flight forceFlush() calls do not hang.\n   */\n  onFailed(callback: () => void): void {\n    this.onFailedCallbacks.push(callback)\n    if (this.state === 'failed') {\n      try {\n        callback()\n      } catch (err) {\n        console.error('[OTel] onFailed callback threw:', err)\n      }\n    }\n  }\n\n  /**\n   * Get the current connection state.\n   */\n  getState(): ConnectionState {\n    return this.state\n  }\n\n  /**\n   * Whether the connection is shutting down. While shutting down, exporters\n   * fail-fast instead of queueing when there is no live connection, so a final\n   * forceFlush() can't hang waiting for a reconnect that will never happen.\n   */\n  isShuttingDown(): boolean {\n    return this.shuttingDown\n  }\n\n  /**\n   * Begin shutdown: stop reconnecting and stop accepting new queued exports,\n   * while leaving an open connection in place so buffered telemetry can still\n   * be flushed. Call before flushing, then call shutdown() to close fully.\n   */\n  beginShutdown(): void {\n    if (this.shuttingDown) {\n      return\n    }\n    this.shuttingDown = true\n\n    if (this.reconnectTimeout) {\n      clearTimeout(this.reconnectTimeout)\n      this.reconnectTimeout = null\n    }\n\n    // With no live connection there's nothing to flush to, so fail queued work\n    // now instead of leaving callbacks unresolved for the flush below to wait on\n    if (this.state !== 'connected') {\n      const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n      const shutdownError = new Error('Connection shutdown before message could be sent')\n      for (const { callback } of pending) {\n        callback?.(shutdownError)\n      }\n\n      for (const cb of this.onFailedCallbacks) {\n        try {\n          cb()\n        } catch (err) {\n          console.error('[OTel] onFailed callback threw:', err)\n        }\n      }\n    }\n  }\n\n  /**\n   * Shutdown the connection.\n   */\n  async shutdown(): Promise<void> {\n    // Set shutdown flag to prevent reconnection attempts\n    this.shuttingDown = true\n\n    if (this.reconnectTimeout) {\n      clearTimeout(this.reconnectTimeout)\n      this.reconnectTimeout = null\n    }\n\n    if (this.ws) {\n      this.ws.close()\n      this.ws = null\n    }\n\n    // Notify pending message callbacks that they won't be delivered\n    const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n    const shutdownError = new Error('Connection shutdown before message could be sent')\n    for (const { callback } of pending) {\n      callback?.(shutdownError)\n    }\n    this.onConnectedCallbacks = []\n    this.onFailedCallbacks = []\n    this.state = 'disconnected'\n  }\n}\n","/**\n * Span exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'\nimport { JsonTraceSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_TRACES } from './types'\n\n/**\n * Span exporter using the shared WebSocket connection.\n */\nexport class EngineSpanExporter implements SpanExporter {\n  private static readonly MAX_PENDING_EXPORTS = 100\n  private connection: SharedEngineConnection\n  private pendingExports: Array<{\n    spans: ReadableSpan[]\n    resultCallback?: (result: ExportResult) => void\n  }> = []\n\n  constructor(connection: SharedEngineConnection) {\n    this.connection = connection\n    this.connection.onConnected(() => this.flushPending())\n    this.connection.onFailed(() => this.failPending())\n  }\n\n  private flushPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    for (const { spans, resultCallback } of pending) {\n      this.sendExport(spans, resultCallback)\n    }\n  }\n\n  private failPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    const error = new Error('Connection failed: dropping queued spans')\n    for (const { resultCallback } of pending) {\n      resultCallback?.({ code: ExportResultCode.FAILED, error })\n    }\n  }\n\n  private sendExport(spans: ReadableSpan[], resultCallback?: (result: ExportResult) => void): void {\n    try {\n      const serialized = JsonTraceSerializer.serializeRequest(spans)\n      if (!serialized) {\n        resultCallback?.({ code: ExportResultCode.SUCCESS })\n        return\n      }\n\n      this.connection.send(PREFIX_TRACES, serialized, err => {\n        if (err) {\n          console.error('[OTel] Failed to send spans:', err.message)\n          resultCallback?.({ code: ExportResultCode.FAILED, error: err })\n        } else {\n          resultCallback?.({ code: ExportResultCode.SUCCESS })\n        }\n      })\n    } catch (err) {\n      console.error('[OTel] Error exporting spans:', err)\n      resultCallback?.({ code: ExportResultCode.FAILED, error: err as Error })\n    }\n  }\n\n  private doExport(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {\n    const state = this.connection.getState()\n    if (state !== 'connected') {\n      // Drop instead of queue when there's no prospect of delivery (failed, or shutting down)\n      if (state === 'failed' || this.connection.isShuttingDown()) {\n        const reason = state === 'failed' ? 'failed' : 'shut down'\n        resultCallback({\n          code: ExportResultCode.FAILED,\n          error: new Error(`Connection ${reason}: dropping spans`),\n        })\n        return\n      }\n      if (this.pendingExports.length >= EngineSpanExporter.MAX_PENDING_EXPORTS) {\n        const dropped = this.pendingExports.shift()\n        dropped?.resultCallback?.({\n          code: ExportResultCode.FAILED,\n          error: new Error('Queue overflow'),\n        })\n        console.warn('[OTel] Spans export queue full, dropped oldest entry')\n      }\n      this.pendingExports.push({ spans, resultCallback })\n      // Don't call resultCallback here - it will be called when actually sent or on shutdown\n      return\n    }\n\n    this.sendExport(spans, resultCallback)\n  }\n\n  export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {\n    this.doExport(spans, resultCallback)\n  }\n\n  async shutdown(): Promise<void> {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    const shutdownError = new Error('Exporter shutdown before export completed')\n    for (const { resultCallback } of pending) {\n      resultCallback?.({ code: ExportResultCode.FAILED, error: shutdownError })\n    }\n  }\n\n  async forceFlush(): Promise<void> {\n    // No-op, spans are sent immediately\n  }\n}\n","/**\n * Metrics exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { PushMetricExporter, ResourceMetrics } from '@opentelemetry/sdk-metrics'\nimport { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_METRICS } from './types'\n\n/**\n * Metrics exporter using the shared WebSocket connection.\n */\nexport class EngineMetricsExporter implements PushMetricExporter {\n  private static readonly MAX_PENDING_EXPORTS = 100\n  private connection: SharedEngineConnection\n  private pendingExports: Array<{\n    metrics: ResourceMetrics\n    resultCallback?: (result: ExportResult) => void\n  }> = []\n\n  constructor(connection: SharedEngineConnection) {\n    this.connection = connection\n    this.connection.onConnected(() => this.flushPending())\n    this.connection.onFailed(() => this.failPending())\n  }\n\n  private flushPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    for (const { metrics, resultCallback } of pending) {\n      this.sendExport(metrics, resultCallback)\n    }\n  }\n\n  private failPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    const error = new Error('Connection failed: dropping queued metrics')\n    for (const { resultCallback } of pending) {\n      resultCallback?.({ code: ExportResultCode.FAILED, error })\n    }\n  }\n\n  private sendExport(\n    metricsData: ResourceMetrics,\n    resultCallback?: (result: ExportResult) => void,\n  ): void {\n    try {\n      const serialized = JsonMetricsSerializer.serializeRequest(metricsData)\n      if (!serialized) {\n        resultCallback?.({ code: ExportResultCode.SUCCESS })\n        return\n      }\n\n      this.connection.send(PREFIX_METRICS, serialized, err => {\n        if (err) {\n          console.error('[OTel] Failed to send metrics:', err.message)\n          resultCallback?.({ code: ExportResultCode.FAILED, error: err })\n        } else {\n          resultCallback?.({ code: ExportResultCode.SUCCESS })\n        }\n      })\n    } catch (err) {\n      console.error('[OTel] Error exporting metrics:', err)\n      resultCallback?.({ code: ExportResultCode.FAILED, error: err as Error })\n    }\n  }\n\n  private doExport(\n    metricsData: ResourceMetrics,\n    resultCallback: (result: ExportResult) => void,\n  ): void {\n    const state = this.connection.getState()\n    if (state !== 'connected') {\n      // Drop instead of queue when there's no prospect of delivery (failed, or shutting down)\n      if (state === 'failed' || this.connection.isShuttingDown()) {\n        const reason = state === 'failed' ? 'failed' : 'shut down'\n        resultCallback({\n          code: ExportResultCode.FAILED,\n          error: new Error(`Connection ${reason}: dropping metrics`),\n        })\n        return\n      }\n      if (this.pendingExports.length >= EngineMetricsExporter.MAX_PENDING_EXPORTS) {\n        const dropped = this.pendingExports.shift()\n        dropped?.resultCallback?.({\n          code: ExportResultCode.FAILED,\n          error: new Error('Queue overflow'),\n        })\n        console.warn('[OTel] Metrics export queue full, dropped oldest entry')\n      }\n      this.pendingExports.push({ metrics: metricsData, resultCallback })\n      // Don't call resultCallback here - it will be called when actually sent or on shutdown\n      return\n    }\n\n    this.sendExport(metricsData, resultCallback)\n  }\n\n  export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void {\n    this.doExport(metrics, resultCallback)\n  }\n\n  async shutdown(): Promise<void> {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    const shutdownError = new Error('Exporter shutdown before export completed')\n    for (const { resultCallback } of pending) {\n      resultCallback?.({ code: ExportResultCode.FAILED, error: shutdownError })\n    }\n  }\n\n  async forceFlush(): Promise<void> {\n    // No-op\n  }\n}\n","/**\n * Log exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { LogRecordExporter, ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport { JsonLogsSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_LOGS } from './types'\n\n/**\n * Log exporter using the shared WebSocket connection.\n */\nexport class EngineLogExporter implements LogRecordExporter {\n  private static readonly MAX_PENDING_EXPORTS = 100\n  private connection: SharedEngineConnection\n  private pendingExports: Array<{\n    logs: ReadableLogRecord[]\n    callback: (result: ExportResult) => void\n  }> = []\n\n  constructor(connection: SharedEngineConnection) {\n    this.connection = connection\n    this.connection.onConnected(() => this.flushPending())\n    this.connection.onFailed(() => this.failPending())\n  }\n\n  private flushPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    for (const { logs, callback } of pending) {\n      this.doExport(logs, callback)\n    }\n  }\n\n  private failPending(): void {\n    const pending = this.pendingExports.splice(0, this.pendingExports.length)\n    const error = new Error('Connection failed: dropping queued logs')\n    for (const { callback } of pending) {\n      callback({ code: ExportResultCode.FAILED, error })\n    }\n  }\n\n  private doExport(\n    logs: ReadableLogRecord[],\n    resultCallback: (result: ExportResult) => void,\n  ): void {\n    const state = this.connection.getState()\n    if (state !== 'connected') {\n      // Drop instead of queue when there's no prospect of delivery (failed, or shutting down)\n      if (state === 'failed' || this.connection.isShuttingDown()) {\n        const reason = state === 'failed' ? 'failed' : 'shut down'\n        resultCallback({\n          code: ExportResultCode.FAILED,\n          error: new Error(`Connection ${reason}: dropping logs`),\n        })\n        return\n      }\n      if (this.pendingExports.length >= EngineLogExporter.MAX_PENDING_EXPORTS) {\n        const dropped = this.pendingExports.shift()\n        dropped?.callback({\n          code: ExportResultCode.FAILED,\n          error: new Error('Logs export queue full'),\n        })\n        console.warn('[OTel] Logs export queue full, dropped oldest entry')\n      }\n      this.pendingExports.push({ logs, callback: resultCallback })\n      return\n    }\n\n    try {\n      const serialized = JsonLogsSerializer.serializeRequest(logs)\n      if (!serialized) {\n        resultCallback({ code: ExportResultCode.SUCCESS })\n        return\n      }\n\n      this.connection.send(PREFIX_LOGS, serialized, err => {\n        if (err) {\n          console.error('[OTel] Failed to send logs:', err.message)\n          resultCallback({ code: ExportResultCode.FAILED, error: err })\n        } else {\n          resultCallback({ code: ExportResultCode.SUCCESS })\n        }\n      })\n    } catch (err) {\n      console.error('[OTel] Error exporting logs:', err)\n      resultCallback({ code: ExportResultCode.FAILED, error: err as Error })\n    }\n  }\n\n  export(logs: ReadableLogRecord[], resultCallback: (result: ExportResult) => void): void {\n    this.doExport(logs, resultCallback)\n  }\n\n  async forceFlush(): Promise<void> {}\n\n  async shutdown(): Promise<void> {\n    for (const { callback } of this.pendingExports) {\n      callback({ code: ExportResultCode.FAILED, error: new Error('Exporter shutdown') })\n    }\n    this.pendingExports = []\n  }\n}\n","/**\n * Trace context and baggage propagation utilities.\n */\n\nimport { trace, context, propagation, type Context } from '@opentelemetry/api'\n\n/**\n * Extract the current trace ID from the active span context.\n */\nexport function currentTraceId(): string | undefined {\n  const span = trace.getActiveSpan()\n  if (span) {\n    const spanContext = span.spanContext()\n    if (spanContext.traceId && spanContext.traceId !== '00000000000000000000000000000000') {\n      return spanContext.traceId\n    }\n  }\n  return undefined\n}\n\n/**\n * Extract the current span ID from the active span context.\n */\nexport function currentSpanId(): string | undefined {\n  const span = trace.getActiveSpan()\n  if (span) {\n    const spanContext = span.spanContext()\n    if (spanContext.spanId && spanContext.spanId !== '0000000000000000') {\n      return spanContext.spanId\n    }\n  }\n  return undefined\n}\n\n/**\n * Inject the current trace context into a W3C traceparent header string.\n */\nexport function injectTraceparent(): string | undefined {\n  const carrier: Record<string, string> = {}\n  propagation.inject(context.active(), carrier)\n  return carrier.traceparent\n}\n\n/**\n * Extract a trace context from a W3C traceparent header string.\n *\n * @param traceparent - W3C `traceparent` header value to parse.\n */\nexport function extractTraceparent(traceparent: string): Context {\n  const carrier: Record<string, string> = { traceparent }\n  return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Inject the current baggage into a W3C baggage header string.\n */\nexport function injectBaggage(): string | undefined {\n  const carrier: Record<string, string> = {}\n  propagation.inject(context.active(), carrier)\n  return carrier.baggage\n}\n\n/**\n * Extract baggage from a W3C baggage header string.\n *\n * @param baggage - W3C `baggage` header value to parse.\n */\nexport function extractBaggage(baggage: string): Context {\n  const carrier: Record<string, string> = { baggage }\n  return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Extract both trace context and baggage from their respective headers.\n *\n * @param traceparent - W3C `traceparent` header value to parse.\n * @param baggage - W3C `baggage` header value to parse.\n */\nexport function extractContext(traceparent?: string, baggage?: string): Context {\n  const carrier: Record<string, string> = {}\n  if (traceparent) {\n    carrier.traceparent = traceparent\n  }\n  if (baggage) {\n    carrier.baggage = baggage\n  }\n  return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Get a baggage entry from the current context.\n *\n * @param key - Baggage entry key to read.\n */\nexport function getBaggageEntry(key: string): string | undefined {\n  const bag = propagation.getBaggage(context.active())\n  return bag?.getEntry(key)?.value\n}\n\n/**\n * Set a baggage entry in the current context.\n *\n * @param key - Baggage entry key to set.\n * @param value - Baggage entry value to set.\n */\nexport function setBaggageEntry(key: string, value: string): Context {\n  let bag = propagation.getBaggage(context.active()) ?? propagation.createBaggage()\n  bag = bag.setEntry(key, { value })\n  return propagation.setBaggage(context.active(), bag)\n}\n\n/**\n * Remove a baggage entry from the current context.\n *\n * @param key - Baggage entry key to remove.\n */\nexport function removeBaggageEntry(key: string): Context {\n  const bag = propagation.getBaggage(context.active())\n  if (!bag) {\n    return context.active()\n  }\n  const newBag = bag.removeEntry(key)\n  return propagation.setBaggage(context.active(), newBag)\n}\n\n/**\n * Get all baggage entries from the current context.\n */\nexport function getAllBaggage(): Record<string, string> {\n  const bag = propagation.getBaggage(context.active())\n  if (!bag) {\n    return {}\n  }\n  const entries: Record<string, string> = {}\n  for (const [key, entry] of bag.getAllEntries()) {\n    entries[key] = entry.value\n  }\n  return entries\n}\n","/**\n * Global fetch auto-instrumentation for the III Node SDK.\n *\n * Patches globalThis.fetch to create OTel CLIENT spans for every HTTP request.\n * Works on all runtimes (Bun, Node.js, Deno) unlike UndiciInstrumentation\n * which only works when fetch is backed by Node.js's undici.\n */\n\nimport { type Tracer, SpanKind, SpanStatusCode, context, propagation } from '@opentelemetry/api'\n\nconst textEncoder = new TextEncoder()\n\nfunction getBodyByteSize(body: unknown): number | undefined {\n  if (body == null) return undefined\n  if (typeof body === 'string') return textEncoder.encode(body).byteLength\n  if (body instanceof ArrayBuffer) return body.byteLength\n  if (ArrayBuffer.isView(body)) return body.byteLength\n  if (body instanceof Blob) return body.size\n  if (body instanceof URLSearchParams) return new TextEncoder().encode(body.toString()).byteLength\n  return undefined\n}\n\nconst SAFE_REQUEST_HEADERS = ['content-type', 'accept'] as const\nconst SAFE_RESPONSE_HEADERS = ['content-type'] as const\n\nlet originalFetch: typeof globalThis.fetch | null = null\n\n/**\n * Substring patterns from `OTEL_FETCH_IGNORE_URLS` (comma-separated). A fetch\n * whose URL contains any pattern is executed WITHOUT creating a span, use it\n * to drop noisy/high-frequency calls (health checks, polling, internal\n * endpoints) that would otherwise flood traces.\n */\nconst FETCH_IGNORE_URL_PATTERNS: string[] = (process.env.OTEL_FETCH_IGNORE_URLS ?? '')\n  .split(',')\n  .map(s => s.trim())\n  .filter(Boolean)\n\nfunction shouldIgnoreFetchUrl(url: string): boolean {\n  return FETCH_IGNORE_URL_PATTERNS.some(pattern => url.includes(pattern))\n}\n\n/**\n * Patch globalThis.fetch to create OTel CLIENT spans for every HTTP request.\n *\n * @param tracer - Tracer used to create the client span for each request.\n */\nexport function patchGlobalFetch(tracer: Tracer): void {\n  if (originalFetch) return\n\n  originalFetch = globalThis.fetch\n  const capturedFetch = originalFetch\n\n  globalThis.fetch = async (\n    input: string | URL | Request,\n    init?: RequestInit,\n  ): Promise<Response> => {\n    const url = input instanceof Request ? input.url : String(input)\n\n    // Skip tracing entirely for ignored URLs (no span, no context injection).\n    if (shouldIgnoreFetchUrl(url)) {\n      return capturedFetch(input, init)\n    }\n\n    const method = (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase()\n\n    let host: string | undefined\n    let scheme: string | undefined\n    let path: string | undefined\n    let port: number | undefined\n    let query: string | undefined\n    try {\n      const parsed = new URL(url)\n      host = parsed.hostname\n      scheme = parsed.protocol.replace(':', '')\n      path = parsed.pathname\n      port = parsed.port ? parseInt(parsed.port, 10) : undefined\n      query = parsed.search ? parsed.search.slice(1) : undefined\n    } catch {\n      // relative URL or invalid, skip host/scheme/path attributes\n    }\n\n    const spanAttributes: Record<string, string | number> = {\n      'http.request.method': method,\n      'url.full': url,\n    }\n    if (host) spanAttributes['server.address'] = host\n    if (scheme) {\n      spanAttributes['url.scheme'] = scheme\n      spanAttributes['network.protocol.name'] = 'http'\n    }\n    if (path) spanAttributes['url.path'] = path\n    if (port) spanAttributes['server.port'] = port\n    if (query) spanAttributes['url.query'] = query\n\n    const spanName = path ? `${method} ${path}` : method\n\n    return tracer.startActiveSpan(\n      spanName,\n      { kind: SpanKind.CLIENT, attributes: spanAttributes },\n      context.active(),\n      async span => {\n        try {\n          const carrier: Record<string, string> = {}\n          propagation.inject(context.active(), carrier)\n\n          const headers = new Headers(\n            init?.headers ?? (input instanceof Request ? input.headers : undefined),\n          )\n          for (const [key, value] of Object.entries(carrier)) {\n            headers.set(key, value)\n          }\n\n          for (const name of SAFE_REQUEST_HEADERS) {\n            const value = headers.get(name)\n            if (value !== null) {\n              span.setAttribute(`http.request.header.${name}`, value)\n            }\n          }\n\n          const requestBody = init?.body ?? (input instanceof Request ? input.body : undefined)\n          const requestBodySize = getBodyByteSize(requestBody)\n          if (requestBodySize !== undefined) {\n            span.setAttribute('http.request.body.size', requestBodySize)\n          }\n\n          const response = await capturedFetch(input, { ...init, headers })\n\n          span.setAttribute('http.response.status_code', response.status)\n\n          const contentLength = response.headers.get('content-length')\n          if (contentLength !== null) {\n            const size = parseInt(contentLength, 10)\n            if (!Number.isNaN(size)) {\n              span.setAttribute('http.response.body.size', size)\n            }\n          }\n\n          for (const name of SAFE_RESPONSE_HEADERS) {\n            const value = response.headers.get(name)\n            if (value !== null) {\n              span.setAttribute(`http.response.header.${name}`, value)\n            }\n          }\n\n          if (response.status >= 400) {\n            span.setAttribute('error.type', String(response.status))\n            span.setStatus({ code: SpanStatusCode.ERROR })\n          } else {\n            span.setStatus({ code: SpanStatusCode.OK })\n          }\n\n          return response\n        } catch (error) {\n          span.setAttribute('error.type', (error as Error).name ?? 'Error')\n          span.setStatus({ code: SpanStatusCode.ERROR, message: (error as Error).message })\n          span.recordException(error as Error)\n          throw error\n        } finally {\n          span.end()\n        }\n      },\n    )\n  }\n}\n\n/**\n * Restore globalThis.fetch to its original implementation.\n */\nexport function unpatchGlobalFetch(): void {\n  if (originalFetch) {\n    globalThis.fetch = originalFetch\n    originalFetch = null\n  }\n}\n","/**\n * Parse a numeric environment variable with optional minimum bound.\n *\n * An empty or whitespace-only string is treated as unset: `Number('')` is 0,\n * so without this check a variable set-but-blank (common in .env files) would\n * silently resolve to 0 instead of falling through to the default.\n */\nexport function parseNumberEnv(value: string | undefined, minimum: number = 0): number | undefined {\n  if (value === undefined || value.trim() === '') return undefined\n  const parsed = Number(value)\n  if (!Number.isFinite(parsed) || parsed < minimum) return undefined\n  return parsed\n}\n\n/**\n * Parse an integer environment variable with optional minimum bound.\n */\nexport function parseIntegerEnv(\n  value: string | undefined,\n  minimum: number = 0,\n): number | undefined {\n  const parsed = parseNumberEnv(value, minimum)\n  if (parsed === undefined || !Number.isInteger(parsed)) return undefined\n  return parsed\n}\n\n/**\n * Resolve a batch-processor flush delay: explicit config wins, then the\n * III-specific env var, then the III default.\n *\n * III SDKs deliberately expose a single OTEL_*_FLUSH_INTERVAL_MS knob and do\n * NOT honor the standard OTel OTEL_BSP_SCHEDULE_DELAY / OTEL_BLRP_SCHEDULE_DELAY\n * vars, for cross-SDK consistency (the Node, Python, and Rust SDKs all resolve\n * the same way). Passing an explicit `scheduledDelayMillis` to the processor\n * already makes the OTel SDK ignore those standard vars regardless.\n */\nexport function resolveFlushIntervalMs(\n  configValue: number | undefined,\n  envValue: string | undefined,\n  defaultValue: number,\n): number {\n  return configValue ?? parseNumberEnv(envValue, 0) ?? defaultValue\n}\n","/** High-level span operations so consumers don't need `@opentelemetry/api`. */\n\nimport { SpanStatusCode, trace, type AttributeValue, type Attributes } from '@opentelemetry/api'\n\n/** Returns `false` when there is no active span or the sampler dropped it. */\nexport function currentSpanIsRecording(): boolean {\n  const span = trace.getActiveSpan()\n  return span ? span.isRecording() : false\n}\n\n/**\n * No-op when the current span is not recording.\n *\n * @param key - Attribute key to set on the active span.\n * @param value - Attribute value to set.\n */\nexport function setCurrentSpanAttribute(key: string, value: AttributeValue): void {\n  const span = trace.getActiveSpan()\n  if (!span || !span.isRecording()) return\n  span.setAttribute(key, value)\n}\n\n/**\n * No-op when there is no active span.\n *\n * @param message - Error message to set as the span's error status.\n */\nexport function setCurrentSpanError(message: string): void {\n  const span = trace.getActiveSpan()\n  if (!span) return\n  span.setStatus({ code: SpanStatusCode.ERROR, message })\n}\n\n/**\n * No-op when the current span is not recording.\n *\n * @param name - Name of the event to add to the active span.\n * @param attrs - Optional attributes to attach to the event.\n */\nexport function recordSpanEvent(name: string, attrs?: Attributes): void {\n  const span = trace.getActiveSpan()\n  if (!span || !span.isRecording()) return\n  span.addEvent(name, attrs)\n}\n","/** Payload redaction + truncation for invocation event capture. */\n\nexport const REDACTED_PLACEHOLDER = '[REDACTED]'\nconst TRUNCATION_MARKER = '...\"[TRUNCATED]\"'\n\n/**\n * Resolve the payload byte cap from the environment, returning undefined when\n * unset.\n */\nexport function resolveMaxBytesFromEnv(): number | null {\n  const raw = process.env.III_TRACE_PAYLOAD_MAX_BYTES\n  if (raw === undefined) return null\n  const trimmed = raw.trim()\n  if (trimmed === '' || trimmed.toLowerCase() === 'unlimited') return null\n  // parseInt accepts partial parses like \"8192mb\" → 8192; Python int()\n  // and Rust parse::<usize>() reject those. Match the strict semantics.\n  if (!/^\\d+$/.test(trimmed)) return null\n  const parsed = Number(trimmed)\n  if (parsed <= 0) return null\n  return parsed\n}\n\nconst SENSITIVE_FRAGMENTS = [\n  'api_key',\n  'apikey',\n  'api-key',\n  'password',\n  'secret',\n  'credential',\n  'authorization',\n  'auth_token',\n  'access_token',\n  'refresh_token',\n  'bearer',\n  'private_key',\n  'client_secret',\n]\n\nfunction isSensitiveKey(key: string): boolean {\n  const lower = key.toLowerCase()\n  if (SENSITIVE_FRAGMENTS.some((fragment) => lower.includes(fragment))) return true\n  // `token` alone is too common a substring; require whole-key or suffix match.\n  return lower === 'token' || lower.endsWith('_token') || lower.endsWith('-token')\n}\n\n/**\n * Recursively redact values of sensitive keys. Returns a new value.\n *\n * @param value - The value to recursively redact.\n */\nexport function redact(value: unknown): unknown {\n  if (value === null || value === undefined) return value\n  if (Array.isArray(value)) return value.map(redact)\n  if (typeof value === 'object') {\n    const out: Record<string, unknown> = {}\n    for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n      out[k] = isSensitiveKey(k) ? REDACTED_PLACEHOLDER : redact(v)\n    }\n    return out\n  }\n  return value\n}\n\n/**\n * Redact then serialize to JSON, optionally capped at `maxBytes`.\n *\n * @param value - The value to redact and serialize.\n * @param maxBytes - Maximum serialized size in bytes; null leaves it uncapped.\n */\nexport function redactAndTruncate(\n  value: unknown,\n  maxBytes: number | null = null,\n): { json: string; truncated: boolean } {\n  const redacted = redact(value)\n  let serialized: string\n  try {\n    serialized = JSON.stringify(redacted) ?? 'null'\n  } catch {\n    serialized = 'null'\n  }\n\n  if (maxBytes === null || maxBytes === undefined || maxBytes <= 0) {\n    return { json: serialized, truncated: false }\n  }\n\n  const byteLen = Buffer.byteLength(serialized, 'utf8')\n  if (byteLen <= maxBytes) {\n    return { json: serialized, truncated: false }\n  }\n\n  const markerLen = Buffer.byteLength(TRUNCATION_MARKER, 'utf8')\n  // When maxBytes is smaller than the marker itself, emit only a\n  // truncated marker so the result never exceeds the cap.\n  if (maxBytes <= markerLen) {\n    return { json: TRUNCATION_MARKER.slice(0, maxBytes), truncated: true }\n  }\n\n  const cap = maxBytes - markerLen\n  const buf = Buffer.from(serialized, 'utf8')\n  let cut = Math.min(cap, buf.length)\n  // Walk back to a UTF-8 boundary so we don't emit half-codepoints.\n  while (cut > 0 && (buf[cut] & 0xc0) === 0x80) {\n    cut -= 1\n  }\n  const truncated = buf.subarray(0, cut).toString('utf8') + TRUNCATION_MARKER\n  return { json: truncated, truncated: true }\n}\n","/**\n * OpenTelemetry initialization for the III Node SDK.\n *\n * This module provides trace, metrics, and log export to the III Engine\n * via a shared WebSocket connection using OTLP JSON format.\n */\n\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'\nimport { randomUUID } from 'node:crypto'\nimport {\n  trace,\n  context,\n  propagation,\n  SpanKind,\n  SpanStatusCode,\n  metrics,\n  type Span,\n  type Context,\n  type Tracer,\n  type Meter,\n} from '@opentelemetry/api'\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { BaggageSpanProcessor } from './baggage-span-processor'\nimport { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport { CompositePropagator, W3CBaggagePropagator, W3CTraceContextPropagator } from '@opentelemetry/core'\nimport { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'\nimport { registerInstrumentations } from '@opentelemetry/instrumentation'\nimport { LoggerProvider, BatchLogRecordProcessor } from '@opentelemetry/sdk-logs'\nimport { type Logger, SeverityNumber } from '@opentelemetry/api-logs'\n\nimport {\n  type OtelConfig,\n  DEFAULT_OTEL_CONFIG,\n  parseBoolEnv,\n  ATTR_SERVICE_VERSION,\n  ATTR_SERVICE_NAMESPACE,\n  ATTR_SERVICE_INSTANCE_ID,\n} from './types'\nimport { SharedEngineConnection } from './connection'\nimport { EngineSpanExporter, EngineMetricsExporter, EngineLogExporter } from './exporters'\nimport { extractTraceparent } from './context'\nimport { patchGlobalFetch, unpatchGlobalFetch } from './fetch-instrumentation'\nimport { parseIntegerEnv, resolveFlushIntervalMs } from './utils'\n\n// Re-export everything from submodules\nexport * from './types'\nexport * from './context'\nexport { BaggageSpanProcessor } from './baggage-span-processor'\nexport {\n  currentSpanIsRecording,\n  recordSpanEvent,\n  setCurrentSpanAttribute,\n  setCurrentSpanError,\n} from './span-ops'\nexport {\n  REDACTED_PLACEHOLDER,\n  redact,\n  redactAndTruncate,\n  resolveMaxBytesFromEnv,\n} from './payload'\n\n/**\n * Normalize an engine WebSocket URL into the dedicated OTEL endpoint.\n * The engine exposes `/otel` for telemetry-only WS connections; routing\n * there keeps this socket out of the worker registry (otherwise it shows\n * up as a ghost null-metadata worker).\n */\nfunction appendOtelPath(base: string): string {\n  const url = new URL(base)\n  const path = url.pathname.replace(/\\/+$/, '')\n  url.pathname = path.endsWith('/otel') ? path : `${path}/otel`\n  return url.toString()\n}\n\n// Module-level state\nlet sharedConnection: SharedEngineConnection | null = null\nlet tracerProvider: NodeTracerProvider | null = null\nlet meterProvider: MeterProvider | null = null\nlet loggerProvider: LoggerProvider | null = null\nlet tracer: Tracer | null = null\nlet meter: Meter | null = null\nlet logger: Logger | null = null\nlet serviceName: string = 'iii-node-iii'\n\n/**\n * Initialize OpenTelemetry with the given configuration.\n * This should be called once at application startup.\n *\n * @param config - OpenTelemetry configuration; env vars fill in unset fields.\n */\nexport function initOtel(config: OtelConfig = {}): void {\n  const enabled = config.enabled ?? parseBoolEnv(process.env.OTEL_ENABLED, DEFAULT_OTEL_CONFIG.enabled)\n\n  if (!enabled) {\n    console.debug(\n      '[OTel] OpenTelemetry is disabled. To enable, remove OTEL_ENABLED=false or set enabled: true in config.',\n    )\n    return\n  }\n\n  // Configure service identity\n  serviceName = config.serviceName ?? process.env.OTEL_SERVICE_NAME ?? DEFAULT_OTEL_CONFIG.serviceName\n  const serviceVersion = config.serviceVersion ?? process.env.SERVICE_VERSION ?? DEFAULT_OTEL_CONFIG.serviceVersion\n  const serviceNamespace = config.serviceNamespace ?? process.env.SERVICE_NAMESPACE\n  const serviceInstanceId = config.serviceInstanceId ?? process.env.SERVICE_INSTANCE_ID ?? randomUUID()\n  const engineWsUrl = config.engineWsUrl ?? process.env.III_URL ?? DEFAULT_OTEL_CONFIG.engineWsUrl\n\n  // Build resource attributes\n  const resourceAttributes: Record<string, string> = {\n    [ATTR_SERVICE_NAME]: serviceName,\n    [ATTR_SERVICE_VERSION]: serviceVersion,\n    [ATTR_SERVICE_INSTANCE_ID]: serviceInstanceId,\n  }\n  if (serviceNamespace) {\n    resourceAttributes[ATTR_SERVICE_NAMESPACE] = serviceNamespace\n  }\n  const resource = resourceFromAttributes(resourceAttributes)\n\n  // Create shared WebSocket connection.\n  // OTEL always connects to the engine's dedicated `/otel` endpoint so\n  // the telemetry socket doesn't get registered in `worker_registry` as\n  // a ghost null-metadata worker alongside the real worker.\n  sharedConnection = new SharedEngineConnection(\n    appendOtelPath(engineWsUrl),\n    config.reconnectionConfig,\n    config.engineWsHeaders,\n  )\n\n  // BaggageSpanProcessor must register first: onStart fires in\n  // registration order, so baggage entries are materialized as span\n  // attributes before the batch exporter reads them.\n  const spanExporter = new EngineSpanExporter(sharedConnection)\n  // Without an explicit scheduledDelayMillis, BatchSpanProcessor inherits the\n  // OpenTelemetry default of 5000ms, so an ended span sits in the buffer up to\n  // 5s before it is flushed to the engine, the dominant reason traces show up\n  // seconds after the action that produced them. Mirror the logs path\n  // (BatchLogRecordProcessor below) with a small flush delay. maxExportBatchSize\n  // stays at the OTel default so a burst of spans from one turn still coalesces\n  // into a single frame rather than one frame per span.\n  const spansScheduledDelayMillis = resolveFlushIntervalMs(\n    config.spansFlushIntervalMs,\n    process.env.OTEL_SPANS_FLUSH_INTERVAL_MS,\n    DEFAULT_OTEL_CONFIG.spansFlushIntervalMs,\n  )\n  tracerProvider = new NodeTracerProvider({\n    resource,\n    spanProcessors: [\n      new BaggageSpanProcessor(),\n      new BatchSpanProcessor(spanExporter, { scheduledDelayMillis: spansScheduledDelayMillis }),\n    ],\n  })\n\n  // Register W3C Trace Context and Baggage propagators\n  propagation.setGlobalPropagator(\n    new CompositePropagator({\n      propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()],\n    }),\n  )\n\n  tracerProvider.register()\n  tracer = trace.getTracer(serviceName)\n\n  console.debug(`[OTel] Traces initialized: engine=${engineWsUrl}, service=${serviceName}`)\n\n  // Initialize metrics (enabled by default, opt-out via config or env)\n  const metricsEnabled =\n    config.metricsEnabled ?? parseBoolEnv(process.env.OTEL_METRICS_ENABLED, DEFAULT_OTEL_CONFIG.metricsEnabled)\n\n  if (metricsEnabled) {\n    const metricsExporter = new EngineMetricsExporter(sharedConnection)\n    const exportIntervalMs = config.metricsExportIntervalMs ?? DEFAULT_OTEL_CONFIG.metricsExportIntervalMs\n\n    const metricReader = new PeriodicExportingMetricReader({\n      exporter: metricsExporter,\n      exportIntervalMillis: exportIntervalMs,\n    })\n\n    meterProvider = new MeterProvider({\n      resource,\n      readers: [metricReader],\n    })\n\n    metrics.setGlobalMeterProvider(meterProvider)\n    meter = meterProvider.getMeter(serviceName)\n\n    console.debug(`[OTel] Metrics initialized: interval=${exportIntervalMs}ms`)\n  }\n\n  // Register user-provided instrumentations AFTER providers are set up\n  const instrumentations = [...(config.instrumentations ?? [])]\n  if (instrumentations.length > 0) {\n    registerInstrumentations({\n      instrumentations,\n      tracerProvider,\n      meterProvider: meterProvider ?? undefined,\n    })\n    console.debug(`[OTel] Instrumentations registered: ${instrumentations.length} total`)\n  }\n\n  // Patch global fetch for runtime-agnostic HTTP client tracing (works on Bun, Node.js, Deno)\n  const fetchEnabled = config.fetchInstrumentationEnabled ?? DEFAULT_OTEL_CONFIG.fetchInstrumentationEnabled\n\n  if (fetchEnabled) {\n    patchGlobalFetch(tracer)\n    console.debug('[OTel] Global fetch instrumentation enabled')\n  }\n\n  // Initialize logs (always enabled when OTEL is enabled)\n  const logExporter = new EngineLogExporter(sharedConnection)\n  const logsScheduledDelayMillis = resolveFlushIntervalMs(\n    config.logsFlushIntervalMs,\n    process.env.OTEL_LOGS_FLUSH_INTERVAL_MS,\n    DEFAULT_OTEL_CONFIG.logsFlushIntervalMs,\n  )\n  const logsMaxExportBatchSize =\n    config.logsBatchSize ?? parseIntegerEnv(process.env.OTEL_LOGS_BATCH_SIZE, 1) ?? DEFAULT_OTEL_CONFIG.logsBatchSize\n\n  loggerProvider = new LoggerProvider({\n    resource,\n    processors: [\n      new BatchLogRecordProcessor({\n        exporter: logExporter,\n        scheduledDelayMillis: logsScheduledDelayMillis,\n        maxExportBatchSize: logsMaxExportBatchSize,\n      }),\n    ],\n  })\n  logger = loggerProvider.getLogger(serviceName)\n\n  console.debug(`[OTel] Logs initialized: delay=${logsScheduledDelayMillis}ms, batch=${logsMaxExportBatchSize}`)\n}\n\n/**\n * Shut down OpenTelemetry, best-effort flushing any pending data before\n * teardown.\n */\nexport async function shutdownOtel(): Promise<void> {\n  // Stop reconnecting/queuing before flushing so a final forceFlush() can't hang on a dead engine\n  sharedConnection?.beginShutdown()\n\n  // Flushing is best-effort on shutdown: when the engine is gone the exporters\n  // fail their pending exports, which rejects forceFlush()/shutdown(). Swallow\n  // those so a dropped final flush can't crash or block teardown.\n  const settle = (p: Promise<unknown>) => p.catch(() => {})\n\n  if (tracerProvider) {\n    await settle(tracerProvider.forceFlush())\n    await settle(tracerProvider.shutdown())\n    tracerProvider = null\n  }\n\n  if (meterProvider) {\n    await settle(meterProvider.forceFlush())\n    await settle(meterProvider.shutdown())\n    meterProvider = null\n  }\n\n  if (loggerProvider) {\n    await settle(loggerProvider.forceFlush())\n    await settle(loggerProvider.shutdown())\n    loggerProvider = null\n  }\n\n  if (sharedConnection) {\n    await sharedConnection.shutdown()\n    sharedConnection = null\n  }\n\n  unpatchGlobalFetch()\n\n  tracer = null\n  meter = null\n  logger = null\n}\n\n/**\n * Force-flush all OTel providers without tearing them down.\n *\n * Counterpart to {@link shutdownOtel}. Use before short-lived process exits\n * where you want pending spans/metrics/logs delivered but plan to keep using\n * OTel afterwards.\n */\nexport async function flushOtel(): Promise<void> {\n  await Promise.all(\n    [\n      tracerProvider?.forceFlush(),\n      meterProvider?.forceFlush(),\n      loggerProvider?.forceFlush(),\n    ].filter(Boolean),\n  )\n}\n\n/**\n * Get the OpenTelemetry tracer instance.\n */\nexport function getTracer(): Tracer | null {\n  return tracer\n}\n\n/**\n * Get the OpenTelemetry meter instance.\n */\nexport function getMeter(): Meter | null {\n  return meter\n}\n\n/**\n * Get the OpenTelemetry logger instance.\n */\nexport function getLogger(): Logger | null {\n  return logger\n}\n\n/**\n * Start a new span with the given name and run the callback within it.\n *\n * @param name - Name of the span to create.\n * @param options - Span options: `kind` sets the span kind, `traceparent` sets the parent context from a W3C traceparent header.\n * @param fn - Callback run inside the active span; its result is returned.\n */\nexport async function withSpan<T>(\n  name: string,\n  options: { kind?: SpanKind; traceparent?: string },\n  fn: (span: Span) => Promise<T>,\n): Promise<T> {\n  if (!tracer) {\n    // Execute without span context when tracer is not initialized\n    // Provide a no-op span to avoid runtime errors if fn calls span methods\n    const noopSpan: Span = {\n      spanContext: () => ({ traceId: '', spanId: '', traceFlags: 0 }),\n      setAttribute: () => noopSpan,\n      setAttributes: () => noopSpan,\n      addEvent: () => noopSpan,\n      addLink: () => noopSpan,\n      setStatus: () => noopSpan,\n      updateName: () => noopSpan,\n      end: () => {},\n      isRecording: () => false,\n      recordException: () => {},\n      addLinks: () => noopSpan,\n    }\n    return fn(noopSpan)\n  }\n\n  const parentContext = options.traceparent ? extractTraceparent(options.traceparent) : context.active()\n\n  return tracer.startActiveSpan(name, { kind: options.kind ?? SpanKind.INTERNAL }, parentContext, async (span) => {\n    try {\n      const result = await fn(span)\n      span.setStatus({ code: SpanStatusCode.OK })\n      return result\n    } catch (error) {\n      span.setStatus({ code: SpanStatusCode.ERROR, message: (error as Error).message })\n      span.recordException(error as Error)\n      throw error\n    } finally {\n      span.end()\n    }\n  })\n}\n\n// Re-export OTEL types for convenience\nexport { SpanKind, SpanStatusCode, SeverityNumber, type Span, type Context, type Tracer, type Meter, type Logger as OtelApiLogger }\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,IAAa,uBAAb,MAA2D;CACzD,QAAQ,MAAY,eAA8B;AAEhD,MAAI,CAAC,KAAK,aAAa,CACrB;EAGF,MAAM,UAAUA,+BAAY,WAAW,cAAc;AACrD,MAAI,CAAC,QACH;AAGF,OAAK,MAAM,CAAC,KAAK,UAAU,QAAQ,eAAe,CAChD,MAAK,aAAa,KAAK,MAAM,MAAM;;CAIvC,MAAM,OAA2B;CAIjC,MAAM,WAA0B;CAIhC,MAAM,aAA4B;;;;;ACtCpC,MAAa,uBAAuB;AACpC,MAAa,yBAAyB;AACtC,MAAa,2BAA2B;;AAGxC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;AAC9B,MAAa,cAAc;;AAoB3B,MAAa,8BAAkD;CAC7D,gBAAgB;CAChB,YAAY;CACZ,mBAAmB;CACnB,cAAc;CACd,YAAY;CACb;;AA0CD,MAAa,sBAAsB;CACjC,SAAS;CACT,aAAa;CACb,gBAAgB;CAChB,aAAa;CACb,gBAAgB;CAChB,yBAAyB;CACzB,sBAAsB;CACtB,qBAAqB;CACrB,eAAe;CACf,6BAA6B;CAC9B;;AAGD,SAAgB,aAAa,OAA2B,cAAgC;AACtF,KAAI,UAAU,OAAW,QAAO;CAChC,MAAM,QAAQ,MAAM,aAAa;AACjC,QAAO,UAAU,WAAW,UAAU,OAAO,UAAU,QAAQ,UAAU;;;;;;;;;;;;ACxF3E,IAAa,yBAAb,MAAa,uBAAuB;CAClC,OAAwB,uBAAuB;CAC/C,AAAQ,KAAuB;CAC/B,AAAQ;CACR,AAAQ,aAAa;CACrB,AAAQ,eAAe;CACvB,AAAQ,kBAA8E,EAAE;CACxF,AAAQ,mBAAmB;CAC3B,AAAQ,mBAA0C;CAClD,AAAQ;CACR,AAAQ,QAAyB;CACjC,AAAQ,uBAA0C,EAAE;CACpD,AAAQ,oBAAuC,EAAE;CAEjD,YACE,OACA,SAAsC,EAAE,EACxC,AAAiB,SACjB;EADiB;AAEjB,OAAK,QAAQ;AACb,OAAK,SAAS;GAAE,GAAG;GAA6B,GAAG;GAAQ;AAC3D,OAAK,SAAS;;CAGhB,AAAQ,UAAgB;AACtB,MAAI,KAAK,cAAe,KAAK,MAAM,KAAK,GAAG,eAAeC,aAAU,KAClE;AAGF,OAAK,aAAa;AAClB,OAAK,QAAQ;AAEb,MAAI;AAEF,QAAK,KAAK,IAAIA,aAAU,KAAK,OAAO;IAAE,kBAAkB;IAAO,SAAS,KAAK;IAAS,CAAC;AAEvF,QAAK,GAAG,GAAG,cAAc;AACvB,SAAK,aAAa;AAClB,SAAK,QAAQ;AACb,YAAQ,IAAI,iCAAiC,KAAK,QAAQ;AAG1D,QAAI,KAAK,mBAAmB,EAC1B,SAAQ,IAAI,kCAAkC;AAEhD,SAAK,mBAAmB;AAGxB,QAAI,KAAK,kBAAkB;AACzB,kBAAa,KAAK,iBAAiB;AACnC,UAAK,mBAAmB;;IAI1B,MAAM,UAAU,KAAK,gBAAgB,OAAO,GAAG,KAAK,gBAAgB,OAAO;AAC3E,SAAK,MAAM,EAAE,OAAO,cAAc,QAChC,MAAK,IAAI,KAAK,QAAO,QAAO,WAAW,IAAI,CAAC;AAI9C,SAAK,MAAM,MAAM,KAAK,qBACpB,KAAI;KAEN;AAEF,QAAK,GAAG,GAAG,eAAe;AACxB,SAAK,aAAa;AAClB,SAAK,KAAK;AAGV,QAAI,KAAK,cAAc;AACrB,UAAK,QAAQ;AACb,aAAQ,IAAI,2CAA2C;AACvD;;AAGF,SAAK,QAAQ;AACb,YAAQ,IAAI,qDAAqD;AACjE,SAAK,mBAAmB;KACxB;AAEF,QAAK,GAAG,GAAG,UAAS,QAAO;AACzB,SAAK,aAAa;AAGlB,QAAI,KAAK,aACP;AAGF,YAAQ,MAAM,2BAA2B,IAAI,QAAQ;KACrD;WACK,KAAK;AACZ,QAAK,aAAa;AAClB,WAAQ,MAAM,6BAA6B,IAAI;AAC/C,QAAK,mBAAmB;;;CAI5B,AAAQ,oBAA0B;AAChC,MAAI,KAAK,OAAO,eAAe,MAAM,KAAK,oBAAoB,KAAK,OAAO,YAAY;AACpF,QAAK,QAAQ;AACb,WAAQ,MAAM,uBAAuB,KAAK,OAAO,WAAW,sBAAsB;GAGlF,MAAM,UAAU,KAAK,gBAAgB,OAAO,GAAG,KAAK,gBAAgB,OAAO;GAC3E,MAAM,8BAAc,IAAI,MAAM,sCAAsC;AACpE,QAAK,MAAM,EAAE,cAAc,QACzB,YAAW,YAAY;AAIzB,QAAK,MAAM,MAAM,KAAK,kBACpB,KAAI;AACF,QAAI;YACG,KAAK;AACZ,YAAQ,MAAM,mCAAmC,IAAI;;AAGzD;;AAGF,MAAI,KAAK,iBACP;EAGF,MAAM,mBACJ,KAAK,OAAO,iBAAiB,KAAK,OAAO,qBAAqB,KAAK;EACrE,MAAM,cAAc,KAAK,IAAI,kBAAkB,KAAK,OAAO,WAAW;EACtE,MAAM,SAAS,cAAc,KAAK,OAAO,gBAAgB,IAAI,KAAK,QAAQ,GAAG;EAC7E,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,OAAO,CAAC;AAE3D,OAAK,QAAQ;AACb,UAAQ,IAAI,0BAA0B,MAAM,cAAc,KAAK,mBAAmB,EAAE,MAAM;AAE1F,OAAK,mBAAmB,iBAAiB;AACvC,QAAK,mBAAmB;AACxB,QAAK;AACL,QAAK,SAAS;KACb,MAAM;;;;;CAMX,KAAK,QAAgB,MAAkB,UAAwC;EAC7E,MAAM,cAAc,OAAO,KAAK,QAAQ,QAAQ;EAChD,MAAM,QAAQ,OAAO,OAAO,CAAC,aAAa,OAAO,KAAK,KAAK,CAAC,CAAC;AAE7D,MAAI,KAAK,MAAM,KAAK,GAAG,eAAeA,aAAU,KAC9C,MAAK,GAAG,KAAK,OAAO,SAAS;OACxB;AAEL,OAAI,KAAK,gBAAgB,UAAU,uBAAuB,sBAAsB;AAC9E,YAAQ,KAAK,6DAA6D;AAE1E,IADgB,KAAK,gBAAgB,OAC9B,EAAE,2BAAW,IAAI,MAAM,wCAAwC,CAAC;;AAEzE,QAAK,gBAAgB,KAAK;IAAE;IAAO;IAAU,CAAC;AAC9C,QAAK,SAAS;;;;;;CAOlB,YAAY,UAA4B;AACtC,OAAK,qBAAqB,KAAK,SAAS;AACxC,MAAI,KAAK,UAAU,YACjB,WAAU;;;;;;;CASd,SAAS,UAA4B;AACnC,OAAK,kBAAkB,KAAK,SAAS;AACrC,MAAI,KAAK,UAAU,SACjB,KAAI;AACF,aAAU;WACH,KAAK;AACZ,WAAQ,MAAM,mCAAmC,IAAI;;;;;;CAQ3D,WAA4B;AAC1B,SAAO,KAAK;;;;;;;CAQd,iBAA0B;AACxB,SAAO,KAAK;;;;;;;CAQd,gBAAsB;AACpB,MAAI,KAAK,aACP;AAEF,OAAK,eAAe;AAEpB,MAAI,KAAK,kBAAkB;AACzB,gBAAa,KAAK,iBAAiB;AACnC,QAAK,mBAAmB;;AAK1B,MAAI,KAAK,UAAU,aAAa;GAC9B,MAAM,UAAU,KAAK,gBAAgB,OAAO,GAAG,KAAK,gBAAgB,OAAO;GAC3E,MAAM,gCAAgB,IAAI,MAAM,mDAAmD;AACnF,QAAK,MAAM,EAAE,cAAc,QACzB,YAAW,cAAc;AAG3B,QAAK,MAAM,MAAM,KAAK,kBACpB,KAAI;AACF,QAAI;YACG,KAAK;AACZ,YAAQ,MAAM,mCAAmC,IAAI;;;;;;;CAS7D,MAAM,WAA0B;AAE9B,OAAK,eAAe;AAEpB,MAAI,KAAK,kBAAkB;AACzB,gBAAa,KAAK,iBAAiB;AACnC,QAAK,mBAAmB;;AAG1B,MAAI,KAAK,IAAI;AACX,QAAK,GAAG,OAAO;AACf,QAAK,KAAK;;EAIZ,MAAM,UAAU,KAAK,gBAAgB,OAAO,GAAG,KAAK,gBAAgB,OAAO;EAC3E,MAAM,gCAAgB,IAAI,MAAM,mDAAmD;AACnF,OAAK,MAAM,EAAE,cAAc,QACzB,YAAW,cAAc;AAE3B,OAAK,uBAAuB,EAAE;AAC9B,OAAK,oBAAoB,EAAE;AAC3B,OAAK,QAAQ;;;;;;;;;;;;ACrQjB,IAAa,qBAAb,MAAa,mBAA2C;CACtD,OAAwB,sBAAsB;CAC9C,AAAQ;CACR,AAAQ,iBAGH,EAAE;CAEP,YAAY,YAAoC;AAC9C,OAAK,aAAa;AAClB,OAAK,WAAW,kBAAkB,KAAK,cAAc,CAAC;AACtD,OAAK,WAAW,eAAe,KAAK,aAAa,CAAC;;CAGpD,AAAQ,eAAqB;EAC3B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;AACzE,OAAK,MAAM,EAAE,OAAO,oBAAoB,QACtC,MAAK,WAAW,OAAO,eAAe;;CAI1C,AAAQ,cAAoB;EAC1B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;EACzE,MAAM,wBAAQ,IAAI,MAAM,2CAA2C;AACnE,OAAK,MAAM,EAAE,oBAAoB,QAC/B,kBAAiB;GAAE,MAAMC,qCAAiB;GAAQ;GAAO,CAAC;;CAI9D,AAAQ,WAAW,OAAuB,gBAAuD;AAC/F,MAAI;GACF,MAAM,aAAaC,oDAAoB,iBAAiB,MAAM;AAC9D,OAAI,CAAC,YAAY;AACf,qBAAiB,EAAE,MAAMD,qCAAiB,SAAS,CAAC;AACpD;;AAGF,QAAK,WAAW,KAAK,eAAe,aAAY,QAAO;AACrD,QAAI,KAAK;AACP,aAAQ,MAAM,gCAAgC,IAAI,QAAQ;AAC1D,sBAAiB;MAAE,MAAMA,qCAAiB;MAAQ,OAAO;MAAK,CAAC;UAE/D,kBAAiB,EAAE,MAAMA,qCAAiB,SAAS,CAAC;KAEtD;WACK,KAAK;AACZ,WAAQ,MAAM,iCAAiC,IAAI;AACnD,oBAAiB;IAAE,MAAMA,qCAAiB;IAAQ,OAAO;IAAc,CAAC;;;CAI5E,AAAQ,SAAS,OAAuB,gBAAsD;EAC5F,MAAM,QAAQ,KAAK,WAAW,UAAU;AACxC,MAAI,UAAU,aAAa;AAEzB,OAAI,UAAU,YAAY,KAAK,WAAW,gBAAgB,EAAE;IAC1D,MAAM,SAAS,UAAU,WAAW,WAAW;AAC/C,mBAAe;KACb,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,cAAc,OAAO,kBAAkB;KACzD,CAAC;AACF;;AAEF,OAAI,KAAK,eAAe,UAAU,mBAAmB,qBAAqB;AAExE,IADgB,KAAK,eAAe,OAC7B,EAAE,iBAAiB;KACxB,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,iBAAiB;KACnC,CAAC;AACF,YAAQ,KAAK,uDAAuD;;AAEtE,QAAK,eAAe,KAAK;IAAE;IAAO;IAAgB,CAAC;AAEnD;;AAGF,OAAK,WAAW,OAAO,eAAe;;CAGxC,OAAO,OAAuB,gBAAsD;AAClF,OAAK,SAAS,OAAO,eAAe;;CAGtC,MAAM,WAA0B;EAC9B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;EACzE,MAAM,gCAAgB,IAAI,MAAM,4CAA4C;AAC5E,OAAK,MAAM,EAAE,oBAAoB,QAC/B,kBAAiB;GAAE,MAAMA,qCAAiB;GAAQ,OAAO;GAAe,CAAC;;CAI7E,MAAM,aAA4B;;;;;;;;;;;AC3FpC,IAAa,wBAAb,MAAa,sBAAoD;CAC/D,OAAwB,sBAAsB;CAC9C,AAAQ;CACR,AAAQ,iBAGH,EAAE;CAEP,YAAY,YAAoC;AAC9C,OAAK,aAAa;AAClB,OAAK,WAAW,kBAAkB,KAAK,cAAc,CAAC;AACtD,OAAK,WAAW,eAAe,KAAK,aAAa,CAAC;;CAGpD,AAAQ,eAAqB;EAC3B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;AACzE,OAAK,MAAM,EAAE,SAAS,oBAAoB,QACxC,MAAK,WAAW,SAAS,eAAe;;CAI5C,AAAQ,cAAoB;EAC1B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;EACzE,MAAM,wBAAQ,IAAI,MAAM,6CAA6C;AACrE,OAAK,MAAM,EAAE,oBAAoB,QAC/B,kBAAiB;GAAE,MAAME,qCAAiB;GAAQ;GAAO,CAAC;;CAI9D,AAAQ,WACN,aACA,gBACM;AACN,MAAI;GACF,MAAM,aAAaC,sDAAsB,iBAAiB,YAAY;AACtE,OAAI,CAAC,YAAY;AACf,qBAAiB,EAAE,MAAMD,qCAAiB,SAAS,CAAC;AACpD;;AAGF,QAAK,WAAW,KAAK,gBAAgB,aAAY,QAAO;AACtD,QAAI,KAAK;AACP,aAAQ,MAAM,kCAAkC,IAAI,QAAQ;AAC5D,sBAAiB;MAAE,MAAMA,qCAAiB;MAAQ,OAAO;MAAK,CAAC;UAE/D,kBAAiB,EAAE,MAAMA,qCAAiB,SAAS,CAAC;KAEtD;WACK,KAAK;AACZ,WAAQ,MAAM,mCAAmC,IAAI;AACrD,oBAAiB;IAAE,MAAMA,qCAAiB;IAAQ,OAAO;IAAc,CAAC;;;CAI5E,AAAQ,SACN,aACA,gBACM;EACN,MAAM,QAAQ,KAAK,WAAW,UAAU;AACxC,MAAI,UAAU,aAAa;AAEzB,OAAI,UAAU,YAAY,KAAK,WAAW,gBAAgB,EAAE;IAC1D,MAAM,SAAS,UAAU,WAAW,WAAW;AAC/C,mBAAe;KACb,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,cAAc,OAAO,oBAAoB;KAC3D,CAAC;AACF;;AAEF,OAAI,KAAK,eAAe,UAAU,sBAAsB,qBAAqB;AAE3E,IADgB,KAAK,eAAe,OAC7B,EAAE,iBAAiB;KACxB,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,iBAAiB;KACnC,CAAC;AACF,YAAQ,KAAK,yDAAyD;;AAExE,QAAK,eAAe,KAAK;IAAE,SAAS;IAAa;IAAgB,CAAC;AAElE;;AAGF,OAAK,WAAW,aAAa,eAAe;;CAG9C,OAAO,SAA0B,gBAAsD;AACrF,OAAK,SAAS,SAAS,eAAe;;CAGxC,MAAM,WAA0B;EAC9B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;EACzE,MAAM,gCAAgB,IAAI,MAAM,4CAA4C;AAC5E,OAAK,MAAM,EAAE,oBAAoB,QAC/B,kBAAiB;GAAE,MAAMA,qCAAiB;GAAQ,OAAO;GAAe,CAAC;;CAI7E,MAAM,aAA4B;;;;;;;;;;;ACjGpC,IAAa,oBAAb,MAAa,kBAA+C;CAC1D,OAAwB,sBAAsB;CAC9C,AAAQ;CACR,AAAQ,iBAGH,EAAE;CAEP,YAAY,YAAoC;AAC9C,OAAK,aAAa;AAClB,OAAK,WAAW,kBAAkB,KAAK,cAAc,CAAC;AACtD,OAAK,WAAW,eAAe,KAAK,aAAa,CAAC;;CAGpD,AAAQ,eAAqB;EAC3B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;AACzE,OAAK,MAAM,EAAE,MAAM,cAAc,QAC/B,MAAK,SAAS,MAAM,SAAS;;CAIjC,AAAQ,cAAoB;EAC1B,MAAM,UAAU,KAAK,eAAe,OAAO,GAAG,KAAK,eAAe,OAAO;EACzE,MAAM,wBAAQ,IAAI,MAAM,0CAA0C;AAClE,OAAK,MAAM,EAAE,cAAc,QACzB,UAAS;GAAE,MAAME,qCAAiB;GAAQ;GAAO,CAAC;;CAItD,AAAQ,SACN,MACA,gBACM;EACN,MAAM,QAAQ,KAAK,WAAW,UAAU;AACxC,MAAI,UAAU,aAAa;AAEzB,OAAI,UAAU,YAAY,KAAK,WAAW,gBAAgB,EAAE;IAC1D,MAAM,SAAS,UAAU,WAAW,WAAW;AAC/C,mBAAe;KACb,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,cAAc,OAAO,iBAAiB;KACxD,CAAC;AACF;;AAEF,OAAI,KAAK,eAAe,UAAU,kBAAkB,qBAAqB;AAEvE,IADgB,KAAK,eAAe,OAC7B,EAAE,SAAS;KAChB,MAAMA,qCAAiB;KACvB,uBAAO,IAAI,MAAM,yBAAyB;KAC3C,CAAC;AACF,YAAQ,KAAK,sDAAsD;;AAErE,QAAK,eAAe,KAAK;IAAE;IAAM,UAAU;IAAgB,CAAC;AAC5D;;AAGF,MAAI;GACF,MAAM,aAAaC,mDAAmB,iBAAiB,KAAK;AAC5D,OAAI,CAAC,YAAY;AACf,mBAAe,EAAE,MAAMD,qCAAiB,SAAS,CAAC;AAClD;;AAGF,QAAK,WAAW,KAAK,aAAa,aAAY,QAAO;AACnD,QAAI,KAAK;AACP,aAAQ,MAAM,+BAA+B,IAAI,QAAQ;AACzD,oBAAe;MAAE,MAAMA,qCAAiB;MAAQ,OAAO;MAAK,CAAC;UAE7D,gBAAe,EAAE,MAAMA,qCAAiB,SAAS,CAAC;KAEpD;WACK,KAAK;AACZ,WAAQ,MAAM,gCAAgC,IAAI;AAClD,kBAAe;IAAE,MAAMA,qCAAiB;IAAQ,OAAO;IAAc,CAAC;;;CAI1E,OAAO,MAA2B,gBAAsD;AACtF,OAAK,SAAS,MAAM,eAAe;;CAGrC,MAAM,aAA4B;CAElC,MAAM,WAA0B;AAC9B,OAAK,MAAM,EAAE,cAAc,KAAK,eAC9B,UAAS;GAAE,MAAMA,qCAAiB;GAAQ,uBAAO,IAAI,MAAM,oBAAoB;GAAE,CAAC;AAEpF,OAAK,iBAAiB,EAAE;;;;;;;;;;;;AC5F5B,SAAgB,iBAAqC;CACnD,MAAM,OAAOE,yBAAM,eAAe;AAClC,KAAI,MAAM;EACR,MAAM,cAAc,KAAK,aAAa;AACtC,MAAI,YAAY,WAAW,YAAY,YAAY,mCACjD,QAAO,YAAY;;;;;;AASzB,SAAgB,gBAAoC;CAClD,MAAM,OAAOA,yBAAM,eAAe;AAClC,KAAI,MAAM;EACR,MAAM,cAAc,KAAK,aAAa;AACtC,MAAI,YAAY,UAAU,YAAY,WAAW,mBAC/C,QAAO,YAAY;;;;;;AASzB,SAAgB,oBAAwC;CACtD,MAAM,UAAkC,EAAE;AAC1C,gCAAY,OAAOC,2BAAQ,QAAQ,EAAE,QAAQ;AAC7C,QAAO,QAAQ;;;;;;;AAQjB,SAAgB,mBAAmB,aAA8B;CAC/D,MAAM,UAAkC,EAAE,aAAa;AACvD,QAAOC,+BAAY,QAAQD,2BAAQ,QAAQ,EAAE,QAAQ;;;;;AAMvD,SAAgB,gBAAoC;CAClD,MAAM,UAAkC,EAAE;AAC1C,gCAAY,OAAOA,2BAAQ,QAAQ,EAAE,QAAQ;AAC7C,QAAO,QAAQ;;;;;;;AAQjB,SAAgB,eAAe,SAA0B;CACvD,MAAM,UAAkC,EAAE,SAAS;AACnD,QAAOC,+BAAY,QAAQD,2BAAQ,QAAQ,EAAE,QAAQ;;;;;;;;AASvD,SAAgB,eAAe,aAAsB,SAA2B;CAC9E,MAAM,UAAkC,EAAE;AAC1C,KAAI,YACF,SAAQ,cAAc;AAExB,KAAI,QACF,SAAQ,UAAU;AAEpB,QAAOC,+BAAY,QAAQD,2BAAQ,QAAQ,EAAE,QAAQ;;;;;;;AAQvD,SAAgB,gBAAgB,KAAiC;AAE/D,QADYC,+BAAY,WAAWD,2BAAQ,QAAQ,CACzC,EAAE,SAAS,IAAI,EAAE;;;;;;;;AAS7B,SAAgB,gBAAgB,KAAa,OAAwB;CACnE,IAAI,MAAMC,+BAAY,WAAWD,2BAAQ,QAAQ,CAAC,IAAIC,+BAAY,eAAe;AACjF,OAAM,IAAI,SAAS,KAAK,EAAE,OAAO,CAAC;AAClC,QAAOA,+BAAY,WAAWD,2BAAQ,QAAQ,EAAE,IAAI;;;;;;;AAQtD,SAAgB,mBAAmB,KAAsB;CACvD,MAAM,MAAMC,+BAAY,WAAWD,2BAAQ,QAAQ,CAAC;AACpD,KAAI,CAAC,IACH,QAAOA,2BAAQ,QAAQ;CAEzB,MAAM,SAAS,IAAI,YAAY,IAAI;AACnC,QAAOC,+BAAY,WAAWD,2BAAQ,QAAQ,EAAE,OAAO;;;;;AAMzD,SAAgB,gBAAwC;CACtD,MAAM,MAAMC,+BAAY,WAAWD,2BAAQ,QAAQ,CAAC;AACpD,KAAI,CAAC,IACH,QAAO,EAAE;CAEX,MAAM,UAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,KAAK,UAAU,IAAI,eAAe,CAC5C,SAAQ,OAAO,MAAM;AAEvB,QAAO;;;;;;;;;;;;AC/HT,MAAM,cAAc,IAAI,aAAa;AAErC,SAAS,gBAAgB,MAAmC;AAC1D,KAAI,QAAQ,KAAM,QAAO;AACzB,KAAI,OAAO,SAAS,SAAU,QAAO,YAAY,OAAO,KAAK,CAAC;AAC9D,KAAI,gBAAgB,YAAa,QAAO,KAAK;AAC7C,KAAI,YAAY,OAAO,KAAK,CAAE,QAAO,KAAK;AAC1C,KAAI,gBAAgB,KAAM,QAAO,KAAK;AACtC,KAAI,gBAAgB,gBAAiB,QAAO,IAAI,aAAa,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC;;AAIxF,MAAM,uBAAuB,CAAC,gBAAgB,SAAS;AACvD,MAAM,wBAAwB,CAAC,eAAe;AAE9C,IAAI,gBAAgD;;;;;;;AAQpD,MAAM,6BAAuC,QAAQ,IAAI,0BAA0B,IAChF,MAAM,IAAI,CACV,KAAI,MAAK,EAAE,MAAM,CAAC,CAClB,OAAO,QAAQ;AAElB,SAAS,qBAAqB,KAAsB;AAClD,QAAO,0BAA0B,MAAK,YAAW,IAAI,SAAS,QAAQ,CAAC;;;;;;;AAQzE,SAAgB,iBAAiB,QAAsB;AACrD,KAAI,cAAe;AAEnB,iBAAgB,WAAW;CAC3B,MAAM,gBAAgB;AAEtB,YAAW,QAAQ,OACjB,OACA,SACsB;EACtB,MAAM,MAAM,iBAAiB,UAAU,MAAM,MAAM,OAAO,MAAM;AAGhE,MAAI,qBAAqB,IAAI,CAC3B,QAAO,cAAc,OAAO,KAAK;EAGnC,MAAM,UAAU,MAAM,WAAW,iBAAiB,UAAU,MAAM,SAAS,QAAQ,aAAa;EAEhG,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;AACJ,MAAI;GACF,MAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,UAAO,OAAO;AACd,YAAS,OAAO,SAAS,QAAQ,KAAK,GAAG;AACzC,UAAO,OAAO;AACd,UAAO,OAAO,OAAO,SAAS,OAAO,MAAM,GAAG,GAAG;AACjD,WAAQ,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE,GAAG;UAC3C;EAIR,MAAM,iBAAkD;GACtD,uBAAuB;GACvB,YAAY;GACb;AACD,MAAI,KAAM,gBAAe,oBAAoB;AAC7C,MAAI,QAAQ;AACV,kBAAe,gBAAgB;AAC/B,kBAAe,2BAA2B;;AAE5C,MAAI,KAAM,gBAAe,cAAc;AACvC,MAAI,KAAM,gBAAe,iBAAiB;AAC1C,MAAI,MAAO,gBAAe,eAAe;EAEzC,MAAM,WAAW,OAAO,GAAG,OAAO,GAAG,SAAS;AAE9C,SAAO,OAAO,gBACZ,UACA;GAAE,MAAME,4BAAS;GAAQ,YAAY;GAAgB,EACrDC,2BAAQ,QAAQ,EAChB,OAAM,SAAQ;AACZ,OAAI;IACF,MAAM,UAAkC,EAAE;AAC1C,mCAAY,OAAOA,2BAAQ,QAAQ,EAAE,QAAQ;IAE7C,MAAM,UAAU,IAAI,QAClB,MAAM,YAAY,iBAAiB,UAAU,MAAM,UAAU,QAC9D;AACD,SAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,SAAQ,IAAI,KAAK,MAAM;AAGzB,SAAK,MAAM,QAAQ,sBAAsB;KACvC,MAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,SAAI,UAAU,KACZ,MAAK,aAAa,uBAAuB,QAAQ,MAAM;;IAK3D,MAAM,kBAAkB,gBADJ,MAAM,SAAS,iBAAiB,UAAU,MAAM,OAAO,QACvB;AACpD,QAAI,oBAAoB,OACtB,MAAK,aAAa,0BAA0B,gBAAgB;IAG9D,MAAM,WAAW,MAAM,cAAc,OAAO;KAAE,GAAG;KAAM;KAAS,CAAC;AAEjE,SAAK,aAAa,6BAA6B,SAAS,OAAO;IAE/D,MAAM,gBAAgB,SAAS,QAAQ,IAAI,iBAAiB;AAC5D,QAAI,kBAAkB,MAAM;KAC1B,MAAM,OAAO,SAAS,eAAe,GAAG;AACxC,SAAI,CAAC,OAAO,MAAM,KAAK,CACrB,MAAK,aAAa,2BAA2B,KAAK;;AAItD,SAAK,MAAM,QAAQ,uBAAuB;KACxC,MAAM,QAAQ,SAAS,QAAQ,IAAI,KAAK;AACxC,SAAI,UAAU,KACZ,MAAK,aAAa,wBAAwB,QAAQ,MAAM;;AAI5D,QAAI,SAAS,UAAU,KAAK;AAC1B,UAAK,aAAa,cAAc,OAAO,SAAS,OAAO,CAAC;AACxD,UAAK,UAAU,EAAE,MAAMC,kCAAe,OAAO,CAAC;UAE9C,MAAK,UAAU,EAAE,MAAMA,kCAAe,IAAI,CAAC;AAG7C,WAAO;YACA,OAAO;AACd,SAAK,aAAa,cAAe,MAAgB,QAAQ,QAAQ;AACjE,SAAK,UAAU;KAAE,MAAMA,kCAAe;KAAO,SAAU,MAAgB;KAAS,CAAC;AACjF,SAAK,gBAAgB,MAAe;AACpC,UAAM;aACE;AACR,SAAK,KAAK;;IAGf;;;;;;AAOL,SAAgB,qBAA2B;AACzC,KAAI,eAAe;AACjB,aAAW,QAAQ;AACnB,kBAAgB;;;;;;;;;;;;;ACrKpB,SAAgB,eAAe,OAA2B,UAAkB,GAAuB;AACjG,KAAI,UAAU,UAAa,MAAM,MAAM,KAAK,GAAI,QAAO;CACvD,MAAM,SAAS,OAAO,MAAM;AAC5B,KAAI,CAAC,OAAO,SAAS,OAAO,IAAI,SAAS,QAAS,QAAO;AACzD,QAAO;;;;;AAMT,SAAgB,gBACd,OACA,UAAkB,GACE;CACpB,MAAM,SAAS,eAAe,OAAO,QAAQ;AAC7C,KAAI,WAAW,UAAa,CAAC,OAAO,UAAU,OAAO,CAAE,QAAO;AAC9D,QAAO;;;;;;;;;;;;AAaT,SAAgB,uBACd,aACA,UACA,cACQ;AACR,QAAO,eAAe,eAAe,UAAU,EAAE,IAAI;;;;;;;ACpCvD,SAAgB,yBAAkC;CAChD,MAAM,OAAOC,yBAAM,eAAe;AAClC,QAAO,OAAO,KAAK,aAAa,GAAG;;;;;;;;AASrC,SAAgB,wBAAwB,KAAa,OAA6B;CAChF,MAAM,OAAOA,yBAAM,eAAe;AAClC,KAAI,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAE;AAClC,MAAK,aAAa,KAAK,MAAM;;;;;;;AAQ/B,SAAgB,oBAAoB,SAAuB;CACzD,MAAM,OAAOA,yBAAM,eAAe;AAClC,KAAI,CAAC,KAAM;AACX,MAAK,UAAU;EAAE,MAAMC,kCAAe;EAAO;EAAS,CAAC;;;;;;;;AASzD,SAAgB,gBAAgB,MAAc,OAA0B;CACtE,MAAM,OAAOD,yBAAM,eAAe;AAClC,KAAI,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAE;AAClC,MAAK,SAAS,MAAM,MAAM;;;;;;ACxC5B,MAAa,uBAAuB;AACpC,MAAM,oBAAoB;;;;;AAM1B,SAAgB,yBAAwC;CACtD,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,QAAQ,OAAW,QAAO;CAC9B,MAAM,UAAU,IAAI,MAAM;AAC1B,KAAI,YAAY,MAAM,QAAQ,aAAa,KAAK,YAAa,QAAO;AAGpE,KAAI,CAAC,QAAQ,KAAK,QAAQ,CAAE,QAAO;CACnC,MAAM,SAAS,OAAO,QAAQ;AAC9B,KAAI,UAAU,EAAG,QAAO;AACxB,QAAO;;AAGT,MAAM,sBAAsB;CAC1B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,eAAe,KAAsB;CAC5C,MAAM,QAAQ,IAAI,aAAa;AAC/B,KAAI,oBAAoB,MAAM,aAAa,MAAM,SAAS,SAAS,CAAC,CAAE,QAAO;AAE7E,QAAO,UAAU,WAAW,MAAM,SAAS,SAAS,IAAI,MAAM,SAAS,SAAS;;;;;;;AAQlF,SAAgB,OAAO,OAAyB;AAC9C,KAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,MAAM,IAAI,OAAO;AAClD,KAAI,OAAO,UAAU,UAAU;EAC7B,MAAM,MAA+B,EAAE;AACvC,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,MAAiC,CACnE,KAAI,KAAK,eAAe,EAAE,GAAG,uBAAuB,OAAO,EAAE;AAE/D,SAAO;;AAET,QAAO;;;;;;;;AAST,SAAgB,kBACd,OACA,WAA0B,MACY;CACtC,MAAM,WAAW,OAAO,MAAM;CAC9B,IAAI;AACJ,KAAI;AACF,eAAa,KAAK,UAAU,SAAS,IAAI;SACnC;AACN,eAAa;;AAGf,KAAI,aAAa,QAAQ,aAAa,UAAa,YAAY,EAC7D,QAAO;EAAE,MAAM;EAAY,WAAW;EAAO;AAI/C,KADgB,OAAO,WAAW,YAAY,OACnC,IAAI,SACb,QAAO;EAAE,MAAM;EAAY,WAAW;EAAO;CAG/C,MAAM,YAAY,OAAO,WAAW,mBAAmB,OAAO;AAG9D,KAAI,YAAY,UACd,QAAO;EAAE,MAAM,kBAAkB,MAAM,GAAG,SAAS;EAAE,WAAW;EAAM;CAGxE,MAAM,MAAM,WAAW;CACvB,MAAM,MAAM,OAAO,KAAK,YAAY,OAAO;CAC3C,IAAI,MAAM,KAAK,IAAI,KAAK,IAAI,OAAO;AAEnC,QAAO,MAAM,MAAM,IAAI,OAAO,SAAU,IACtC,QAAO;AAGT,QAAO;EAAE,MADS,IAAI,SAAS,GAAG,IAAI,CAAC,SAAS,OAAO,GAAG;EAChC,WAAW;EAAM;;;;;;;;;;;;;;;;;ACrC7C,SAAS,eAAe,MAAsB;CAC5C,MAAM,MAAM,IAAI,IAAI,KAAK;CACzB,MAAM,OAAO,IAAI,SAAS,QAAQ,QAAQ,GAAG;AAC7C,KAAI,WAAW,KAAK,SAAS,QAAQ,GAAG,OAAO,GAAG,KAAK;AACvD,QAAO,IAAI,UAAU;;AAIvB,IAAI,mBAAkD;AACtD,IAAI,iBAA4C;AAChD,IAAI,gBAAsC;AAC1C,IAAI,iBAAwC;AAC5C,IAAI,SAAwB;AAC5B,IAAI,QAAsB;AAC1B,IAAI,SAAwB;AAC5B,IAAI,cAAsB;;;;;;;AAQ1B,SAAgB,SAAS,SAAqB,EAAE,EAAQ;AAGtD,KAAI,EAFY,OAAO,WAAW,aAAa,QAAQ,IAAI,cAAc,oBAAoB,QAAQ,GAEvF;AACZ,UAAQ,MACN,yGACD;AACD;;AAIF,eAAc,OAAO,eAAe,QAAQ,IAAI,qBAAqB,oBAAoB;CACzF,MAAM,iBAAiB,OAAO,kBAAkB,QAAQ,IAAI,mBAAmB,oBAAoB;CACnG,MAAM,mBAAmB,OAAO,oBAAoB,QAAQ,IAAI;CAChE,MAAM,oBAAoB,OAAO,qBAAqB,QAAQ,IAAI,oDAAmC;CACrG,MAAM,cAAc,OAAO,eAAe,QAAQ,IAAI,WAAW,oBAAoB;CAGrF,MAAM,qBAA6C;GAChDE,wDAAoB;GACpB,uBAAuB;GACvB,2BAA2B;EAC7B;AACD,KAAI,iBACF,oBAAmB,0BAA0B;CAE/C,MAAM,gEAAkC,mBAAmB;AAM3D,oBAAmB,IAAI,uBACrB,eAAe,YAAY,EAC3B,OAAO,oBACP,OAAO,gBACR;CAKD,MAAM,eAAe,IAAI,mBAAmB,iBAAiB;CAQ7D,MAAM,4BAA4B,uBAChC,OAAO,sBACP,QAAQ,IAAI,8BACZ,oBAAoB,qBACrB;AACD,kBAAiB,IAAIC,iDAAmB;EACtC;EACA,gBAAgB,CACd,IAAI,sBAAsB,EAC1B,IAAIC,iDAAmB,cAAc,EAAE,sBAAsB,2BAA2B,CAAC,CAC1F;EACF,CAAC;AAGF,gCAAY,oBACV,IAAIC,wCAAoB,EACtB,aAAa,CAAC,IAAIC,+CAA2B,EAAE,IAAIC,0CAAsB,CAAC,EAC3E,CAAC,CACH;AAED,gBAAe,UAAU;AACzB,UAASC,yBAAM,UAAU,YAAY;AAErC,SAAQ,MAAM,qCAAqC,YAAY,YAAY,cAAc;AAMzF,KAFE,OAAO,kBAAkB,aAAa,QAAQ,IAAI,sBAAsB,oBAAoB,eAAe,EAEzF;EAClB,MAAM,kBAAkB,IAAI,sBAAsB,iBAAiB;EACnE,MAAM,mBAAmB,OAAO,2BAA2B,oBAAoB;AAO/E,kBAAgB,IAAIC,yCAAc;GAChC;GACA,SAAS,CAAC,IAPaC,yDAA8B;IACrD,UAAU;IACV,sBAAsB;IACvB,CAIuB,CAAC;GACxB,CAAC;AAEF,6BAAQ,uBAAuB,cAAc;AAC7C,UAAQ,cAAc,SAAS,YAAY;AAE3C,UAAQ,MAAM,wCAAwC,iBAAiB,IAAI;;CAI7E,MAAM,mBAAmB,CAAC,GAAI,OAAO,oBAAoB,EAAE,CAAE;AAC7D,KAAI,iBAAiB,SAAS,GAAG;AAC/B,+DAAyB;GACvB;GACA;GACA,eAAe,iBAAiB;GACjC,CAAC;AACF,UAAQ,MAAM,uCAAuC,iBAAiB,OAAO,QAAQ;;AAMvF,KAFqB,OAAO,+BAA+B,oBAAoB,6BAE7D;AAChB,mBAAiB,OAAO;AACxB,UAAQ,MAAM,8CAA8C;;CAI9D,MAAM,cAAc,IAAI,kBAAkB,iBAAiB;CAC3D,MAAM,2BAA2B,uBAC/B,OAAO,qBACP,QAAQ,IAAI,6BACZ,oBAAoB,oBACrB;CACD,MAAM,yBACJ,OAAO,iBAAiB,gBAAgB,QAAQ,IAAI,sBAAsB,EAAE,IAAI,oBAAoB;AAEtG,kBAAiB,IAAIC,uCAAe;EAClC;EACA,YAAY,CACV,IAAIC,gDAAwB;GAC1B,UAAU;GACV,sBAAsB;GACtB,oBAAoB;GACrB,CAAC,CACH;EACF,CAAC;AACF,UAAS,eAAe,UAAU,YAAY;AAE9C,SAAQ,MAAM,kCAAkC,yBAAyB,YAAY,yBAAyB;;;;;;AAOhH,eAAsB,eAA8B;AAElD,mBAAkB,eAAe;CAKjC,MAAM,UAAU,MAAwB,EAAE,YAAY,GAAG;AAEzD,KAAI,gBAAgB;AAClB,QAAM,OAAO,eAAe,YAAY,CAAC;AACzC,QAAM,OAAO,eAAe,UAAU,CAAC;AACvC,mBAAiB;;AAGnB,KAAI,eAAe;AACjB,QAAM,OAAO,cAAc,YAAY,CAAC;AACxC,QAAM,OAAO,cAAc,UAAU,CAAC;AACtC,kBAAgB;;AAGlB,KAAI,gBAAgB;AAClB,QAAM,OAAO,eAAe,YAAY,CAAC;AACzC,QAAM,OAAO,eAAe,UAAU,CAAC;AACvC,mBAAiB;;AAGnB,KAAI,kBAAkB;AACpB,QAAM,iBAAiB,UAAU;AACjC,qBAAmB;;AAGrB,qBAAoB;AAEpB,UAAS;AACT,SAAQ;AACR,UAAS;;;;;;;;;AAUX,eAAsB,YAA2B;AAC/C,OAAM,QAAQ,IACZ;EACE,gBAAgB,YAAY;EAC5B,eAAe,YAAY;EAC3B,gBAAgB,YAAY;EAC7B,CAAC,OAAO,QAAQ,CAClB;;;;;AAMH,SAAgB,YAA2B;AACzC,QAAO;;;;;AAMT,SAAgB,WAAyB;AACvC,QAAO;;;;;AAMT,SAAgB,YAA2B;AACzC,QAAO;;;;;;;;;AAUT,eAAsB,SACpB,MACA,SACA,IACY;AACZ,KAAI,CAAC,QAAQ;EAGX,MAAM,WAAiB;GACrB,oBAAoB;IAAE,SAAS;IAAI,QAAQ;IAAI,YAAY;IAAG;GAC9D,oBAAoB;GACpB,qBAAqB;GACrB,gBAAgB;GAChB,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,WAAW;GACX,mBAAmB;GACnB,uBAAuB;GACvB,gBAAgB;GACjB;AACD,SAAO,GAAG,SAAS;;CAGrB,MAAM,gBAAgB,QAAQ,cAAc,mBAAmB,QAAQ,YAAY,GAAGC,2BAAQ,QAAQ;AAEtG,QAAO,OAAO,gBAAgB,MAAM,EAAE,MAAM,QAAQ,QAAQC,4BAAS,UAAU,EAAE,eAAe,OAAO,SAAS;AAC9G,MAAI;GACF,MAAM,SAAS,MAAM,GAAG,KAAK;AAC7B,QAAK,UAAU,EAAE,MAAMC,kCAAe,IAAI,CAAC;AAC3C,UAAO;WACA,OAAO;AACd,QAAK,UAAU;IAAE,MAAMA,kCAAe;IAAO,SAAU,MAAgB;IAAS,CAAC;AACjF,QAAK,gBAAgB,MAAe;AACpC,SAAM;YACE;AACR,QAAK,KAAK;;GAEZ"}