{"version":3,"file":"diagnostics.cjs","names":["safeRequire","SeverityNumber","safeRequire","logs","trace","ATTR_HTTP_REQUEST_METHOD","ATTR_URL_PATH","ATTR_URL_SCHEME","ATTR_NETWORK_PROTOCOL_VERSION","ATTR_USER_AGENT_ORIGINAL","ATTR_SERVER_ADDRESS","ATTR_SERVER_PORT","propagation","otelContext","defaultTextMapGetter","SpanKind","ATTR_URL_FULL","defaultTextMapSetter","SpanStatusCode","ATTR_HTTP_RESPONSE_STATUS_CODE"],"sources":["../src/diagnostics/channel.ts","../src/diagnostics/console.ts","../src/diagnostics/http.ts"],"sourcesContent":["/**\n * Edge-safe wrappers over Node's `diagnostics_channel`.\n *\n * The module is loaded lazily through {@link safeRequire} — never a static\n * `node:` import — so merely importing this file is side-effect-free and bundles\n * cleanly for browser/edge targets, where every subscribe call degrades to a\n * no-op (returning an unsubscribe that does nothing). This is the shared\n * primitive behind autotel's diagnostics-channel integrations (console capture,\n * HTTP spans) and any app- or library-specific channel you want to bridge into\n * a span/event.\n *\n * `diagnostics_channel.subscribe` (Node 18.7+) and `tracingChannel` (Node 19+)\n * are used; autotel targets Node 22+, but on any runtime that lacks them the\n * loader returns `undefined` and the helpers no-op.\n */\n\nimport { safeRequire } from '../node-require.js';\n\ntype DiagnosticsChannelModule = typeof import('node:diagnostics_channel');\n\nlet cached: DiagnosticsChannelModule | null | undefined;\n\nfunction loadDiagnosticsChannel(): DiagnosticsChannelModule | undefined {\n  if (cached !== undefined) return cached ?? undefined;\n  cached =\n    safeRequire<DiagnosticsChannelModule>('node:diagnostics_channel') ?? null;\n  return cached ?? undefined;\n}\n\n/** Whether Node's `diagnostics_channel` is available in this runtime. */\nexport function diagnosticsChannelAvailable(): boolean {\n  return loadDiagnosticsChannel() !== undefined;\n}\n\n/** Handler for a plain named channel. */\nexport type ChannelMessageHandler = (\n  message: unknown,\n  name: string | symbol,\n) => void;\n\n/**\n * Subscribe to a named diagnostics channel. Returns an idempotent unsubscribe\n * function; a no-op (that still returns a disposer) on unsupported runtimes.\n */\nexport function subscribeChannel(\n  name: string,\n  handler: ChannelMessageHandler,\n): () => void {\n  const dc = loadDiagnosticsChannel();\n  if (!dc?.subscribe) return () => {};\n  dc.subscribe(name, handler);\n  let active = true;\n  return () => {\n    if (!active) return;\n    active = false;\n    dc.unsubscribe?.(name, handler);\n  };\n}\n\n/** Subscriber set for a {@link https://nodejs.org/api/diagnostics_channel.html#class-tracingchannel TracingChannel}. */\nexport interface TracingChannelHandlers {\n  start?(message: unknown): void;\n  end?(message: unknown): void;\n  asyncStart?(message: unknown): void;\n  asyncEnd?(message: unknown): void;\n  error?(message: unknown): void;\n}\n\n/**\n * Subscribe to a `tracingChannel` (the `tracing:${name}:{start,end,…}` set).\n * Returns an idempotent unsubscribe; a no-op on runtimes without\n * `tracingChannel` support.\n */\nexport function subscribeTracingChannel(\n  name: string,\n  handlers: TracingChannelHandlers,\n): () => void {\n  const dc = loadDiagnosticsChannel();\n  const channel = dc?.tracingChannel?.(name);\n  if (!channel) return () => {};\n  // Node's typings want all five handlers; we pass the subset provided.\n  channel.subscribe(handlers as Parameters<typeof channel.subscribe>[0]);\n  let active = true;\n  return () => {\n    if (!active) return;\n    active = false;\n    channel.unsubscribe(handlers as Parameters<typeof channel.unsubscribe>[0]);\n  };\n}\n","/**\n * Capture `console.*` calls as wide events — without monkey-patching `console`.\n *\n * Node publishes every `console.log` / `info` / `debug` / `warn` / `error` call\n * on a built-in diagnostics channel. {@link captureConsole} subscribes to those\n * channels and turns each call into an OpenTelemetry **log record** (correlated\n * to the active span via trace context by the logs SDK) and/or a **span event**\n * on the active span. Nothing patches the global `console`, so there is no\n * load-order fragility and no interference with other tooling.\n *\n * Opt-in. Call once after `init()` and keep the returned disposer to stop:\n *\n * ```ts\n * import { captureConsole } from 'autotel/diagnostics';\n *\n * const stop = captureConsole();      // every console.* → correlated log record\n * // …later: stop();\n * ```\n *\n * The built-in `console.*` channels are a Stability-1 (experimental) Node API;\n * this module degrades to a no-op where they are unavailable.\n */\n\nimport { trace, type Attributes } from '@opentelemetry/api';\nimport { logs, SeverityNumber, type Logger } from '@opentelemetry/api-logs';\nimport { safeRequire } from '../node-require.js';\nimport { subscribeChannel } from './channel.js';\n\n/** Console methods that publish a diagnostics channel. */\nexport type ConsoleLevel = 'log' | 'info' | 'debug' | 'warn' | 'error';\n\nconst ALL_LEVELS: readonly ConsoleLevel[] = [\n  'log',\n  'info',\n  'debug',\n  'warn',\n  'error',\n];\n\nconst SEVERITY: Record<ConsoleLevel, SeverityNumber> = {\n  debug: SeverityNumber.DEBUG,\n  log: SeverityNumber.INFO,\n  info: SeverityNumber.INFO,\n  warn: SeverityNumber.WARN,\n  error: SeverityNumber.ERROR,\n};\n\nexport interface CaptureConsoleOptions {\n  /** Which console methods to capture. Defaults to all five. */\n  levels?: readonly ConsoleLevel[];\n  /**\n   * Where to record captured output:\n   * - `'log'` (default): emit an OpenTelemetry log record;\n   * - `'span-event'`: add an event to the active span (nothing if no active span);\n   * - `'both'`.\n   */\n  target?: 'log' | 'span-event' | 'both';\n  /** Logger name for emitted records. Defaults to `'autotel.console'`. */\n  loggerName?: string;\n  /** Static attributes merged onto every captured record/event. */\n  attributes?: Attributes;\n}\n\ntype ConsoleMessage = { args?: unknown[] };\n\nconst nodeUtil = safeRequire<typeof import('node:util')>('node:util');\n\n/** Format console arguments the way `console` itself would (printf + inspect). */\nfunction formatArgs(args: unknown[]): string {\n  if (nodeUtil?.format) return nodeUtil.format(...args);\n  return args\n    .map((a) => (typeof a === 'string' ? a : safeStringify(a)))\n    .join(' ');\n}\n\nfunction safeStringify(value: unknown): string {\n  try {\n    return JSON.stringify(value) ?? String(value);\n  } catch {\n    return String(value);\n  }\n}\n\n/**\n * Start capturing `console.*` calls as wide events. Returns a disposer that\n * stops capture. Safe to call on runtimes without the console channels (no-op).\n */\nexport function captureConsole(\n  options: CaptureConsoleOptions = {},\n): () => void {\n  const levels = options.levels ?? ALL_LEVELS;\n  const target = options.target ?? 'log';\n  const toLog = target === 'log' || target === 'both';\n  const toSpan = target === 'span-event' || target === 'both';\n  const logger: Logger = logs.getLogger(\n    options.loggerName ?? 'autotel.console',\n  );\n\n  // Guard against re-entrancy: if recording a captured call itself triggers a\n  // `console.*` (e.g. an exporter logging a warning), don't capture that.\n  let recording = false;\n\n  const disposers = levels.map((level) =>\n    subscribeChannel(`console.${level}`, (message) => {\n      if (recording) return;\n      const args = (message as ConsoleMessage)?.args ?? [];\n      const body = formatArgs(args as unknown[]);\n      recording = true;\n      try {\n        const attributes: Attributes = {\n          'log.source': 'console',\n          'log.method': level,\n          ...options.attributes,\n        };\n        if (toLog) {\n          logger.emit({\n            severityNumber: SEVERITY[level],\n            severityText: level.toUpperCase(),\n            body,\n            attributes,\n          });\n        }\n        if (toSpan) {\n          trace\n            .getActiveSpan()\n            ?.addEvent('log', { 'log.message': body, ...attributes });\n        }\n      } finally {\n        recording = false;\n      }\n    }),\n  );\n\n  let active = true;\n  return () => {\n    if (!active) return;\n    active = false;\n    for (const dispose of disposers) dispose();\n  };\n}\n","/**\n * Lightweight HTTP spans via Node's built-in `diagnostics_channel` — no\n * monkey-patching, no `import-in-the-middle`.\n *\n * Node publishes `http.server.request.start` / `http.server.response.finish`\n * and `http.client.request.start` / `http.client.response.finish` /\n * `http.client.request.error`. {@link instrumentHttp} subscribes to those and\n * emits a `SERVER` span per inbound request (parented to an incoming W3C\n * `traceparent`) and a `CLIENT` span per outbound request (whose context it\n * injects into the outgoing headers for downstream propagation).\n *\n * ```ts\n * import { instrumentHttp } from 'autotel/diagnostics';\n *\n * const stop = instrumentHttp();\n * ```\n *\n * Scope & limitation. This is an opt-in, low-overhead alternative to\n * `@opentelemetry/instrumentation-http` for HTTP span coverage + W3C\n * propagation. Client-side propagation works (the `traceparent` is injected on\n * the `ClientRequest` object directly). What it does **not** do is establish an\n * *ambient* OpenTelemetry context for the duration of a server request handler,\n * so application spans created inside a handler will not become children of the\n * `SERVER` span.\n *\n * This is structural, not a \"wait for a newer Node\" gap. Node publishes the\n * `http.*` channels with a plain `channel.publish()` — not `runStores` /\n * `tracingChannel` — so a subscriber has no scope to bind a store to. The only\n * ways to get handler nesting both defeat the purpose of using a channel:\n *   1. `AsyncLocalStorage.enterWith()` in the start handler — no scoped exit, so\n *      context leaks across requests sharing an event-loop tick / keep-alive\n *      connection and misattributes spans. Strictly worse than no nesting.\n *   2. Patching `http.Server.prototype.emit` to wrap the `'request'` listener in\n *      `context.with()` — monkey-patching, i.e. reimplementing\n *      `@opentelemetry/instrumentation-http`.\n * If you need handler nesting, use `@opentelemetry/instrumentation-http`.\n *\n * The `http.*` channels are a Stability-1 (experimental) Node API; this module\n * degrades to a no-op where they are unavailable.\n */\n\nimport type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http';\nimport {\n  context as otelContext,\n  defaultTextMapGetter,\n  defaultTextMapSetter,\n  propagation,\n  SpanKind,\n  SpanStatusCode,\n  trace,\n  type Attributes,\n  type Span,\n  type Tracer,\n} from '@opentelemetry/api';\nimport {\n  ATTR_HTTP_REQUEST_METHOD,\n  ATTR_HTTP_RESPONSE_STATUS_CODE,\n  ATTR_NETWORK_PROTOCOL_VERSION,\n  ATTR_SERVER_ADDRESS,\n  ATTR_SERVER_PORT,\n  ATTR_URL_FULL,\n  ATTR_URL_PATH,\n  ATTR_URL_SCHEME,\n  ATTR_USER_AGENT_ORIGINAL,\n} from '@opentelemetry/semantic-conventions';\nimport { subscribeChannel } from './channel.js';\n\nexport interface InstrumentHttpOptions {\n  /** Instrument inbound (server) requests. Default `true`. */\n  server?: boolean;\n  /** Instrument outbound (client) requests. Default `true`. */\n  client?: boolean;\n  /** Tracer to use. Defaults to `trace.getTracer('autotel.http-diagnostics')`. */\n  tracer?: Tracer;\n}\n\ninterface ServerStartMessage {\n  request?: IncomingMessage;\n  response?: ServerResponse;\n}\ninterface ServerFinishMessage {\n  request?: IncomingMessage;\n  response?: ServerResponse;\n}\ninterface ClientStartMessage {\n  request?: ClientRequest;\n}\ninterface ClientFinishMessage {\n  request?: ClientRequest;\n  response?: IncomingMessage;\n}\ninterface ClientErrorMessage {\n  request?: ClientRequest;\n  error?: unknown;\n}\n\nconst SERVER_SPANS = new WeakMap<object, Span>();\nconst CLIENT_SPANS = new WeakMap<object, Span>();\n\nfunction firstHeader(value: string | string[] | undefined): string | undefined {\n  return Array.isArray(value) ? value[0] : value;\n}\n\nfunction splitHostPort(host: string | undefined): {\n  address?: string;\n  port?: number;\n} {\n  if (!host) return {};\n  const idx = host.lastIndexOf(':');\n  if (idx === -1) return { address: host };\n  const port = Number(host.slice(idx + 1));\n  return {\n    address: host.slice(0, idx),\n    port: Number.isFinite(port) ? port : undefined,\n  };\n}\n\n/**\n * Start emitting HTTP server/client spans from Node's HTTP diagnostics\n * channels. Returns a disposer; a no-op on runtimes without the channels.\n */\nexport function instrumentHttp(\n  options: InstrumentHttpOptions = {},\n): () => void {\n  const tracer = options.tracer ?? trace.getTracer('autotel.http-diagnostics');\n  const disposers: Array<() => void> = [];\n\n  if (options.server !== false) {\n    disposers.push(\n      subscribeChannel('http.server.request.start', (message) => {\n        const request = (message as ServerStartMessage)?.request;\n        if (!request) return;\n        const method = request.method ?? 'HTTP';\n        const host = firstHeader(request.headers.host);\n        const { address, port } = splitHostPort(host);\n        const path = (request.url ?? '/').split('?', 1)[0];\n        const attributes: Attributes = {\n          [ATTR_HTTP_REQUEST_METHOD]: method,\n          [ATTR_URL_PATH]: path,\n          [ATTR_URL_SCHEME]: 'http',\n          [ATTR_NETWORK_PROTOCOL_VERSION]: request.httpVersion,\n          [ATTR_USER_AGENT_ORIGINAL]: firstHeader(\n            request.headers['user-agent'],\n          ),\n          [ATTR_SERVER_ADDRESS]: address,\n          [ATTR_SERVER_PORT]: port,\n        };\n        const parent = propagation.extract(\n          otelContext.active(),\n          request.headers,\n          defaultTextMapGetter,\n        );\n        const span = tracer.startSpan(\n          method,\n          { kind: SpanKind.SERVER, attributes },\n          parent,\n        );\n        SERVER_SPANS.set(request, span);\n      }),\n      subscribeChannel('http.server.response.finish', (message) => {\n        const { request, response } = (message as ServerFinishMessage) ?? {};\n        if (!request) return;\n        const span = SERVER_SPANS.get(request);\n        if (!span) return;\n        SERVER_SPANS.delete(request);\n        finishHttpSpan(span, response?.statusCode, 500);\n      }),\n    );\n  }\n\n  if (options.client !== false) {\n    disposers.push(\n      subscribeChannel('http.client.request.start', (message) => {\n        const request = (message as ClientStartMessage)?.request;\n        if (!request) return;\n        const method = request.method ?? 'HTTP';\n        // `ClientRequest` exposes host/protocol/path on the public surface.\n        const req = request as ClientRequest & {\n          host?: string;\n          protocol?: string;\n          path?: string;\n        };\n        const { address, port } = splitHostPort(req.host);\n        const scheme = (req.protocol ?? 'http:').replace(':', '');\n        const attributes: Attributes = {\n          [ATTR_HTTP_REQUEST_METHOD]: method,\n          [ATTR_SERVER_ADDRESS]: address,\n          [ATTR_SERVER_PORT]: port,\n          [ATTR_URL_FULL]:\n            address && req.path\n              ? `${scheme}://${req.host}${req.path}`\n              : undefined,\n        };\n        const span = tracer.startSpan(method, {\n          kind: SpanKind.CLIENT,\n          attributes,\n        });\n        CLIENT_SPANS.set(request, span);\n\n        // Inject this span's context into the outbound headers so the\n        // downstream service continues the trace.\n        if (!request.headersSent) {\n          const carrier: Record<string, string> = {};\n          propagation.inject(\n            trace.setSpan(otelContext.active(), span),\n            carrier,\n            defaultTextMapSetter,\n          );\n          for (const [key, value] of Object.entries(carrier)) {\n            try {\n              request.setHeader(key, value);\n            } catch {\n              // Headers already sent / immutable — propagation best-effort.\n            }\n          }\n        }\n      }),\n      subscribeChannel('http.client.response.finish', (message) => {\n        const { request, response } = (message as ClientFinishMessage) ?? {};\n        if (!request) return;\n        const span = CLIENT_SPANS.get(request);\n        if (!span) return;\n        CLIENT_SPANS.delete(request);\n        finishHttpSpan(span, response?.statusCode, 400);\n      }),\n      subscribeChannel('http.client.request.error', (message) => {\n        const { request, error } = (message as ClientErrorMessage) ?? {};\n        if (!request) return;\n        const span = CLIENT_SPANS.get(request);\n        if (!span) return;\n        CLIENT_SPANS.delete(request);\n        if (error instanceof Error) span.recordException(error);\n        span.setStatus({\n          code: SpanStatusCode.ERROR,\n          message: error instanceof Error ? error.message : undefined,\n        });\n        span.end();\n      }),\n    );\n  }\n\n  let active = true;\n  return () => {\n    if (!active) return;\n    active = false;\n    for (const dispose of disposers) dispose();\n  };\n}\n\n/** Set status code + error status (when `>= errorAt`) and end the span. */\nfunction finishHttpSpan(\n  span: Span,\n  statusCode: number | undefined,\n  errorAt: number,\n): void {\n  if (statusCode !== undefined) {\n    span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, statusCode);\n    if (statusCode >= errorAt) {\n      span.setStatus({ code: SpanStatusCode.ERROR });\n    }\n  }\n  span.end();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,IAAI;AAEJ,SAAS,yBAA+D;CACtE,IAAI,WAAW,QAAW,OAAO,UAAU;CAC3C,SACEA,iCAAsC,0BAA0B,KAAK;CACvE,OAAO,UAAU;AACnB;;AAGA,SAAgB,8BAAuC;CACrD,OAAO,uBAAuB,MAAM;AACtC;;;;;AAYA,SAAgB,iBACd,MACA,SACY;CACZ,MAAM,KAAK,uBAAuB;CAClC,IAAI,CAAC,IAAI,WAAW,aAAa,CAAC;CAClC,GAAG,UAAU,MAAM,OAAO;CAC1B,IAAI,SAAS;CACb,aAAa;EACX,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,GAAG,cAAc,MAAM,OAAO;CAChC;AACF;;;;;;AAgBA,SAAgB,wBACd,MACA,UACY;CAEZ,MAAM,UADK,uBACM,CAAC,EAAE,iBAAiB,IAAI;CACzC,IAAI,CAAC,SAAS,aAAa,CAAC;CAE5B,QAAQ,UAAU,QAAmD;CACrE,IAAI,SAAS;CACb,aAAa;EACX,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,QAAQ,YAAY,QAAqD;CAC3E;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;ACzDA,MAAM,aAAsC;CAC1C;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,WAAiD;CACrD,OAAOC,uCAAe;CACtB,KAAKA,uCAAe;CACpB,MAAMA,uCAAe;CACrB,MAAMA,uCAAe;CACrB,OAAOA,uCAAe;AACxB;AAoBA,MAAM,WAAWC,iCAAwC,WAAW;;AAGpE,SAAS,WAAW,MAAyB;CAC3C,IAAI,UAAU,QAAQ,OAAO,SAAS,OAAO,GAAG,IAAI;CACpD,OAAO,KACJ,KAAK,MAAO,OAAO,MAAM,WAAW,IAAI,cAAc,CAAC,CAAE,CAAC,CAC1D,KAAK,GAAG;AACb;AAEA,SAAS,cAAc,OAAwB;CAC7C,IAAI;EACF,OAAO,KAAK,UAAU,KAAK,KAAK,OAAO,KAAK;CAC9C,QAAQ;EACN,OAAO,OAAO,KAAK;CACrB;AACF;;;;;AAMA,SAAgB,eACd,UAAiC,CAAC,GACtB;CACZ,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,QAAQ,WAAW,SAAS,WAAW;CAC7C,MAAM,SAAS,WAAW,gBAAgB,WAAW;CACrD,MAAM,SAAiBC,6BAAK,UAC1B,QAAQ,cAAc,iBACxB;CAIA,IAAI,YAAY;CAEhB,MAAM,YAAY,OAAO,KAAK,UAC5B,iBAAiB,WAAW,UAAU,YAAY;EAChD,IAAI,WAAW;EAEf,MAAM,OAAO,WADC,SAA4B,QAAQ,CAAC,CACV;EACzC,YAAY;EACZ,IAAI;GACF,MAAM,aAAyB;IAC7B,cAAc;IACd,cAAc;IACd,GAAG,QAAQ;GACb;GACA,IAAI,OACF,OAAO,KAAK;IACV,gBAAgB,SAAS;IACzB,cAAc,MAAM,YAAY;IAChC;IACA;GACF,CAAC;GAEH,IAAI,QACF,yBACG,cAAc,CAAC,EACd,SAAS,OAAO;IAAE,eAAe;IAAM,GAAG;GAAW,CAAC;EAE9D,UAAU;GACR,YAAY;EACd;CACF,CAAC,CACH;CAEA,IAAI,SAAS;CACb,aAAa;EACX,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,KAAK,MAAM,WAAW,WAAW,QAAQ;CAC3C;AACF;;;;AC3CA,MAAM,+BAAe,IAAI,QAAsB;AAC/C,MAAM,+BAAe,IAAI,QAAsB;AAE/C,SAAS,YAAY,OAA0D;CAC7E,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;AAC3C;AAEA,SAAS,cAAc,MAGrB;CACA,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,MAAM,MAAM,KAAK,YAAY,GAAG;CAChC,IAAI,QAAQ,IAAI,OAAO,EAAE,SAAS,KAAK;CACvC,MAAM,OAAO,OAAO,KAAK,MAAM,MAAM,CAAC,CAAC;CACvC,OAAO;EACL,SAAS,KAAK,MAAM,GAAG,GAAG;EAC1B,MAAM,OAAO,SAAS,IAAI,IAAI,OAAO;CACvC;AACF;;;;;AAMA,SAAgB,eACd,UAAiC,CAAC,GACtB;CACZ,MAAM,SAAS,QAAQ,UAAUC,yBAAM,UAAU,0BAA0B;CAC3E,MAAM,YAA+B,CAAC;CAEtC,IAAI,QAAQ,WAAW,OACrB,UAAU,KACR,iBAAiB,8BAA8B,YAAY;EACzD,MAAM,UAAW,SAAgC;EACjD,IAAI,CAAC,SAAS;EACd,MAAM,SAAS,QAAQ,UAAU;EAEjC,MAAM,EAAE,SAAS,SAAS,cADb,YAAY,QAAQ,QAAQ,IACE,CAAC;EAC5C,MAAM,QAAQ,QAAQ,OAAO,IAAG,CAAE,MAAM,KAAK,CAAC,CAAC,CAAC;EAChD,MAAM,aAAyB;IAC5BC,+DAA2B;IAC3BC,oDAAgB;IAChBC,sDAAkB;IAClBC,oEAAgC,QAAQ;IACxCC,+DAA2B,YAC1B,QAAQ,QAAQ,aAClB;IACCC,0DAAsB;IACtBC,uDAAmB;EACtB;EACA,MAAM,SAASC,+BAAY,QACzBC,2BAAY,OAAO,GACnB,QAAQ,SACRC,uCACF;EACA,MAAM,OAAO,OAAO,UAClB,QACA;GAAE,MAAMC,4BAAS;GAAQ;EAAW,GACpC,MACF;EACA,aAAa,IAAI,SAAS,IAAI;CAChC,CAAC,GACD,iBAAiB,gCAAgC,YAAY;EAC3D,MAAM,EAAE,SAAS,aAAc,WAAmC,CAAC;EACnE,IAAI,CAAC,SAAS;EACd,MAAM,OAAO,aAAa,IAAI,OAAO;EACrC,IAAI,CAAC,MAAM;EACX,aAAa,OAAO,OAAO;EAC3B,eAAe,MAAM,UAAU,YAAY,GAAG;CAChD,CAAC,CACH;CAGF,IAAI,QAAQ,WAAW,OACrB,UAAU,KACR,iBAAiB,8BAA8B,YAAY;EACzD,MAAM,UAAW,SAAgC;EACjD,IAAI,CAAC,SAAS;EACd,MAAM,SAAS,QAAQ,UAAU;EAEjC,MAAM,MAAM;EAKZ,MAAM,EAAE,SAAS,SAAS,cAAc,IAAI,IAAI;EAChD,MAAM,UAAU,IAAI,YAAY,QAAO,CAAE,QAAQ,KAAK,EAAE;EACxD,MAAM,aAAyB;IAC5BV,+DAA2B;IAC3BK,0DAAsB;IACtBC,uDAAmB;IACnBK,oDACC,WAAW,IAAI,OACX,GAAG,OAAO,KAAK,IAAI,OAAO,IAAI,SAC9B;EACR;EACA,MAAM,OAAO,OAAO,UAAU,QAAQ;GACpC,MAAMD,4BAAS;GACf;EACF,CAAC;EACD,aAAa,IAAI,SAAS,IAAI;EAI9B,IAAI,CAAC,QAAQ,aAAa;GACxB,MAAM,UAAkC,CAAC;GACzC,+BAAY,OACVX,yBAAM,QAAQS,2BAAY,OAAO,GAAG,IAAI,GACxC,SACAI,uCACF;GACA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAC/C,IAAI;IACF,QAAQ,UAAU,KAAK,KAAK;GAC9B,QAAQ,CAER;EAEJ;CACF,CAAC,GACD,iBAAiB,gCAAgC,YAAY;EAC3D,MAAM,EAAE,SAAS,aAAc,WAAmC,CAAC;EACnE,IAAI,CAAC,SAAS;EACd,MAAM,OAAO,aAAa,IAAI,OAAO;EACrC,IAAI,CAAC,MAAM;EACX,aAAa,OAAO,OAAO;EAC3B,eAAe,MAAM,UAAU,YAAY,GAAG;CAChD,CAAC,GACD,iBAAiB,8BAA8B,YAAY;EACzD,MAAM,EAAE,SAAS,UAAW,WAAkC,CAAC;EAC/D,IAAI,CAAC,SAAS;EACd,MAAM,OAAO,aAAa,IAAI,OAAO;EACrC,IAAI,CAAC,MAAM;EACX,aAAa,OAAO,OAAO;EAC3B,IAAI,iBAAiB,OAAO,KAAK,gBAAgB,KAAK;EACtD,KAAK,UAAU;GACb,MAAMC,kCAAe;GACrB,SAAS,iBAAiB,QAAQ,MAAM,UAAU;EACpD,CAAC;EACD,KAAK,IAAI;CACX,CAAC,CACH;CAGF,IAAI,SAAS;CACb,aAAa;EACX,IAAI,CAAC,QAAQ;EACb,SAAS;EACT,KAAK,MAAM,WAAW,WAAW,QAAQ;CAC3C;AACF;;AAGA,SAAS,eACP,MACA,YACA,SACM;CACN,IAAI,eAAe,QAAW;EAC5B,KAAK,aAAaC,oEAAgC,UAAU;EAC5D,IAAI,cAAc,SAChB,KAAK,UAAU,EAAE,MAAMD,kCAAe,MAAM,CAAC;CAEjD;CACA,KAAK,IAAI;AACX"}