{"version":3,"file":"baseline.mjs","names":[],"sources":["../../../src/ir/sdk-behavior.ts","../../../src/errors.ts","../../../src/parser/refs.ts","../../../src/ir/types.ts","../../../src/utils/naming.ts","../../../src/parser/inline-models.ts","../../../src/parser/schemas.ts","../../../src/parser/pagination.ts","../../../src/parser/responses.ts","../../../src/parser/operations.ts","../../../src/parser/normalize-inline-models.ts","../../../src/parser/collect-inline-enums.ts","../../../src/parser/normalize-model-refs.ts","../../../src/parser/parse.ts","../../../scripts/smoke/shared.ts","../../../scripts/smoke/baseline.ts"],"sourcesContent":["/**\n * SDK Behavior IR — language-agnostic runtime policies for generated SDKs.\n *\n * These types capture the \"what\" of SDK behavior (retry, telemetry, errors, etc.)\n * while emitters provide the \"how\" (language-specific mechanism).\n *\n * Emitters access these via `ctx.spec.sdk` — always populated, never undefined.\n */\n\n// ── Retry ──────────────────────────────────────────────────────────\n\n/** Retry policy — when and how to retry failed requests. */\nexport interface RetryPolicy {\n  /** HTTP status codes that trigger a retry. */\n  retryableStatusCodes: number[];\n  /** Maximum number of retry attempts (0 = no retries). */\n  maxRetries: number;\n  /** Whether to retry on connection errors (DNS failure, TCP reset). */\n  retryOnConnectionError: boolean;\n  /** Whether to retry on timeout errors. */\n  retryOnTimeout: boolean;\n  /** Backoff strategy between retries. */\n  backoff: BackoffStrategy;\n}\n\n/** Exponential backoff configuration.\n *\n * Formula: `delay = min(initialDelay * multiplier^attempt, maxDelay)`\n * With jitter: `delay += delay * jitterFactor * random(0, 1)`\n */\nexport interface BackoffStrategy {\n  /** Initial delay in seconds before the first retry. */\n  initialDelay: number;\n  /** Multiplier applied to the delay on each subsequent retry. */\n  multiplier: number;\n  /** Maximum delay in seconds (cap). */\n  maxDelay: number;\n  /** Jitter factor (0..1). 0.5 means up to 50% random jitter added. */\n  jitterFactor: number;\n}\n\n// ── Errors ─────────────────────────────────────────────────────────\n\n/** Error mapping — status codes to named exception kinds. */\nexport interface ErrorPolicy {\n  /** Map from HTTP status code to a logical error kind name (e.g. 400 → 'BadRequest').\n   *  Emitters append language-specific suffixes (e.g. 'BadRequestException'). */\n  statusCodeMap: Record<number, string>;\n  /** Catch-all error kind for 5xx status codes not in the map. */\n  serverErrorKind: string;\n  /** Catch-all error kind for unrecognized status codes. */\n  clientErrorKind: string;\n  /** URL template for error documentation. Use {code} as placeholder for the API error code. */\n  errorDocUrlTemplate?: string;\n}\n\n// ── Telemetry ──────────────────────────────────────────────────────\n\n/** Telemetry — what request metrics to track and send. */\nexport interface TelemetryPolicy {\n  /** Whether telemetry is enabled by default. Users can opt out via constructor param. */\n  enabledByDefault: boolean;\n  /** Header name for client telemetry data (previous request's ID + latency). */\n  headerName: string;\n  /** Response header name for the request ID. */\n  requestIdHeader: string;\n}\n\n// ── Pagination ─────────────────────────────────────────────────────\n\n/** Pagination behavior defaults. */\nexport interface PaginationPolicy {\n  /** Delay in milliseconds between pages during auto-pagination. 0 = no delay. */\n  autoPageDelayMs: number;\n}\n\n// ── Idempotency ────────────────────────────────────────────────────\n\n/** Idempotency auto-generation rules. */\nexport interface IdempotencyPolicy {\n  /** Header name for the idempotency key. */\n  headerName: string;\n  /** Whether to auto-generate a UUID v4 idempotency key for POST requests when retries > 0. */\n  autoGenerateForPost: boolean;\n}\n\n// ── Logging ────────────────────────────────────────────────────────\n\n/** Logging contract — what to log at which level. */\nexport interface LoggingPolicy {\n  /** Whether structured logging hooks are generated. */\n  enabled: boolean;\n  /** Log events that the generated client emits. */\n  events: LogEvent[];\n}\n\n/** A discrete loggable event in the request lifecycle. */\nexport type LogEvent =\n  | 'request.start'\n  | 'request.success'\n  | 'request.retry'\n  | 'request.rate_limited'\n  | 'request.error'\n  | 'request.connection_error';\n\n// ── User-Agent ─────────────────────────────────────────────────────\n\n/** User-Agent construction rules. */\nexport interface UserAgentPolicy {\n  /** Template for the SDK identifier string.\n   *  Placeholders: {name} = spec name, {lang} = emitter language, {version} = SDK version.\n   *  Each emitter interpolates with its own language string and casing conventions.\n   *  Example: '{name} {lang}/{version}' → 'Acme PHP/4.32.0' */\n  sdkIdentifierTemplate: string;\n  /** Whether to append the runtime/language version (e.g. PHP 8.2, Python 3.12). */\n  includeRuntimeVersion: boolean;\n  /** Whether to allow app info enrichment via setAppInfo(name, version, url). */\n  allowAppInfo: boolean;\n  /** AI agent environment variable detection entries. */\n  aiAgentEnvVars: AiAgentEnvVar[];\n}\n\n/** Maps an environment variable to an AI agent slug for User-Agent enrichment. */\nexport interface AiAgentEnvVar {\n  /** Environment variable to check (e.g. 'CLAUDE_CODE'). */\n  envVar: string;\n  /** Agent name to append to User-Agent (e.g. 'ClaudeCode'). */\n  agentName: string;\n}\n\n// ── Request Guards ─────────────────────────────────────────────────\n\n/** Guards that validate request params before sending. */\nexport interface RequestGuardPolicy {\n  /** Keys that should be in RequestOptions, not in params.\n   *  If detected in the body or query params, the SDK throws an error. */\n  optionKeys: string[];\n}\n\n// ── Timeouts ───────────────────────────────────────────────────────\n\n/** Timeout configuration. */\nexport interface TimeoutPolicy {\n  /** Default HTTP request timeout in seconds. */\n  defaultTimeoutSeconds: number;\n  /** Environment variable name to override the timeout (e.g. 'SDK_REQUEST_TIMEOUT'). */\n  timeoutEnvVar?: string;\n}\n\n// ── Root ───────────────────────────────────────────────────────────\n\n/** Language-agnostic runtime policies for generated SDKs.\n *  Attached to `ApiSpec.sdk` and consumed by emitters via `ctx.spec.sdk`. */\nexport interface SdkBehavior {\n  retry: RetryPolicy;\n  errors: ErrorPolicy;\n  telemetry: TelemetryPolicy;\n  pagination: PaginationPolicy;\n  idempotency: IdempotencyPolicy;\n  logging: LoggingPolicy;\n  userAgent: UserAgentPolicy;\n  requestGuard: RequestGuardPolicy;\n  timeout: TimeoutPolicy;\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\n/**\n * Canonical SDK behavior defaults. Per-language or per-project overrides can\n * be applied via `mergeSdkBehavior()` in each SDK's `oagen.config.ts`.\n *\n * - Retry: exponential backoff with jitter, retries on 429/5xx\n * - Errors: standard HTTP status → exception kind mapping\n * - Telemetry: enabled by default, tracks request ID + latency\n * - Pagination: no inter-page delay (Node overrides to 350ms)\n * - Idempotency: auto-generate UUID v4 for retryable POSTs\n * - Logging: all lifecycle events enabled\n * - User-Agent: SDK identifier + runtime version + app info + AI agent detection\n * - Request guards: detect misplaced RequestOptions keys in params\n * - Timeout: 60s default (Python overrides to 30s)\n */\nexport function defaultSdkBehavior(): SdkBehavior {\n  return {\n    retry: {\n      retryableStatusCodes: [429, 500, 502, 503, 504],\n      maxRetries: 3,\n      retryOnConnectionError: true,\n      retryOnTimeout: true,\n      backoff: {\n        initialDelay: 1.0,\n        multiplier: 2.0,\n        maxDelay: 30.0,\n        jitterFactor: 0.5,\n      },\n    },\n    errors: {\n      statusCodeMap: {\n        400: 'BadRequest',\n        401: 'Authentication',\n        403: 'Authorization',\n        404: 'NotFound',\n        409: 'Conflict',\n        422: 'UnprocessableEntity',\n        429: 'RateLimitExceeded',\n      },\n      serverErrorKind: 'Server',\n      clientErrorKind: 'Api',\n    },\n    telemetry: {\n      enabledByDefault: true,\n      headerName: 'X-Client-Telemetry',\n      requestIdHeader: 'X-Request-ID',\n    },\n    pagination: {\n      autoPageDelayMs: 0,\n    },\n    idempotency: {\n      headerName: 'Idempotency-Key',\n      autoGenerateForPost: true,\n    },\n    logging: {\n      enabled: true,\n      events: [\n        'request.start',\n        'request.success',\n        'request.retry',\n        'request.rate_limited',\n        'request.error',\n        'request.connection_error',\n      ],\n    },\n    userAgent: {\n      sdkIdentifierTemplate: '{name} {lang}/{version}',\n      includeRuntimeVersion: true,\n      allowAppInfo: true,\n      aiAgentEnvVars: [\n        { envVar: 'CLAUDE_CODE', agentName: 'ClaudeCode' },\n        { envVar: 'CURSOR_AGENT', agentName: 'Cursor' },\n        { envVar: 'CLINE_ACTIVE', agentName: 'Cline' },\n        { envVar: 'WINDSURF_ACTIVE', agentName: 'Windsurf' },\n        { envVar: 'COPILOT_AGENT', agentName: 'Copilot' },\n      ],\n    },\n    requestGuard: {\n      optionKeys: [\n        'api_key',\n        'apiKey',\n        'idempotency_key',\n        'idempotencyKey',\n        'extra_headers',\n        'extraHeaders',\n        'max_retries',\n        'maxRetries',\n        'base_url',\n        'baseUrl',\n      ],\n    },\n    timeout: {\n      defaultTimeoutSeconds: 60,\n    },\n  };\n}\n\n// ── Merge ──────────────────────────────────────────────────────────\n\n/** Recursive partial type for deep overrides. */\nexport type DeepPartial<T> = {\n  [K in keyof T]?: T[K] extends (infer U)[]\n    ? U[] // Arrays replace entirely (don't concat)\n    : T[K] extends object\n      ? DeepPartial<T[K]>\n      : T[K];\n};\n\n/**\n * Deep-merge partial overrides into the canonical defaults.\n * Arrays replace entirely (so `retryableStatusCodes: [429]` replaces the full list,\n * rather than appending). Object properties are merged recursively.\n */\nexport function mergeSdkBehavior(overrides: DeepPartial<SdkBehavior>): SdkBehavior {\n  return deepMerge(\n    defaultSdkBehavior() as unknown as Record<string, unknown>,\n    overrides as unknown as Record<string, unknown>,\n  ) as unknown as SdkBehavior;\n}\n\n/**\n * Self-contained deep merge (no external imports — ir/ is layer 0).\n * Arrays and primitives from `source` replace those in `target`.\n * Objects are merged recursively.\n */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n  const result: Record<string, unknown> = { ...target };\n  for (const key of Object.keys(source)) {\n    const sourceVal = source[key];\n    const targetVal = target[key];\n    if (sourceVal === undefined) continue;\n    if (\n      sourceVal !== null &&\n      typeof sourceVal === 'object' &&\n      !Array.isArray(sourceVal) &&\n      targetVal !== null &&\n      typeof targetVal === 'object' &&\n      !Array.isArray(targetVal)\n    ) {\n      result[key] = deepMerge(targetVal as Record<string, unknown>, sourceVal as Record<string, unknown>);\n    } else {\n      result[key] = sourceVal;\n    }\n  }\n  return result;\n}\n","/**\n * Structured error hierarchy for oagen.\n *\n * Every error carries a human-readable `hint` that suggests a recovery action.\n * The hint is appended to the `message` so it appears in stack traces and logs.\n */\n\n/** Base class for all oagen errors. */\nexport class OagenError extends Error {\n  readonly hint: string;\n\n  constructor(message: string, hint: string) {\n    const fullMessage = hint ? `${message}\\nHint: ${hint}` : message;\n    super(fullMessage);\n    this.name = 'OagenError';\n    this.hint = hint;\n  }\n}\n\n/** Thrown when a command should terminate with a specific exit code. */\nexport class CommandError extends OagenError {\n  readonly exitCode: number;\n\n  constructor(message: string, hint: string, exitCode: number) {\n    super(message, hint);\n    this.name = 'CommandError';\n    this.exitCode = exitCode;\n  }\n}\n\n/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */\nexport class SpecParseError extends OagenError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'SpecParseError';\n  }\n}\n\n/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */\nexport class ConfigError extends OagenError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'ConfigError';\n  }\n}\n\n/** Thrown when a config file exists but cannot be loaded or evaluated. */\nexport class ConfigLoadError extends ConfigError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'ConfigLoadError';\n  }\n}\n\n/** Thrown when a config targets a different IR version than the installed package. */\nexport class ConfigVersionMismatchError extends ConfigError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'ConfigVersionMismatchError';\n  }\n}\n\n/** Thrown when an API surface extractor encounters a problem. */\nexport class ExtractorError extends OagenError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'ExtractorError';\n  }\n}\n\n/** Thrown when a requested language or extractor is not found in a registry. */\nexport class RegistryError extends OagenError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'RegistryError';\n  }\n}\n\n/** Thrown for internal invariant violations that indicate a bug. */\nexport class InternalError extends OagenError {\n  constructor(message: string, hint: string) {\n    super(message, hint);\n    this.name = 'InternalError';\n  }\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { makeDocumentFromString, bundleDocument, createConfig, BaseResolver, Oas3_1Types } from '@redocly/openapi-core';\nimport { SpecParseError } from '../errors.js';\n\nexport interface BundledSpec {\n  parsed: Record<string, unknown>;\n  specPath: string;\n}\n\nexport async function loadAndBundleSpec(specPath: string): Promise<BundledSpec> {\n  const absolutePath = resolve(specPath);\n  const content = await readFile(absolutePath, 'utf-8');\n  const document = makeDocumentFromString(content, pathToFileURL(absolutePath).href);\n\n  const config = await createConfig({});\n  const resolver = new BaseResolver();\n\n  const result = await bundleDocument({\n    document,\n    config,\n    types: Oas3_1Types,\n    externalRefResolver: resolver,\n    dereference: false,\n  });\n\n  if (result.problems.some((p) => p.severity === 'error')) {\n    const errors = result.problems\n      .filter((p) => p.severity === 'error')\n      .map((p) => p.message)\n      .join('\\n');\n    throw new SpecParseError(\n      `Failed to parse spec: ${errors}`,\n      `Check the OpenAPI spec at \"${absolutePath}\" for syntax errors. Run a linter such as \\`npx @redocly/cli lint ${specPath}\\` to identify issues.`,\n    );\n  }\n\n  return {\n    parsed: result.bundle.parsed as Record<string, unknown>,\n    specPath: absolutePath,\n  };\n}\n","import type { SdkBehavior } from './sdk-behavior.js';\n\n/** Authentication scheme extracted from OpenAPI securitySchemes */\nexport type AuthScheme =\n  | { kind: 'bearer' }\n  | { kind: 'apiKey'; in: 'header' | 'query' | 'cookie'; name: string }\n  | { kind: 'oauth2'; flows: Record<string, unknown> };\n\n/** Root IR node representing the full API surface */\n/** A server entry from the OpenAPI servers array */\nexport interface ServerEntry {\n  url: string;\n  description?: string;\n}\n\n/** Root IR node representing the full API surface */\nexport interface ApiSpec {\n  name: string;\n  version: string;\n  description?: string;\n  baseUrl: string;\n  servers?: ServerEntry[];\n  services: Service[];\n  models: Model[];\n  enums: Enum[];\n  auth?: AuthScheme[];\n  /** Language-agnostic runtime policies (retry, errors, telemetry, etc.). */\n  sdk: SdkBehavior;\n}\n\n/** A service groups related operations (maps to an SDK resource class) */\nexport interface Service {\n  name: string;\n  description?: string;\n  operations: Operation[];\n}\n\n/** A single API operation (maps to an SDK method) */\n/** Per-operation security requirement: scheme name → scope list. */\nexport interface SecurityRequirement {\n  schemeName: string;\n  scopes: string[];\n}\n\nexport interface Operation {\n  name: string;\n  description?: string;\n  httpMethod: HttpMethod;\n  path: string;\n  pathParams: Parameter[];\n  queryParams: Parameter[];\n  headerParams: Parameter[];\n  cookieParams?: Parameter[];\n  requestBody?: TypeRef;\n  requestBodyEncoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n  response: TypeRef;\n  successResponses?: SuccessResponse[];\n  errors: ErrorResponse[];\n  pagination?: PaginationMeta;\n  injectIdempotencyKey: boolean;\n  deprecated?: boolean;\n  async?: boolean;\n  /** Per-operation security overrides. When present, overrides the global spec-level security. */\n  security?: SecurityRequirement[];\n  /**\n   * Mutually-exclusive parameter groups parsed from `x-mutually-exclusive-parameter-groups`.\n   * Each group represents a logical choice the caller must (or may) make between\n   * several subsets of query/path/header parameters. The grouped parameters remain\n   * in their original arrays (queryParams, pathParams, etc.) for wire-format purposes;\n   * this field adds the grouping metadata so emitters can render sum types.\n   */\n  parameterGroups?: ParameterGroup[];\n}\n\n/**\n * A mutually-exclusive parameter group. The caller must supply exactly one\n * variant (when `optional` is false) or may omit the group entirely (when true).\n */\nexport interface ParameterGroup {\n  /** Group name from the extension (e.g. \"parent_resource\"). */\n  name: string;\n  /** True when the whole group may be omitted. */\n  optional: boolean;\n  /** Ordered variants (insertion order matches the spec). */\n  variants: ParameterGroupVariant[];\n}\n\n/**\n * One variant within a mutually-exclusive parameter group.\n */\nexport interface ParameterGroupVariant {\n  /** Variant name from the extension (e.g. \"by_id\", \"by_external_id\"). */\n  name: string;\n  /**\n   * References to the actual parameter IR nodes. These are the same\n   * objects that live in operation.queryParams / .pathParams / .headerParams --\n   * shared by identity, not duplicated.\n   */\n  parameters: Parameter[];\n}\n\n/** Structured pagination metadata for auto-paging iterator generation */\nexport interface PaginationMeta {\n  strategy: 'cursor' | 'offset' | 'link-header';\n  param: string;\n  limitParam?: string;\n  dataPath?: string;\n  itemType: TypeRef;\n}\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\nexport interface Parameter {\n  name: string;\n  type: TypeRef;\n  required: boolean;\n  description?: string;\n  deprecated?: boolean;\n  default?: unknown;\n  example?: unknown;\n  style?: 'form' | 'simple' | 'label' | 'matrix';\n  explode?: boolean;\n}\n\n/** Type reference — the core type system of the IR */\nexport type TypeRef = PrimitiveType | ArrayType | ModelRef | EnumRef | UnionType | NullableType | LiteralType | MapType;\n\nexport interface PrimitiveType {\n  kind: 'primitive';\n  type: 'string' | 'integer' | 'number' | 'boolean' | 'unknown';\n  format?: string;\n}\n\nexport interface ArrayType {\n  kind: 'array';\n  items: TypeRef;\n}\n\nexport interface ModelRef {\n  kind: 'model';\n  name: string;\n}\n\nexport interface EnumRef {\n  kind: 'enum';\n  name: string;\n  values?: (string | number)[];\n}\n\nexport interface LiteralType {\n  kind: 'literal';\n  value: string | number | boolean | null;\n}\n\nexport interface UnionType {\n  kind: 'union';\n  variants: TypeRef[];\n  discriminator?: { property: string; mapping: Record<string, string> };\n  /** Which OAS composition keyword produced this union. Emitters can use this to\n   *  distinguish inheritance (allOf) from exclusive union (oneOf) from open union (anyOf). */\n  compositionKind?: 'allOf' | 'oneOf' | 'anyOf';\n}\n\nexport interface NullableType {\n  kind: 'nullable';\n  inner: TypeRef;\n}\n\nexport interface MapType {\n  kind: 'map';\n  valueType: TypeRef;\n  keyType?: TypeRef;\n}\n\n/**\n * A generic type parameter on a model.\n * Example: `DirectoryUser<TCustomAttributes = Record<string, unknown>>`\n * → `{ name: 'TCustomAttributes', default: { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } } }`\n */\nexport interface TypeParam {\n  name: string;\n  /** Default type when the param is not specified. */\n  default?: TypeRef;\n}\n\n/** Model definition (maps to an SDK model/data class) */\nexport interface Model {\n  name: string;\n  description?: string;\n  fields: Field[];\n  /** Generic type parameters. Empty/undefined for non-generic models. */\n  typeParams?: TypeParam[];\n  /**\n   * When set, this model is a discriminated union over allOf+oneOf variants.\n   * Emitters should generate a dispatcher (factory) instead of a regular dataclass.\n   * The `property` field is the discriminator key (e.g. \"event\"), and `mapping`\n   * maps each discriminator value to the concrete variant model name.\n   */\n  discriminator?: {\n    property: string;\n    mapping: Record<string, string>;\n  };\n}\n\nexport interface Field {\n  name: string;\n  /**\n   * Optional domain-facing name override. When set, emitters derive the\n   * domain-side identifier (in their own casing) from this instead of `name`,\n   * while serialization still uses `name` for the wire key. Lets an SDK expose\n   * a wire field under a friendlier name (e.g. `connection_type` → `type`)\n   * without changing the API contract. Set via the `fieldHints` config and\n   * honored by any emitter that reads it.\n   */\n  domainName?: string;\n  type: TypeRef;\n  required: boolean;\n  description?: string;\n  readOnly?: boolean;\n  writeOnly?: boolean;\n  deprecated?: boolean;\n  default?: unknown;\n  example?: unknown;\n}\n\n/** Enum definition */\nexport interface Enum {\n  name: string;\n  values: EnumValue[];\n  /** Spec-level default value (the value of `default:` on the schema). Optional. */\n  default?: string | number;\n}\n\nexport interface EnumValue {\n  name: string;\n  value: string | number;\n  description?: string;\n  deprecated?: boolean;\n}\n\n/**\n * Exhaustive check helper for TypeRef switches.\n * If a new kind is added to TypeRef, any switch that doesn't handle it\n * will fail to compile because `never` won't accept the unhandled variant.\n *\n * Usage:\n *   switch (ref.kind) {\n *     case 'primitive': ...\n *     case 'array': ...\n *     // If you forget 'literal', TypeScript errors here:\n *     default: assertNever(ref);\n *   }\n */\nexport function assertNever(x: never): never {\n  // Inline to avoid importing from ../errors.js (ir/ is layer 0, must not import upward)\n  const kind = (x as TypeRef).kind;\n  const err = new Error(\n    `Unexpected TypeRef kind: ${kind}\\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`,\n  );\n  err.name = 'InternalError';\n  throw err;\n}\n\n/**\n * Generic depth-first walker for TypeRef trees.\n * Handles recursion into array/nullable/union/map children and provides\n * an exhaustive `assertNever` check so callers don't need to repeat the\n * switch boilerplate.  Supply callbacks only for the leaf kinds you care about.\n */\nexport function walkTypeRef(\n  ref: TypeRef,\n  visitor: {\n    model?: (ref: ModelRef) => void;\n    enum?: (ref: EnumRef) => void;\n    primitive?: (ref: PrimitiveType) => void;\n    literal?: (ref: LiteralType) => void;\n  },\n): void {\n  switch (ref.kind) {\n    case 'model':\n      visitor.model?.(ref);\n      break;\n    case 'enum':\n      visitor.enum?.(ref);\n      break;\n    case 'array':\n      walkTypeRef(ref.items, visitor);\n      break;\n    case 'nullable':\n      walkTypeRef(ref.inner, visitor);\n      break;\n    case 'union':\n      for (const v of ref.variants) walkTypeRef(v, visitor);\n      break;\n    case 'map':\n      if (ref.keyType) walkTypeRef(ref.keyType, visitor);\n      walkTypeRef(ref.valueType, visitor);\n      break;\n    case 'literal':\n      visitor.literal?.(ref);\n      break;\n    case 'primitive':\n      visitor.primitive?.(ref);\n      break;\n    default:\n      assertNever(ref);\n  }\n}\n\n/**\n * Generic depth-first mapper for TypeRef trees.\n * Like walkTypeRef but returns a transformed value instead of void.\n * Handles recursion into array/nullable/union/map children, passing\n * already-mapped child values to the parent callback.\n */\nexport function mapTypeRef<T>(\n  ref: TypeRef,\n  mapper: {\n    primitive: (ref: PrimitiveType) => T;\n    array: (ref: ArrayType, mappedItems: T) => T;\n    model: (ref: ModelRef) => T;\n    enum: (ref: EnumRef) => T;\n    union: (ref: UnionType, mappedVariants: T[]) => T;\n    nullable: (ref: NullableType, mappedInner: T) => T;\n    literal: (ref: LiteralType) => T;\n    map: (ref: MapType, mappedValue: T, mappedKey?: T) => T;\n  },\n): T {\n  switch (ref.kind) {\n    case 'primitive':\n      return mapper.primitive(ref);\n    case 'array':\n      return mapper.array(ref, mapTypeRef(ref.items, mapper));\n    case 'model':\n      return mapper.model(ref);\n    case 'enum':\n      return mapper.enum(ref);\n    case 'union':\n      return mapper.union(\n        ref,\n        ref.variants.map((v) => mapTypeRef(v, mapper)),\n      );\n    case 'nullable':\n      return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));\n    case 'literal':\n      return mapper.literal(ref);\n    case 'map':\n      return mapper.map(\n        ref,\n        mapTypeRef(ref.valueType, mapper),\n        ref.keyType ? mapTypeRef(ref.keyType, mapper) : undefined,\n      );\n    default:\n      return assertNever(ref);\n  }\n}\n\n// --- IR traversal utilities ---\n\n/**\n * Collect all model names referenced (directly or transitively) by a TypeRef.\n */\nexport function collectModelRefs(ref: TypeRef): string[] {\n  const names: string[] = [];\n  walkTypeRef(ref, { model: (r) => names.push(r.name) });\n  return names;\n}\n\n/**\n * Collect all enum names referenced by a TypeRef.\n */\nexport function collectEnumRefs(ref: TypeRef): string[] {\n  const names: string[] = [];\n  walkTypeRef(ref, { enum: (r) => names.push(r.name) });\n  return names;\n}\n\n/**\n * Collect all TypeRef-referenced model and enum names from a model's fields.\n * Returns { models, enums } sets for generating import statements.\n */\nexport function collectFieldDependencies(model: Model): {\n  models: Set<string>;\n  enums: Set<string>;\n} {\n  const models = new Set<string>();\n  const enums = new Set<string>();\n\n  for (const field of model.fields) {\n    for (const name of collectModelRefs(field.type)) {\n      if (name !== model.name) models.add(name);\n    }\n    for (const name of collectEnumRefs(field.type)) {\n      enums.add(name);\n    }\n  }\n\n  return { models, enums };\n}\n\n/**\n * Assign each model to the service that first references it.\n * Models referenced by multiple services are assigned to the first.\n * Models not referenced by any service are unassigned (absent from the map).\n *\n * @param hints - Optional pin overrides keyed by IR model name → IR service\n *   name. Applied after the natural assignment loop. Both names must exist in\n *   the spec; unknown keys/values throw a config-style error so typos fail\n *   loud at generation time.\n */\nexport function assignModelsToServices(\n  models: Model[],\n  services: Service[],\n  hints?: Record<string, string>,\n): Map<string, string> {\n  const modelToService = new Map<string, string>();\n  const modelNames = new Set(models.map((m) => m.name));\n\n  for (const service of services) {\n    const referencedModels = new Set<string>();\n\n    for (const op of service.operations) {\n      if (op.requestBody) {\n        for (const name of collectModelRefs(op.requestBody)) {\n          referencedModels.add(name);\n        }\n      }\n      for (const name of collectModelRefs(op.response)) {\n        referencedModels.add(name);\n      }\n      for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n        for (const name of collectModelRefs(param.type)) {\n          referencedModels.add(name);\n        }\n      }\n      if (op.pagination) {\n        for (const name of collectModelRefs(op.pagination.itemType)) {\n          referencedModels.add(name);\n        }\n      }\n    }\n\n    // Transitively collect models referenced by the directly-referenced models\n    const toVisit = [...referencedModels];\n    while (toVisit.length > 0) {\n      const name = toVisit.pop()!;\n      const model = models.find((m) => m.name === name);\n      if (!model) continue;\n      for (const field of model.fields) {\n        for (const ref of collectModelRefs(field.type)) {\n          if (!referencedModels.has(ref) && modelNames.has(ref)) {\n            referencedModels.add(ref);\n            toVisit.push(ref);\n          }\n        }\n      }\n    }\n\n    for (const name of referencedModels) {\n      if (!modelToService.has(name)) {\n        modelToService.set(name, service.name);\n      }\n    }\n  }\n\n  if (hints) {\n    const serviceNames = new Set(services.map((s) => s.name));\n    for (const [modelName, serviceName] of Object.entries(hints)) {\n      if (!modelNames.has(modelName)) {\n        const err = new Error(\n          `modelHints: unknown model \"${modelName}\". Hint keys must match an IR model name (post-cleanSchemaName/schemaNameTransform).`,\n        );\n        err.name = 'ConfigError';\n        throw err;\n      }\n      if (!serviceNames.has(serviceName)) {\n        const err = new Error(\n          `modelHints: unknown service \"${serviceName}\" for model \"${modelName}\". Hint values must match an IR service name (PascalCase, derived from the operation's first tag).`,\n        );\n        err.name = 'ConfigError';\n        throw err;\n      }\n      modelToService.set(modelName, serviceName);\n    }\n  }\n\n  return modelToService;\n}\n\n/**\n * Collect all model names referenced as request bodies across all services.\n */\nexport function collectRequestBodyModels(services: Service[]): Set<string> {\n  const result = new Set<string>();\n  for (const service of services) {\n    for (const op of service.operations) {\n      if (op.requestBody) {\n        for (const name of collectModelRefs(op.requestBody)) {\n          result.add(name);\n        }\n      }\n    }\n  }\n  return result;\n}\n\nexport interface ErrorResponse {\n  statusCode: number;\n  type?: TypeRef;\n}\n\n/** A successful response entry from a 2xx status code */\nexport interface SuccessResponse {\n  statusCode: number;\n  type: TypeRef;\n}\n","/**\n * Known compound tokens that the regex-based splitter over-splits.\n * Each entry is [lowercase-word-sequence, canonical-form].\n * Sorted longest-first so greedy matching works correctly.\n */\nconst COMPOUND_WORDS: [string[], string][] = [\n  [['m', '2', 'm'], 'M2M'],\n  [['o', 'auth'], 'OAuth'],\n];\n\n/**\n * Recombine adjacent words that form a known compound token.\n */\nfunction recombineCompounds(words: string[]): string[] {\n  const result: string[] = [];\n  let i = 0;\n  while (i < words.length) {\n    let matched = false;\n    for (const [pattern, canonical] of COMPOUND_WORDS) {\n      if (i + pattern.length <= words.length) {\n        const matches = pattern.every((p, j) => words[i + j].toLowerCase() === p);\n        if (matches) {\n          result.push(canonical);\n          i += pattern.length;\n          matched = true;\n          break;\n        }\n      }\n    }\n    if (!matched) {\n      result.push(words[i]);\n      i++;\n    }\n  }\n  return result;\n}\n\n/**\n * Split a string into words, handling:\n * - camelCase / PascalCase boundaries\n * - snake_case / kebab-case separators\n * - Consecutive capitals (e.g., \"HTTPClient\" → [\"HTTP\", \"Client\"])\n * - Numbers as word boundaries (e.g., \"OAuth2Token\" → [\"OAuth\", \"2\", \"Token\"])\n * - Known compounds are recombined (e.g., \"M2M\" stays as one word)\n */\nexport function splitWords(s: string): string[] {\n  if (!s) return [];\n\n  const words = s\n    .replace(/[^a-zA-Z0-9_\\-\\s.]/g, '_') // replace non-alphanumeric chars with separator\n    .replace(/([a-z])([A-Z])/g, '$1\\0$2') // camelCase boundary\n    .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2') // consecutive caps boundary\n    .replace(/([a-zA-Z])(\\d)/g, '$1\\0$2') // letter to number\n    .replace(/(\\d)([a-zA-Z])/g, '$1\\0$2') // number to letter\n    .split(/[\\0_\\-\\s.]+/)\n    .filter((w) => w.length > 0);\n\n  return recombineCompounds(words);\n}\n\nexport const ACRONYM_SET = new Set(['SSO', 'FGA', 'SAML', 'SCIM', 'JWT', 'HMAC', 'M2M']);\n\nexport function toPascalCase(s: string, acronyms?: Set<string>): string {\n  const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n  return splitWords(s)\n    .map((w) => {\n      const upper = w.toUpperCase();\n      if (merged.has(upper)) return upper;\n      // Special case: OAuth should stay as OAuth, not OAUTH\n      if (upper === 'OAUTH') return 'OAuth';\n      return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n    })\n    .join('');\n}\n\nexport function toCamelCase(s: string, acronyms?: Set<string>): string {\n  const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n  const words = splitWords(s);\n  if (words.length === 0) return '';\n  return words\n    .map((w, i) => {\n      if (i === 0) return w.toLowerCase();\n      const upper = w.toUpperCase();\n      if (merged.has(upper)) return upper;\n      if (upper === 'OAUTH') return 'OAuth';\n      return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n    })\n    .join('');\n}\n\nexport function toSnakeCase(s: string): string {\n  return splitWords(s)\n    .map((w) => w.toLowerCase())\n    .join('_');\n}\n\nexport function toKebabCase(s: string): string {\n  return splitWords(s)\n    .map((w) => w.toLowerCase())\n    .join('-');\n}\n\nexport function toUpperSnakeCase(s: string): string {\n  return splitWords(s)\n    .map((w) => w.toUpperCase())\n    .join('_');\n}\n\nconst BACKEND_SUFFIXES = ['Controller'];\n\nexport function stripBackendSuffixes(name: string): string {\n  for (const suffix of BACKEND_SUFFIXES) {\n    if (name.endsWith(suffix) && name.length > suffix.length) {\n      return name.slice(0, -suffix.length);\n    }\n  }\n  return name;\n}\n\nexport function stripBackendPrefixes(name: string): string {\n  return name.replace(/Userland/g, '').replace(/Controller/g, '');\n}\n\n/**\n * Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.\n * E.g. \"DirectoriesListItemState\" → \"DirectoriesState\"\n */\nexport function stripListItemMarkers(name: string): string {\n  return name\n    .replace(/ListItem/g, '')\n    .replace(/ByExternalId/g, '')\n    .replace(/ByResourceId/g, '')\n    .replace(/ForResource/g, '');\n}\n\n/** Words that look plural but must NOT be singularized. */\nconst SINGULAR_SAFE_LIST = new Set([\n  'Status',\n  'Address',\n  'Access',\n  'Process',\n  'Progress',\n  'Success',\n  'Radius',\n  'Canvas',\n  'Alias',\n  'Basis',\n  'Bus',\n  'Species',\n  'Series',\n]);\n\n/**\n * Conservative singularize for the leading PascalCase word.\n * Only applied to the first word of a PascalCase name (the resource word).\n * - `ies` → `y` (e.g. Directories → Directory)\n * - trailing `s` for words >4 chars (e.g. Organizations → Organization)\n * Safe-listed words are never singularized.\n */\nexport function singularize(word: string): string {\n  if (SINGULAR_SAFE_LIST.has(word)) return word;\n  if (word.endsWith('ies') && word.length > 4) {\n    return word.slice(0, -3) + 'y';\n  }\n  if (word.endsWith('ses') && word.length > 4) {\n    // e.g. \"Processes\" — but \"Process\" is safe-listed, this handles non-safe ones\n    return word.slice(0, -2);\n  }\n  if (word.endsWith('s') && !word.endsWith('ss') && word.length > 4) {\n    return word.slice(0, -1);\n  }\n  return word;\n}\n\n/**\n * Compose all backend name cleaning transforms in order:\n * 1. Strip backend prefixes (Userland, Controller)\n * 2. Strip backend suffixes (Dto, DTO, Controller)\n * 3. Strip ListItem / ByExternalId markers\n * 4. Singularize leading resource word\n *\n * Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`\n */\n/** Strip `.js` extensions from import/export specifiers for dedup comparison. */\nexport function normalizeJsExtension(text: string): string {\n  return text.replace(/\\.js(['\"])/g, '$1');\n}\n\nexport function cleanSchemaName(name: string): string {\n  let result = stripBackendPrefixes(stripBackendSuffixes(name));\n  result = stripListItemMarkers(result);\n\n  // Singularize the leading PascalCase word\n  const match = result.match(/^([A-Z][a-z]*)/);\n  if (match) {\n    const leadWord = match[1];\n    const singular = singularize(leadWord);\n    if (singular !== leadWord) {\n      result = singular + result.slice(leadWord.length);\n    }\n  }\n\n  return result;\n}\n","import type { Model, Field } from '../ir/types.js';\nimport { toPascalCase, stripListItemMarkers, singularize } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { buildFieldFromSchema, resolveSchemaName } from './schemas.js';\n\n/**\n * Qualify an inline model name with the parent schema name.\n * If `parentName` is provided and the field name doesn't already start with\n * the parent, the result is `${parentName}${PascalField}` with the trailing\n * word singularized (e.g., Connection + Domains → ConnectionDomain).\n */\nexport function qualifyInlineModelName(baseName: string, parentName?: string): string {\n  if (!parentName) return baseName;\n  // Strip ListItem/ByExternalId markers from parent name so inline model names\n  // are clean and match the names produced by qualifyNestedName() in responses.ts.\n  // e.g., ConnectionListItem + Domains → Connection + Domain = ConnectionDomain\n  const cleanParent = stripListItemMarkers(parentName);\n  if (baseName.startsWith(cleanParent)) return baseName;\n  // Singularize the trailing PascalCase word of the combined name.\n  // Split baseName into leading words + trailing word, singularize trailing.\n  const trailingMatch = baseName.match(/^(.*?)([A-Z][a-z]*)$/);\n  if (trailingMatch) {\n    const [, prefix, trailingWord] = trailingMatch;\n    const singular = singularize(trailingWord);\n    return `${cleanParent}${prefix}${singular}`;\n  }\n  return `${cleanParent}${baseName}`;\n}\n\n/**\n * Walk all component schemas and extract inline Model definitions for fields\n * that are objects with properties (or arrays of such objects).\n * These correspond to the ModelRef entries created by schemaToTypeRef.\n */\nexport function extractInlineModelsFromSchemas(schemas: Record<string, SchemaObject> | undefined): Model[] {\n  if (!schemas) return [];\n\n  const inlineModels: Model[] = [];\n\n  for (const [schemaName, schema] of Object.entries(schemas)) {\n    const parentName = resolveSchemaName(schemaName);\n    extractInlineModelsFromProperties(schema, inlineModels, parentName);\n  }\n\n  return inlineModels;\n}\n\nfunction extractInlineModelsFromProperties(schema: SchemaObject, results: Model[], parentName?: string): void {\n  const properties = schema.properties ?? {};\n  const allOfSchemas = schema.allOf ?? [];\n\n  for (const sub of allOfSchemas) {\n    if (sub.properties) {\n      extractInlineModelsFromProperties(sub, results, parentName);\n    }\n  }\n\n  for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n    if (!fieldSchema) continue;\n    // Direct inline object with properties (with or without explicit type: 'object')\n    if (fieldSchema.properties && (fieldSchema.type === 'object' || !fieldSchema.type)) {\n      const baseName = toPascalCase(fieldName);\n      const modelName = qualifyInlineModelName(baseName, parentName);\n      results.push(buildInlineModel(modelName, fieldSchema));\n      extractInlineModelsFromProperties(fieldSchema, results, modelName);\n    }\n\n    // Array of inline objects\n    if (fieldSchema.type === 'array' && fieldSchema.items) {\n      const items = fieldSchema.items;\n      if (items.properties && (items.type === 'object' || !items.type)) {\n        const baseName = toPascalCase(fieldName);\n        const modelName = qualifyInlineModelName(baseName, parentName);\n        results.push(buildInlineModel(modelName, items));\n        extractInlineModelsFromProperties(items, results, modelName);\n      }\n    }\n\n    // oneOf containing objects — extract every inline object variant as a\n    // model so each gets its own typed class. Variant 0 keeps the bare\n    // qualified inline name (e.g. `ApiKeyCreatedDataOwner`); subsequent\n    // variants are prefixed by their const-discriminator value via\n    // `nameOneOfVariant` (e.g. `UserApiKeyCreatedDataOwner`). When the\n    // oneOf doesn't have a const-discriminator (single object variant + null\n    // for nullable, or single object variant only), only variant 0 is\n    // extracted and the bare name pattern preserves backward compat.\n    if (fieldSchema.oneOf) {\n      const inlineObjectVariants = fieldSchema.oneOf.filter(\n        (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n      );\n      if (inlineObjectVariants.length > 0) {\n        const baseName = toPascalCase(fieldName);\n        const modelName = qualifyInlineModelName(baseName, parentName);\n        const existingNames = new Set(results.map((r) => r.name));\n        const namingDiscProp = deriveOneOfNamingDiscriminator(inlineObjectVariants);\n        const emittedNames: string[] = [];\n        for (const variant of inlineObjectVariants) {\n          const variantName = nameOneOfVariant(variant, modelName, emittedNames, namingDiscProp);\n          emittedNames.push(variantName);\n          if (!existingNames.has(variantName)) {\n            existingNames.add(variantName);\n            results.push(buildInlineModel(variantName, variant));\n            extractInlineModelsFromProperties(variant, results, variantName);\n          }\n        }\n      }\n    }\n  }\n}\n\n/** Find a single string-const-valued property shared by every variant whose\n *  values are all distinct — the implicit discriminator. Returns null when no\n *  such property exists. Mirrors `deriveConstNamingDiscriminator` in schemas.ts. */\nfunction deriveOneOfNamingDiscriminator(variants: SchemaObject[]): string | null {\n  if (variants.length < 2) return null;\n  const candidates = Object.keys(variants[0]?.properties ?? {});\n  for (const propName of candidates) {\n    const values = variants.map((v) => readConstString(v.properties?.[propName]));\n    if (values.some((v) => v === null)) continue;\n    if (new Set(values).size !== values.length) continue;\n    return propName;\n  }\n  return null;\n}\n\nfunction readConstString(prop: SchemaObject | undefined): string | null {\n  if (!prop) return null;\n  if (typeof prop.const === 'string') return prop.const;\n  if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n    return prop.enum[0];\n  }\n  return null;\n}\n\n/** Produce a per-variant model name. Variant 0 keeps the bare parent name;\n *  later variants are prefixed by the const-derived label. Mirrors\n *  `nameVariantModel` in schemas.ts. Falls back to a numeric suffix when no\n *  discriminator is available, the const value PascalCases to nothing, or\n *  the derived candidate collides with the parent or an already-emitted name. */\nfunction nameOneOfVariant(\n  variant: SchemaObject,\n  parentName: string,\n  alreadyEmitted: string[],\n  discriminatorProperty: string | null,\n): string {\n  if (alreadyEmitted.length === 0) return parentName;\n  if (discriminatorProperty) {\n    const constValue = readConstString(variant.properties?.[discriminatorProperty]);\n    if (constValue) {\n      const prefix = toPascalCase(constValue);\n      if (prefix) {\n        const candidate = parentName.startsWith(prefix) ? parentName : `${prefix}${parentName}`;\n        const collision = candidate === parentName || alreadyEmitted.includes(candidate);\n        if (!collision) return candidate;\n      }\n    }\n  }\n  return `${parentName}${alreadyEmitted.length + 1}`;\n}\n\nfunction buildInlineModel(name: string, schema: SchemaObject): Model {\n  const requiredSet = new Set(schema.required ?? []);\n  const fields: Field[] = [];\n\n  for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n    if (!fieldSchema) continue;\n    fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n  }\n\n  return { name, description: schema.description, fields };\n}\n","import type { Model, Enum, EnumValue, Field, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport {\n  toPascalCase,\n  toUpperSnakeCase,\n  cleanSchemaName,\n  singularize,\n  stripListItemMarkers,\n  splitWords,\n} from '../utils/naming.js';\n\n/**\n * Module-level transform set during extractSchemas(). Used by schemaToTypeRef()\n * to apply the same name transform to $ref model/enum references.\n */\nlet activeSchemaNameTransform: ((name: string) => string) | null = null;\n\n/**\n * Module-level set of resolved schema names whose components/schemas entry is\n * an enum (i.e. has `enum:`). Populated by extractSchemas() so schemaToTypeRef()\n * can classify a `$ref` to a top-level enum schema as `kind: 'enum'` instead of\n * `kind: 'model'`. Without this, every `$ref` was naively returned as a model\n * ref, even when the target was a shared enum like `PaginationOrder`.\n */\nlet activeEnumSchemaNames: Set<string> = new Set();\n\n/** Apply cleanSchemaName + the active transform (if any) to a raw schema name. */\nexport function resolveSchemaName(rawName: string): string {\n  let name = cleanSchemaName(toPascalCase(rawName));\n  if (activeSchemaNameTransform) name = activeSchemaNameTransform(name);\n  return name;\n}\n\nexport interface SchemaExtractionOptions {\n  schemaNameTransform?: (name: string) => string;\n}\n\nexport interface SchemaObject {\n  type?: string | string[];\n  format?: string;\n  description?: string;\n  properties?: Record<string, SchemaObject | undefined>;\n  required?: string[];\n  items?: SchemaObject;\n  enum?: (string | number)[];\n  allOf?: SchemaObject[];\n  oneOf?: SchemaObject[];\n  anyOf?: SchemaObject[];\n  discriminator?: { propertyName: string; mapping?: Record<string, string> };\n  readOnly?: boolean;\n  writeOnly?: boolean;\n  nullable?: boolean;\n  $ref?: string;\n  additionalProperties?: boolean | SchemaObject;\n  const?: unknown;\n  patternProperties?: Record<string, SchemaObject>;\n  deprecated?: boolean;\n  default?: unknown;\n  example?: unknown;\n  [key: string]: unknown;\n}\n\nexport interface ExtractedSchemas {\n  models: Model[];\n  enums: Enum[];\n}\n\nexport function extractSchemas(\n  schemas: Record<string, SchemaObject> | undefined,\n  options?: SchemaExtractionOptions,\n): ExtractedSchemas {\n  const enums: Enum[] = [];\n\n  if (!schemas) return { models: [], enums };\n\n  // Build collision-safe transform if provided\n  if (options?.schemaNameTransform) {\n    const transform = options.schemaNameTransform;\n    const rawNames = Object.keys(schemas);\n    const cleanedNames = rawNames.map((n) => cleanSchemaName(toPascalCase(n)));\n    const transformedToOriginals = new Map<string, string[]>();\n    for (const cleaned of cleanedNames) {\n      const transformed = transform(cleaned);\n      if (!transformedToOriginals.has(transformed)) transformedToOriginals.set(transformed, []);\n      transformedToOriginals.get(transformed)!.push(cleaned);\n    }\n    const unsafeToTransform = new Set<string>();\n    for (const [, originals] of transformedToOriginals) {\n      if (originals.length > 1) {\n        for (const n of originals) unsafeToTransform.add(n);\n      }\n    }\n    activeSchemaNameTransform = (name: string) => (unsafeToTransform.has(name) ? name : transform(name));\n  } else {\n    activeSchemaNameTransform = null;\n  }\n\n  // Pre-compute the set of resolved names whose component schema is an enum so\n  // schemaToTypeRef() can classify `$ref` targets correctly. Built in a separate\n  // pass because the per-schema loop mutates models/enums and we want this map\n  // available before any TypeRef is resolved (operations + nested fields both\n  // call schemaToTypeRef during extraction).\n  activeEnumSchemaNames = new Set();\n  for (const [name, schema] of Object.entries(schemas)) {\n    if (schema.enum) activeEnumSchemaNames.add(resolveSchemaName(name));\n  }\n\n  const modelsByCleanName = new Map<string, Model>();\n\n  for (const [name, schema] of Object.entries(schemas)) {\n    const pascalName = resolveSchemaName(name);\n\n    if (schema.enum) {\n      enums.push(extractEnum(pascalName, schema));\n    } else {\n      const model = extractModel(pascalName, schema, schemas);\n      const existing = modelsByCleanName.get(pascalName);\n      if (existing) {\n        // Keep the model with more fields when names collide after cleaning\n        if (model.fields.length > existing.fields.length) {\n          modelsByCleanName.set(pascalName, model);\n        }\n      } else {\n        modelsByCleanName.set(pascalName, model);\n      }\n\n      for (const inlineModel of extractDiscriminatedAllOfVariantModels(schema, pascalName)) {\n        const existingInline = modelsByCleanName.get(inlineModel.name);\n        if (existingInline) {\n          if (inlineModel.fields.length > existingInline.fields.length) {\n            modelsByCleanName.set(inlineModel.name, inlineModel);\n          }\n        } else {\n          modelsByCleanName.set(inlineModel.name, inlineModel);\n        }\n      }\n    }\n  }\n\n  const models = [...modelsByCleanName.values()];\n\n  // Collect inline models from nested object/oneOf properties\n  // that schemaToTypeRef created model refs for but weren't extracted\n  const modelNames = new Set(models.map((m) => m.name));\n  const inlineQueue: Model[] = [...models];\n  while (inlineQueue.length > 0) {\n    const model = inlineQueue.pop()!;\n    for (const field of model.fields) {\n      collectNestedInlineModels(field.type, field.name, model.name, schemas ?? {}, models, modelNames, inlineQueue);\n    }\n  }\n\n  // Collect inline enums from model fields\n  for (const model of models) {\n    collectInlineEnums(model.fields, enums);\n  }\n\n  // NOTE: activeSchemaNameTransform is intentionally NOT cleared here.\n  // extractOperations() calls schemaToTypeRef() for $ref resolution and\n  // needs the same transform active. parseSpec() calls clearSchemaNameTransform()\n  // after all extraction is complete.\n  return { models, enums };\n}\n\n/** Clear the module-level schemaNameTransform. Called by parseSpec() after all extraction phases. */\nexport function clearSchemaNameTransform(): void {\n  activeSchemaNameTransform = null;\n  activeEnumSchemaNames = new Set();\n}\n\n/**\n * Walk a single TypeRef and extract inline enum refs as top-level enum definitions.\n * Shared by both schemas.ts (field-level) and parse.ts (model-level) collection passes.\n */\nexport function collectInlineEnumFromRef(ref: TypeRef, enums: Enum[], seen: Set<string>): void {\n  walkTypeRef(ref, {\n    enum: (r) => {\n      if (r.values && !seen.has(r.name)) {\n        seen.add(r.name);\n        enums.push({\n          name: r.name,\n          values: r.values.map((v) => ({\n            name: toUpperSnakeCase(String(v)),\n            value: v,\n            description: undefined,\n          })),\n        });\n      }\n    },\n  });\n}\n\n/**\n * Walk model fields and extract inline enum refs as top-level enum definitions.\n * This ensures type alias files are generated for inline enums.\n */\nfunction collectInlineEnums(fields: Field[], enums: Enum[]): void {\n  const seen = new Set(enums.map((e) => e.name));\n  for (const field of fields) {\n    collectInlineEnumFromRef(field.type, enums, seen);\n  }\n}\n\n/**\n * Walk a TypeRef tree and extract inline models for any model refs that point\n * to schemas with inline object properties (not in components/schemas).\n * This handles nested objects like `totp: { oneOf: [{ type: object, properties: {...} }] }`\n * that schemaToTypeRef turns into model refs but aren't extracted from components.\n */\nfunction collectNestedInlineModels(\n  ref: TypeRef,\n  fieldName: string,\n  parentModelName: string,\n  schemas: Record<string, SchemaObject>,\n  models: Model[],\n  modelNames: Set<string>,\n  queue: Model[],\n): void {\n  walkTypeRef(ref, {\n    model: (modelRef) => {\n      if (modelNames.has(modelRef.name)) return; // already extracted\n      // Check if this model name corresponds to a component schema\n      // by checking all possible original names that would map to this PascalCase name\n      const isComponent = Object.keys(schemas).some((k) => resolveSchemaName(k) === modelRef.name);\n      if (isComponent) return; // will be extracted from components\n\n      // This is a reference to a nested inline model that wasn't extracted.\n      // Look up the field schema in the parent model's component schema to extract it.\n      const parentSchema = findSchemaByName(parentModelName, schemas);\n      if (!parentSchema) return;\n\n      const fieldSchema = findNestedFieldSchema(fieldName, parentSchema, schemas);\n      if (!fieldSchema) return;\n\n      // Extract inline models from the field schema\n      const extracted = extractNestedSchema(modelRef.name, fieldSchema);\n      for (const m of extracted) {\n        if (!modelNames.has(m.name)) {\n          models.push(m);\n          modelNames.add(m.name);\n          queue.push(m); // re-scan for deeper nesting\n        }\n      }\n    },\n  });\n}\n\n/** Find a component schema by PascalCase name. */\nfunction findSchemaByName(pascalName: string, schemas: Record<string, SchemaObject>): SchemaObject | null {\n  for (const [k, v] of Object.entries(schemas)) {\n    if (resolveSchemaName(k) === pascalName) return v;\n  }\n  return null;\n}\n\n/** Walk into a schema to find a field's sub-schema, resolving allOf and oneOf/anyOf. */\nfunction findNestedFieldSchema(\n  fieldName: string,\n  parentSchema: SchemaObject,\n  schemas: Record<string, SchemaObject>,\n): SchemaObject | null {\n  if (parentSchema.properties?.[fieldName]) {\n    return parentSchema.properties[fieldName]!;\n  }\n  if (parentSchema.allOf) {\n    for (const sub of parentSchema.allOf) {\n      let resolved = sub;\n      if (sub.$ref) {\n        const segments = sub.$ref.split('/');\n        const refName = segments[segments.length - 1];\n        if (refName && schemas[refName]) resolved = schemas[refName];\n      }\n      if (resolved.properties?.[fieldName]) {\n        return resolved.properties[fieldName]!;\n      }\n    }\n  }\n  // Also check inside oneOf/anyOf variants (pure oneOf schemas flatten variant\n  // properties into the model, so the field may live inside a variant).\n  for (const variant of [...(parentSchema.oneOf ?? []), ...(parentSchema.anyOf ?? [])]) {\n    let resolved = variant;\n    if (variant.$ref) {\n      const segments = variant.$ref.split('/');\n      const refName = segments[segments.length - 1];\n      if (refName && schemas[refName]) resolved = schemas[refName];\n    }\n    if (resolved.properties?.[fieldName]) {\n      return resolved.properties[fieldName]!;\n    }\n  }\n  return null;\n}\n\n/** Extract a model (and nested models) from an inline field schema. */\nfunction extractNestedSchema(name: string, schema: SchemaObject): Model[] {\n  // Handle oneOf: extract each object variant as its own model\n  if (schema.oneOf) {\n    const models: Model[] = [];\n\n    // Collect the inline object variants up front. When every variant pins\n    // the same property to a const value, we can derive meaningful names\n    // from the const (e.g. `UserApiKeyOwner` instead of `ApiKeyOwner2`)\n    // — much friendlier for SDK consumers than numeric suffixes.\n    const inlineObjectVariants: SchemaObject[] = schema.oneOf.filter(\n      (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n    );\n    const constNamingDiscriminator = deriveConstNamingDiscriminator(inlineObjectVariants);\n\n    for (const variant of schema.oneOf) {\n      if (variant.$ref) continue;\n      if (variant.properties && (variant.type === 'object' || !variant.type)) {\n        const requiredSet = new Set(variant.required ?? []);\n        const fields: Field[] = [];\n        for (const [fn, fs] of Object.entries(variant.properties)) {\n          if (!fs) continue;\n          fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n        }\n        const variantName = nameVariantModel(variant, name, models, constNamingDiscriminator);\n        models.push({ name: variantName, description: variant.description, fields });\n      }\n    }\n    return models;\n  }\n\n  // Handle direct object\n  if (schema.properties && (schema.type === 'object' || !schema.type)) {\n    const requiredSet = new Set(schema.required ?? []);\n    const fields: Field[] = [];\n    for (const [fn, fs] of Object.entries(schema.properties)) {\n      if (!fs) continue;\n      fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n    }\n    return [{ name, description: schema.description, fields }];\n  }\n\n  // Handle array with inline items\n  if (schema.type === 'array' && schema.items?.properties) {\n    const requiredSet = new Set(schema.items.required ?? []);\n    const fields: Field[] = [];\n    for (const [fn, fs] of Object.entries(schema.items.properties)) {\n      if (!fs) continue;\n      fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n    }\n    return [{ name, description: schema.items.description, fields }];\n  }\n\n  return [];\n}\n\n/**\n * Derive a meaningful name for a oneOf object variant past the first,\n * falling back to the numeric-suffix scheme (`Foo2`, `Foo3`) when no\n * better signal is available. The \"better signal\" is a const-valued\n * discriminator property that distinguishes one variant from the others.\n *\n * For a schema like `ApiKey.owner` whose oneOf has two variants — one\n * with `type: { const: \"organization\" }` and one with `type: { const:\n * \"user\" }` — this returns `ApiKeyOwner` for the first variant (the\n * baseline name that the union TypeRef will reference, so consumer-\n * visible typed fields stay backward-compatible) and `UserApiKeyOwner`\n * for the second instead of `ApiKeyOwner2`. SDK consumers reading the\n * generated types can tell the variants apart at a glance.\n *\n * The first variant always keeps the bare parent name because\n * `schemaToTypeRef` builds union variants whose model refs collapse to\n * `qualifyInlineModelName(field, parent)` — so the first model name\n * must match for the union's degenerate-collapse to land on a valid\n * type. Renaming variant 0 would orphan it.\n *\n * Falls back to numeric suffix when:\n *   - The variant has no discriminator property (no shared const\n *     property across all object variants), OR\n *   - The const value PascalCases to an empty/whitespace name, OR\n *   - The derived name collides with the parent name or an already-\n *     emitted variant name (numeric keeps uniqueness).\n */\nfunction nameVariantModel(\n  variant: SchemaObject,\n  parentName: string,\n  alreadyEmitted: Model[],\n  discriminator: { property: string } | null,\n): string {\n  // Variant 0 keeps the bare parent name so the union TypeRef's degenerate\n  // collapse target exists in the model registry.\n  if (alreadyEmitted.length === 0) return parentName;\n\n  if (discriminator) {\n    const constValue = getConstPropertyValue(variant, discriminator.property);\n    if (constValue) {\n      const prefix = toPascalCase(constValue);\n      if (prefix) {\n        const candidate = parentName.startsWith(prefix) ? parentName : `${prefix}${parentName}`;\n        const collision = candidate === parentName || alreadyEmitted.some((m) => m.name === candidate);\n        if (!collision) return candidate;\n      }\n    }\n  }\n  return `${parentName}${alreadyEmitted.length + 1}`;\n}\n\n/**\n * Returns a discriminator descriptor when every inline object variant in a\n * oneOf has a string-const value on the same property — the signature of a\n * discriminated union without an explicit `discriminator:` keyword. Used by\n * `nameVariantModel` to derive variant names from the const values.\n *\n * Distinct from `detectConstPropertyDiscriminator` (which requires every\n * variant to carry a `$ref` or `title` so a name mapping can be built):\n * this pass operates on inline anonymous variants, where naming is exactly\n * what we're trying to derive.\n */\nfunction deriveConstNamingDiscriminator(variants: SchemaObject[]): { property: string } | null {\n  if (variants.length < 2) return null;\n  const candidates = Object.keys(variants[0]?.properties ?? {});\n  for (const propName of candidates) {\n    const values = variants.map((v) => getConstPropertyValue(v, propName));\n    if (values.some((v) => v === null)) continue;\n    if (new Set(values).size !== values.length) continue; // collisions = no signal\n    return { property: propName };\n  }\n  return null;\n}\n\n/** Build a single Field from a schema property entry. Shared across all extraction sites. */\nexport function buildFieldFromSchema(\n  fieldName: string,\n  fieldSchema: SchemaObject,\n  contextName: string,\n  requiredSet: Set<string>,\n): Field {\n  return {\n    name: fieldName,\n    type: schemaToTypeRef(fieldSchema, fieldName, contextName),\n    required: requiredSet.has(fieldName),\n    description: fieldSchema.description,\n    readOnly: fieldSchema.readOnly || undefined,\n    writeOnly: fieldSchema.writeOnly || undefined,\n    deprecated: fieldSchema.deprecated || undefined,\n    default: fieldSchema.default,\n    example: fieldSchema.example,\n  };\n}\n\n/**\n * If every non-null oneOf/anyOf variant is a string-valued const, return the\n * list of those const values so the union can collapse into a single enum.\n * Returns null when any variant isn't a pure string-const (model ref,\n * number const, nullable, etc.).\n */\nfunction collectLiteralStringConsts(variants: SchemaObject[]): string[] | null {\n  if (variants.length === 0) return null;\n  const values: string[] = [];\n  for (const v of variants) {\n    // A single-element enum is semantically identical to const.\n    if (typeof v.const === 'string') {\n      values.push(v.const);\n      continue;\n    }\n    if (Array.isArray(v.enum) && v.enum.length === 1 && typeof v.enum[0] === 'string') {\n      values.push(v.enum[0]);\n      continue;\n    }\n    return null;\n  }\n  return values;\n}\n\n/** Build an EnumRef the same way the regular enum path does for naming. */\nfunction buildSyntheticEnumRef(\n  values: string[],\n  contextName: string | undefined,\n  parentModelName: string | undefined,\n): TypeRef {\n  const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n  const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n  const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n  // Run the same `schemaNameTransform` we apply to component-schema names so\n  // a project-level rename map (e.g. `RadarAction` → `RadarListAction` in\n  // `oagen.config.ts`) catches inline parameter enums too.\n  const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n  return { kind: 'enum', name: finalName, values };\n}\n\n/**\n * Detect an implicit discriminator on an oneOf where every variant is an\n * object schema that pins the same property to a const value. Returns\n * { property, mapping } so the IR can represent the union as discriminated\n * without needing an explicit `discriminator:` key in the spec.\n *\n * Both shapes are supported:\n *   { properties: { event: { const: \"x\" } }, required: [\"event\"] }\n *   { properties: { event: { type: \"string\", enum: [\"x\"] } } }\n *\n * Returns null when any variant doesn't fit the pattern or when variants\n * disagree on which property carries the discriminator.\n */\nfunction detectConstPropertyDiscriminator(\n  variants: SchemaObject[],\n): { property: string; mapping: Record<string, string> } | null {\n  if (variants.length < 2) return null;\n\n  // Find properties whose const value is present on every variant.\n  let candidateProperty: string | null = null;\n  const candidates = Object.keys(variants[0]?.properties ?? {});\n  for (const propName of candidates) {\n    if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) {\n      candidateProperty = propName;\n      break;\n    }\n  }\n\n  if (!candidateProperty) return null;\n\n  const mapping: Record<string, string> = {};\n  for (const v of variants) {\n    const value = getConstPropertyValue(v, candidateProperty);\n    if (value === null) return null;\n    // Require a $ref or title so we have a concrete model name to map to.\n    const variantName = resolveVariantModelName(v);\n    if (!variantName) return null;\n    mapping[value] = variantName;\n  }\n\n  return { property: candidateProperty, mapping };\n}\n\nfunction getConstPropertyValue(schema: SchemaObject, property: string): string | null {\n  const prop = schema.properties?.[property];\n  if (!prop) return null;\n  if (typeof prop.const === 'string') return prop.const;\n  if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n    return prop.enum[0];\n  }\n  return null;\n}\n\nfunction resolveVariantModelName(schema: SchemaObject): string | null {\n  if (schema.$ref) {\n    return resolveSchemaName(schema.$ref.replace(/^#\\/components\\/schemas\\//, ''));\n  }\n  const title = typeof schema['title'] === 'string' ? (schema['title'] as string) : null;\n  if (title) return resolveSchemaName(title);\n  return null;\n}\n\n/** Look up the discriminator's mapped variant name for an inline object\n *  variant by reading its const-valued discriminator property. Returns null\n *  when the variant doesn't pin the property to a string const, or when\n *  the value isn't in the mapping. */\nfunction mapVariantToDiscriminatorEntry(\n  variant: SchemaObject,\n  discriminator: { property: string; mapping: Record<string, string> },\n): string | null {\n  const value = getConstPropertyValue(variant, discriminator.property);\n  if (value === null) return null;\n  return discriminator.mapping[value] ?? null;\n}\n\n/**\n * Derive a discriminator value → variant model name mapping for an inline-\n * variant `oneOf` whose explicit `discriminator:` has no `mapping:` clause.\n *\n * Each variant model name is reproduced via `nameVariantModel` so it matches\n * what `extractNestedSchema` registered when it walked the same `oneOf` to\n * pull variants out as named models. Variant 0 keeps the bare parent name\n * (e.g. `ApiKeyOwner`); subsequent variants get a const-derived prefix\n * (e.g. `UserApiKeyOwner` for the `type: const: user` variant).\n *\n * The \"parent name\" used here mirrors the one `collectNestedInlineModels`\n * passes to `extractNestedSchema`: it's the qualified inline model name\n * built from `contextName` (the field name) plus `parentModelName` (the\n * containing model). Returns null when any non-object variant is present\n * or when a variant lacks a const value on the discriminator property.\n */\nfunction deriveInlineVariantMapping(\n  variants: SchemaObject[],\n  discriminatorProperty: string,\n  contextName: string | undefined,\n  parentModelName: string | undefined,\n): Record<string, string> | null {\n  if (variants.length === 0 || !contextName) return null;\n  const inlineObjectVariants = variants.filter((v) => !v.$ref && v.properties && (v.type === 'object' || !v.type));\n  if (inlineObjectVariants.length !== variants.length) return null;\n\n  const baseInlineName = qualifyInlineModelName(toPascalCase(contextName), parentModelName);\n  const namingDiscriminator = { property: discriminatorProperty };\n  const mapping: Record<string, string> = {};\n  const emittedSoFar: Model[] = [];\n  for (const variant of inlineObjectVariants) {\n    const constValue = getConstPropertyValue(variant, discriminatorProperty);\n    if (constValue === null) return null;\n    const variantName = nameVariantModel(variant, baseInlineName, emittedSoFar, namingDiscriminator);\n    mapping[constValue] = variantName;\n    emittedSoFar.push({ name: variantName, fields: [] });\n  }\n  return mapping;\n}\n\nfunction extractEnum(name: string, schema: SchemaObject): Enum {\n  const values: EnumValue[] = (schema.enum ?? []).map((v) => ({\n    name: toUpperSnakeCase(String(v)),\n    value: typeof v === 'number' ? v : String(v),\n    description: undefined,\n  }));\n\n  const rawDefault = schema.default;\n  const def =\n    rawDefault !== undefined && values.some((v) => v.value === rawDefault)\n      ? (rawDefault as string | number)\n      : undefined;\n\n  return { name, values, default: def };\n}\nfunction extractModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n  if (schema.allOf) {\n    return extractAllOfModel(name, schema, schemas);\n  }\n\n  const requiredSet = new Set(schema.required ?? []);\n  const fields: Field[] = [];\n\n  for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n    if (!fieldSchema) continue;\n    fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n  }\n\n  // Pure oneOf/anyOf schemas (no allOf, no properties): merge variant fields\n  // as optional. This handles schemas like UpdateOrganizationMembership which\n  // is a oneOf with mutually exclusive field groups (role_slug vs role_slugs).\n  if (fields.length === 0 && (schema.oneOf || schema.anyOf)) {\n    const variants = schema.oneOf ?? schema.anyOf ?? [];\n    const emptyRequired = new Set<string>();\n    const seenFieldNames = new Set<string>();\n    for (const variant of variants) {\n      if (!variant.properties) continue;\n      for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n        if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n        seenFieldNames.add(fieldName);\n        fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n      }\n    }\n  }\n\n  // When additionalProperties is an object schema alongside properties,\n  // surface it as a catch-all map field so emitters can generate Map<string, T>.\n  if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && schema.properties) {\n    const apKeys = Object.keys(schema.additionalProperties);\n    if (apKeys.length > 0) {\n      const valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, 'additionalProperties', name);\n      fields.push({\n        name: 'additionalProperties',\n        type: { kind: 'map', valueType },\n        required: false,\n        description: 'Additional properties not captured by named fields',\n      });\n    }\n  }\n\n  return { name, description: schema.description, fields };\n}\n\nfunction extractAllOfModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n  const fields: Field[] = [];\n  const requiredSet = new Set<string>();\n  let resultDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n\n  for (const subSchema of schema.allOf ?? []) {\n    // Resolve $ref sub-schemas by looking up the referenced component schema\n    let resolved = subSchema;\n    if (subSchema.$ref && schemas) {\n      const segments = subSchema.$ref.split('/');\n      const refName = segments[segments.length - 1];\n      if (refName && schemas[refName]) {\n        resolved = schemas[refName];\n      }\n    }\n\n    // If the resolved schema is itself an allOf, recursively extract its fields\n    if (resolved.allOf) {\n      const nested = extractAllOfModel(name, resolved, schemas);\n      for (const f of nested.fields) {\n        fields.push({ ...f, required: false }); // will be re-set below\n        if (f.required) requiredSet.add(f.name);\n      }\n    } else if (resolved.oneOf || resolved.anyOf) {\n      const variants = resolved.oneOf ?? resolved.anyOf ?? [];\n      // Detect discriminated union: every variant pins the same property to a\n      // distinct const value (e.g. EventSchema where each variant has event: const).\n      // When detected, store the discriminator instead of flattening variant fields —\n      // the base allOf schema already captures the common fields.\n      const discriminatorInfo = detectAllOfVariantDiscriminator(variants, name);\n      if (discriminatorInfo) {\n        resultDiscriminator = discriminatorInfo;\n      } else {\n        // Flatten oneOf/anyOf variant fields into the parent model as optional\n        // fields. This handles the common allOf + oneOf pattern where the spec\n        // uses mutually exclusive variant groups (e.g. password vs password_hash).\n        const emptyRequired = new Set<string>();\n        const seenFieldNames = new Set(fields.map((f) => f.name));\n        for (const variant of variants) {\n          if (!variant.properties) continue;\n          for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n            if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n            seenFieldNames.add(fieldName);\n            fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n          }\n        }\n        // Do NOT add variant-level required to the requiredSet — these fields\n        // are optional at the parent level because they come from mutually\n        // exclusive branches.\n      }\n    } else {\n      if (resolved.required) {\n        for (const r of resolved.required) requiredSet.add(r);\n      }\n      if (resolved.properties) {\n        // Use an empty requiredSet — required flags are set in the final pass below\n        const emptyRequired = new Set<string>();\n        for (const [fieldName, fieldSchema] of Object.entries(resolved.properties)) {\n          if (!fieldSchema) continue;\n          fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, emptyRequired));\n        }\n      }\n    }\n  }\n\n  // Also collect required from the outer schema\n  if (schema.required) {\n    for (const r of schema.required) requiredSet.add(r);\n  }\n\n  // Set required flags\n  for (const f of fields) {\n    f.required = requiredSet.has(f.name);\n  }\n\n  return {\n    name,\n    description: schema.description,\n    fields,\n    ...(resultDiscriminator ? { discriminator: resultDiscriminator } : {}),\n  };\n}\n\n/**\n * Walk through `allOf` wrappers to collect the effective top-level properties\n * of a schema. Stops at `oneOf` / `anyOf` boundaries — those are different\n * variant axes, not part of the same flat object.\n *\n * Used by `detectAllOfVariantDiscriminator` and `deriveDiscriminatedVariantName`\n * so a oneOf variant of the form `{ allOf: [{ properties: { … } }, { oneOf: […] }] }`\n * still surfaces its top-level `properties` (in particular its discriminator\n * `const`) instead of being treated as having none.\n */\nfunction getEffectiveProperties(schema: SchemaObject): Record<string, SchemaObject> {\n  const props: Record<string, SchemaObject> = {};\n  const visit = (s: SchemaObject): void => {\n    if (s.properties) {\n      for (const [k, v] of Object.entries(s.properties)) {\n        if (!(k in props) && v) props[k] = v;\n      }\n    }\n    if (s.allOf) {\n      for (const sub of s.allOf) visit(sub);\n    }\n    // Do NOT walk into oneOf / anyOf — those are alternatives, not\n    // simultaneously-present properties.\n  };\n  visit(schema);\n  return props;\n}\n\nfunction getEffectiveConstPropertyValue(schema: SchemaObject, property: string): string | null {\n  const direct = getConstPropertyValue(schema, property);\n  if (direct !== null) return direct;\n  const effective = getEffectiveProperties(schema)[property];\n  if (!effective) return null;\n  if (typeof effective.const === 'string') return effective.const;\n  if (Array.isArray(effective.enum) && effective.enum.length === 1 && typeof effective.enum[0] === 'string') {\n    return effective.enum[0];\n  }\n  return null;\n}\n\n/**\n * Detect an implicit discriminator on an allOf+oneOf where every variant is an\n * object that pins the same property to a distinct const value. Unlike\n * detectConstPropertyDiscriminator (which requires $ref or title for variant\n * model names), this version derives model names from the const value itself\n * using deriveDiscriminatedVariantName — matching how extractDiscriminatedAllOfVariantModels\n * names those models.\n *\n * Walks through allOf wrappers on each variant so a oneOf branch like\n *   { allOf: [{ properties: { type: { const: 'oauth' } } }, { oneOf: […] }] }\n * still surfaces `type` as a candidate discriminator.\n *\n * Returns null when no discriminator can be reliably detected.\n */\nfunction detectAllOfVariantDiscriminator(\n  variants: SchemaObject[],\n  fallbackName: string,\n): { property: string; mapping: Record<string, string> } | null {\n  if (variants.length < 2) return null;\n\n  // Find a property whose const value is present on every variant\n  // (looking through allOf wrappers on each variant).\n  const firstProps = getEffectiveProperties(variants[0] ?? {});\n  let candidateProperty: string | null = null;\n  for (const propName of Object.keys(firstProps)) {\n    if (variants.every((v) => getEffectiveConstPropertyValue(v, propName) !== null)) {\n      candidateProperty = propName;\n      break;\n    }\n  }\n  if (!candidateProperty) return null;\n\n  const mapping: Record<string, string> = {};\n  const seenModelNames = new Set<string>();\n  for (const v of variants) {\n    const value = getEffectiveConstPropertyValue(v, candidateProperty);\n    if (value === null) return null;\n    const modelName = deriveDiscriminatedVariantName(v, fallbackName);\n    // If two variants map to the same model name, the discriminator is ambiguous\n    if (seenModelNames.has(modelName)) return null;\n    seenModelNames.add(modelName);\n    mapping[value] = modelName;\n  }\n\n  return { property: candidateProperty, mapping };\n}\n\nfunction extractDiscriminatedAllOfVariantModels(schema: SchemaObject, fallbackName: string): Model[] {\n  const models: Model[] = [];\n  const seenNames = new Set<string>();\n\n  // Collect base-object properties + required from the allOf wrapper so each\n  // variant can be emitted as a complete, self-contained type. Schemas like\n  // `EventSchema` repeat the base fields inside every variant in the spec\n  // (so this merge is a no-op there), but `ConnectApplication`'s OAuth /\n  // M2M variants don't — without this, dispatcher consumers would get a\n  // variant that's missing the shared `id` / `name` / `object` etc.\n  const baseProperties: Record<string, SchemaObject> = {};\n  const baseRequired = new Set<string>();\n  for (const subSchema of schema.allOf ?? []) {\n    if (subSchema.oneOf) continue; // the variant axis, handled below\n    const flat = subSchema.allOf ? flattenVariantForExtraction(subSchema) : subSchema;\n    if (flat.properties) {\n      for (const [k, v] of Object.entries(flat.properties)) {\n        if (!(k in baseProperties) && v) baseProperties[k] = v;\n      }\n    }\n    if (flat.required) for (const r of flat.required) baseRequired.add(r);\n  }\n\n  for (const subSchema of schema.allOf ?? []) {\n    for (const variant of subSchema.oneOf ?? []) {\n      // Flatten any allOf wrapper on the variant (e.g. `ConnectApplication`'s\n      // OAuth branch is `allOf: [{ properties: {…} }, { oneOf: [first-party\n      // sub-variants] }]`). The flattened object has merged properties and\n      // an inlined sub-variant `oneOf` so `extractInlineModelDeep` can pull\n      // out a complete variant model.\n      const flat = flattenVariantForExtraction(variant);\n      if (!flat.properties || (flat.type !== undefined && flat.type !== 'object')) continue;\n\n      // Merge base fields into the variant. Variant-specific properties win\n      // on name collisions because the spec may pin a base field to a more\n      // specific shape inside a variant.\n      const mergedProperties: Record<string, SchemaObject> = { ...baseProperties };\n      for (const [k, v] of Object.entries(flat.properties)) {\n        if (v) mergedProperties[k] = v;\n      }\n      const mergedRequired = new Set<string>([...baseRequired, ...(flat.required ?? [])]);\n      const merged: SchemaObject = {\n        type: 'object',\n        properties: mergedProperties,\n        required: [...mergedRequired],\n      };\n\n      const variantName = deriveDiscriminatedVariantName(variant, fallbackName);\n      for (const model of extractInlineModelDeep(variantName, merged)) {\n        if (seenNames.has(model.name)) continue;\n        seenNames.add(model.name);\n        models.push(model);\n      }\n    }\n  }\n\n  return models;\n}\n\n/**\n * Flatten a oneOf variant schema into a single object-shaped schema for\n * variant-model extraction. Recursively merges `allOf` members and folds\n * any nested `oneOf` into an inline-oneOf field group whose properties are\n * the union across sub-branches (required only when present in every\n * sub-branch). Returns the schema unchanged when no flattening is needed.\n */\nfunction flattenVariantForExtraction(variant: SchemaObject): SchemaObject {\n  if (!variant.allOf) return variant;\n\n  const mergedProperties: Record<string, SchemaObject> = {};\n  const mergedRequired = new Set<string>();\n  const nestedOneOfs: SchemaObject[][] = [];\n\n  const collect = (s: SchemaObject): void => {\n    if (s.properties) {\n      for (const [k, v] of Object.entries(s.properties)) {\n        if (!(k in mergedProperties) && v) mergedProperties[k] = v;\n      }\n    }\n    if (s.required) {\n      for (const r of s.required) mergedRequired.add(r);\n    }\n    if (s.allOf) {\n      for (const sub of s.allOf) collect(sub);\n    }\n    if (s.oneOf) nestedOneOfs.push(s.oneOf);\n  };\n  collect(variant);\n\n  // Fold each nested oneOf into the merged shape: any field appearing in any\n  // sub-branch is included as optional (or required iff present-and-required\n  // in every sub-branch). Conflicting literal types widen to their primitive\n  // base. This handles the `is_first_party: true | false` widening on the\n  // OAuth variant's first-party sub-oneOf.\n  for (const branches of nestedOneOfs) {\n    const flatBranches = branches.map(flattenVariantForExtraction);\n    const branchKeys = new Set<string>();\n    for (const b of flatBranches) {\n      for (const k of Object.keys(b.properties ?? {})) branchKeys.add(k);\n    }\n    for (const key of branchKeys) {\n      const schemas: SchemaObject[] = [];\n      for (const b of flatBranches) {\n        const s = b.properties?.[key];\n        if (s) schemas.push(s);\n      }\n      const merged = mergeBranchPropertySchemas(schemas);\n      if (!(key in mergedProperties)) mergedProperties[key] = merged;\n      const inAllBranches = flatBranches.every((b) => b.properties && key in b.properties);\n      const requiredInAll = inAllBranches && flatBranches.every((b) => (b.required ?? []).includes(key));\n      if (requiredInAll) mergedRequired.add(key);\n    }\n  }\n\n  return {\n    type: 'object',\n    properties: mergedProperties,\n    required: [...mergedRequired],\n  };\n}\n\n/**\n * Merge same-named property schemas from across sub-variants. If every\n * occurrence is a boolean const, widen to plain boolean; if every occurrence\n * is a distinct string const, widen to plain string. Otherwise return the\n * first occurrence — emitters that build their own widened types (e.g. the\n * Node discriminated-models module) re-derive from the raw spec.\n */\nfunction mergeBranchPropertySchemas(schemas: SchemaObject[]): SchemaObject {\n  if (schemas.length === 0) return {};\n  if (schemas.length === 1) return schemas[0];\n\n  const allBoolConst = schemas.every((s) => s.type === 'boolean' && typeof s.const === 'boolean');\n  if (allBoolConst) {\n    return { type: 'boolean', description: schemas[0].description };\n  }\n  const allStringConst = schemas.every((s) => s.type === 'string' && typeof s.const === 'string');\n  if (allStringConst) {\n    const values = schemas.map((s) => s.const as string);\n    if (new Set(values).size === 1) return schemas[0];\n    return { type: 'string', description: schemas[0].description };\n  }\n  return schemas[0];\n}\n\nfunction deriveDiscriminatedVariantName(schema: SchemaObject, fallbackName: string): string {\n  // Walk through allOf wrappers so a variant of the form\n  // `{ allOf: [{ properties: { type: const: 'oauth' } }, { oneOf: […] }] }`\n  // still surfaces its discriminator const value for naming.\n  const effective = getEffectiveProperties(schema);\n  if (Object.keys(effective).length === 0) return fallbackName;\n\n  const pickConst = (name: string): string | null => {\n    const field = effective[name];\n    if (!field) return null;\n    if (typeof field.const === 'string') return field.const;\n    if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n      return field.enum[0];\n    }\n    return null;\n  };\n\n  let constValue: string | null = null;\n  for (const preferred of ['event', 'type', 'object']) {\n    constValue = pickConst(preferred);\n    if (constValue) break;\n  }\n  if (constValue === null) {\n    for (const name of Object.keys(effective)) {\n      constValue = pickConst(name);\n      if (constValue) break;\n    }\n  }\n  if (constValue === null) return fallbackName;\n\n  const pascal = toPascalCase(constValue);\n  if (!pascal) return fallbackName;\n\n  // A single-word const like `oauth` or `m2m` is too generic to stand alone\n  // as a top-level model name — it would collide with unrelated schemas. Pair\n  // it with the parent name so the variant resolves to e.g. `ConnectApplicationOAuth`\n  // / `ConnectApplicationM2M`. Multi-word consts like `action.authentication.denied`\n  // are already specific enough on their own, matching the established\n  // EventSchema variant naming.\n  const wordCount = splitWords(constValue).length;\n  if (wordCount >= 2) return pascal;\n  if (pascal === fallbackName) return pascal;\n  if (fallbackName.startsWith(pascal)) return fallbackName;\n  if (pascal.endsWith(fallbackName)) return pascal;\n  return `${fallbackName}${pascal}`;\n}\n\nfunction extractInlineModelDeep(name: string, schema: SchemaObject): Model[] {\n  const requiredSet = new Set(schema.required ?? []);\n  const fields: Field[] = [];\n  const properties = schema.properties ?? {};\n  const nestedModels: Model[] = [];\n\n  for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n    if (!fieldSchema) continue;\n    fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n    if (fieldSchema.type === 'object' && fieldSchema.properties) {\n      nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema));\n    }\n\n    if (fieldSchema.type === 'array' && fieldSchema.items?.properties) {\n      nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema.items));\n    }\n\n    if (fieldSchema.allOf) {\n      const mergedProperties: Record<string, SchemaObject | undefined> = {};\n      const mergedRequired: string[] = [];\n      for (const sub of fieldSchema.allOf) {\n        if (sub.properties) Object.assign(mergedProperties, sub.properties);\n        if (sub.required) mergedRequired.push(...sub.required);\n      }\n      if (Object.keys(mergedProperties).length > 0) {\n        nestedModels.push(\n          ...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), {\n            type: 'object',\n            properties: mergedProperties,\n            required: mergedRequired,\n          }),\n        );\n      }\n    }\n\n    if (fieldSchema.oneOf) {\n      const inlineObjectVariants = fieldSchema.oneOf.filter(\n        (v) => !v.$ref && v.properties && (v.type === 'object' || !v.type),\n      );\n      if (inlineObjectVariants.length > 0) {\n        const baseQualified = qualifyNestedInlineName(name, fieldName);\n        const namingDisc = deriveConstNamingDiscriminator(inlineObjectVariants);\n        const emitted: Model[] = [];\n        for (const variant of inlineObjectVariants) {\n          const variantName = nameVariantModel(variant, baseQualified, emitted, namingDisc);\n          emitted.push({ name: variantName, fields: [] });\n          nestedModels.push(...extractInlineModelDeep(variantName, variant));\n        }\n      }\n    }\n  }\n\n  return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n\nfunction qualifyNestedInlineName(parentName: string, fieldName: string): string {\n  const pascalField = toPascalCase(fieldName);\n  if (pascalField.startsWith(parentName)) return pascalField;\n\n  const cleanParent = stripListItemMarkers(parentName);\n  const qualified = `${cleanParent}${pascalField}`;\n  const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n  if (match && match[2]) {\n    return match[1] + singularize(match[2]);\n  }\n  return qualified;\n}\n\nexport function schemaToTypeRef(schema: SchemaObject, contextName?: string, parentModelName?: string): TypeRef {\n  // Handle $ref → ModelRef or EnumRef.\n  // A `$ref` to a top-level component schema needs to preserve whether the\n  // target is a model or an enum, because emitters route imports differently\n  // for the two kinds (e.g. com.example.models.X vs com.example.types.X). The\n  // set of enum names is precomputed by extractSchemas() in a first pass so\n  // it's available even when called recursively for nested $refs.\n  if (schema.$ref) {\n    const segments = schema.$ref.split('/');\n    const rawName = segments[segments.length - 1];\n    const resolved = resolveSchemaName(rawName);\n    if (activeEnumSchemaNames.has(resolved)) {\n      return { kind: 'enum', name: resolved };\n    }\n    return { kind: 'model', name: resolved };\n  }\n\n  // Handle OAS 3.1 nullable type arrays: type: [string, null]\n  if (Array.isArray(schema.type)) {\n    const nonNullTypes = schema.type.filter((t: string) => t !== 'null');\n    // type: ['null'] — only null, no real type\n    if (nonNullTypes.length === 0) {\n      return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n    }\n    if (schema.type.includes('null') && nonNullTypes.length === 1) {\n      return {\n        kind: 'nullable',\n        inner: schemaToTypeRef({ ...schema, type: nonNullTypes[0], nullable: false }, contextName),\n      };\n    }\n    // Multiple non-null types → union\n    if (nonNullTypes.length > 1) {\n      const variants = nonNullTypes.map((t: string) => schemaToTypeRef({ ...schema, type: t }, contextName));\n      const ref: TypeRef = { kind: 'union', variants };\n      if (schema.type.includes('null')) {\n        return { kind: 'nullable', inner: ref };\n      }\n      return ref;\n    }\n  }\n\n  // Handle OAS 3.0 nullable flag\n  if (schema.nullable && schema.type) {\n    return {\n      kind: 'nullable',\n      inner: schemaToTypeRef({ ...schema, nullable: false }, contextName),\n    };\n  }\n\n  // Handle allOf — merge properties from all sub-schemas.\n  // This handles patterns like: allOf: [{ type: object, properties: {...} }, { oneOf: [...] }]\n  // which are valid OAS 3.1 but weren't handled for field-level schemas.\n  if (schema.allOf) {\n    // If allOf contains a $ref, prefer the ref (it's a named type)\n    const refItem = schema.allOf.find((s: SchemaObject) => s.$ref);\n    if (refItem) {\n      // If allOf has $ref AND siblings with properties, return a merged model ref\n      // to avoid losing the augmentation properties\n      const hasAugmentation = schema.allOf.some((s: SchemaObject) => !s.$ref && (s.properties || s.type === 'object'));\n      if (hasAugmentation) {\n        const baseName = toPascalCase(contextName ?? 'UnknownModel');\n        return { kind: 'model', name: qualifyInlineModelName(baseName, parentModelName) };\n      }\n      return schemaToTypeRef(refItem, contextName, parentModelName);\n    }\n    // If allOf has a single item, unwrap it\n    if (schema.allOf.length === 1) {\n      return schemaToTypeRef(schema.allOf[0], contextName, parentModelName);\n    }\n    // If allOf items all have properties, treat as a merged model\n    const hasProperties = schema.allOf.some((s: SchemaObject) => s.properties);\n    if (hasProperties) {\n      const baseName = toPascalCase(contextName ?? 'UnknownModel');\n      return {\n        kind: 'model',\n        name: qualifyInlineModelName(baseName, parentModelName),\n      };\n    }\n    // Fall through to other checks\n  }\n\n  // Handle oneOf / anyOf → Union or Nullable\n  // Valid OAS 3.1: properties can have { oneOf: [{ type: object }, { type: 'null' }] }\n  // without a wrapping `type` field.\n  if (schema.oneOf || schema.anyOf) {\n    const compositionKind: 'oneOf' | 'anyOf' = schema.oneOf ? 'oneOf' : 'anyOf';\n    const rawVariants: SchemaObject[] = schema.oneOf ?? schema.anyOf ?? [];\n\n    // Check for nullable pattern: oneOf: [realType, { type: 'null' }]\n    const nullVariant = rawVariants.find(\n      (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.length === 1 && v.type[0] === 'null'),\n    );\n    const nonNullVariants = rawVariants.filter((v) => v !== nullVariant);\n\n    if (nullVariant && nonNullVariants.length === 1) {\n      // Nullable single type — unwrap as nullable\n      return {\n        kind: 'nullable',\n        inner: schemaToTypeRef(nonNullVariants[0], contextName, parentModelName),\n      };\n    }\n\n    // Collapse an oneOf/anyOf whose non-null variants are all string-const\n    // schemas into a single enum. This turns patterns like\n    //   provider: { oneOf: [{ const: \"AppleOAuth\" }, { const: \"GitHubOAuth\" }, ...] }\n    // into a proper enum type with one member per variant instead of a\n    // structurally-opaque union of literal refs.\n    const literalStrings = collectLiteralStringConsts(nonNullVariants);\n    if (literalStrings !== null && literalStrings.length >= 2) {\n      const enumRef = buildSyntheticEnumRef(literalStrings, contextName, parentModelName);\n      return nullVariant ? { kind: 'nullable', inner: enumRef } : enumRef;\n    }\n\n    // Resolve the discriminator. Three sources, in order:\n    //   1. Explicit `discriminator:` with explicit `mapping:` — trust the spec.\n    //   2. Explicit `discriminator:` with no `mapping:` — derive mapping from\n    //      variants' const values on the discriminator property, pairing each\n    //      to its inline-extracted variant model name (built the same way\n    //      `extractNestedSchema` names them via `nameVariantModel`). This\n    //      covers `ApiKey.owner`-shaped schemas where the spec uses\n    //      `discriminator: { propertyName: type }` but lists inline anonymous\n    //      `oneOf` variants instead of `$ref` links.\n    //   3. No explicit discriminator but every variant pins the same const-\n    //      valued property AND the variants are nameable via $ref/title —\n    //      `detectConstPropertyDiscriminator` covers this.\n    //   4. As a last resort, when (3) doesn't apply because variants are\n    //      inline anonymous objects, derive the same const → variant-model-\n    //      name mapping using `nameVariantModel`. This covers\n    //      `ApiKeyCreatedData.owner`-shaped schemas (oneOf with inline\n    //      const-discriminating variants but no `discriminator:` keyword).\n    let resolvedDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n    if (schema.discriminator) {\n      const property = schema.discriminator.propertyName;\n      const explicitMapping = schema.discriminator.mapping ?? {};\n      let mapping: Record<string, string> = Object.fromEntries(\n        Object.entries(explicitMapping).map(([k, v]) => [k, v.replace(/^#\\/components\\/schemas\\//, '')]),\n      );\n      if (Object.keys(mapping).length === 0) {\n        const inlineMapping = deriveInlineVariantMapping(nonNullVariants, property, contextName, parentModelName);\n        if (inlineMapping) mapping = inlineMapping;\n      }\n      resolvedDiscriminator = { property, mapping };\n    } else if (compositionKind === 'oneOf') {\n      const synthetic = detectConstPropertyDiscriminator(nonNullVariants);\n      if (synthetic) {\n        resolvedDiscriminator = synthetic;\n      } else {\n        const namingDisc = deriveConstNamingDiscriminator(nonNullVariants);\n        if (namingDisc) {\n          const inlineMapping = deriveInlineVariantMapping(\n            nonNullVariants,\n            namingDisc.property,\n            contextName,\n            parentModelName,\n          );\n          if (inlineMapping) {\n            resolvedDiscriminator = { property: namingDisc.property, mapping: inlineMapping };\n          }\n        }\n      }\n    }\n\n    // Build variants. When we have a discriminator with a known mapping and\n    // every non-null variant is an inline object that pins the discriminator\n    // property to a const, route each variant's TypeRef through that mapping.\n    // This avoids the degenerate case where `qualifyInlineModelName` would\n    // assign the same parent-derived name (e.g. `ApiKeyOwner`) to every\n    // inline variant, collapsing the union to a single repeated model ref.\n    const variants: TypeRef[] = [];\n    for (const v of rawVariants) {\n      if (v === nullVariant) continue;\n      const inlineMappingName =\n        resolvedDiscriminator && !v.$ref && v.properties && (v.type === 'object' || !v.type)\n          ? mapVariantToDiscriminatorEntry(v, resolvedDiscriminator)\n          : null;\n      if (inlineMappingName) {\n        variants.push({ kind: 'model', name: inlineMappingName });\n      } else {\n        variants.push(schemaToTypeRef(v, contextName, parentModelName));\n      }\n    }\n    const hasNull = !!nullVariant;\n\n    const union: TypeRef = {\n      kind: 'union',\n      variants,\n      compositionKind,\n      ...(resolvedDiscriminator ? { discriminator: resolvedDiscriminator } : {}),\n    };\n    return hasNull ? { kind: 'nullable', inner: union } : union;\n  }\n\n  // Handle const → LiteralType (supports string, number, boolean)\n  if (schema.const !== undefined) {\n    if (typeof schema.const === 'string' || typeof schema.const === 'number' || typeof schema.const === 'boolean') {\n      return { kind: 'literal', value: schema.const };\n    }\n    // null const → nullable unknown\n    if (schema.const === null) {\n      return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n    }\n    // const of object/array → map or array with unknown values\n    if (typeof schema.const === 'object') {\n      if (Array.isArray(schema.const)) {\n        return { kind: 'array', items: { kind: 'primitive', type: 'unknown' } };\n      }\n      return { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } };\n    }\n  }\n  if (schema.enum && schema.enum.length === 1) {\n    const v = schema.enum[0];\n    return { kind: 'literal', value: typeof v === 'number' ? v : String(v) };\n  }\n\n  // Handle enum\n  if (schema.enum) {\n    const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n    // Strip ListItem/ByExternalId markers from parent name so enum names are clean:\n    // e.g., DirectoryListItem + State → Directory + State = DirectoryState\n    const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n    // Avoid redundant prefix: Connection + ConnectionType → ConnectionType\n    const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n    // Run `schemaNameTransform` so project-level rename maps in\n    // `oagen.config.ts` reach inline parameter/field enums too — without\n    // this, `RadarAction` (built from path param `action` on the Radar\n    // service) couldn't be redirected to `RadarListAction` from config.\n    const finalName = activeSchemaNameTransform ? activeSchemaNameTransform(qualifiedName) : qualifiedName;\n    return {\n      kind: 'enum',\n      name: finalName,\n      values: schema.enum.map((v) => (typeof v === 'number' ? v : String(v))),\n    };\n  }\n\n  // Handle array — pass parentModelName through to qualify inline items\n  if (schema.type === 'array' && schema.items) {\n    return {\n      kind: 'array',\n      items: schemaToTypeRef(schema.items, contextName, parentModelName),\n    };\n  }\n  // Handle array without explicit type but with items (valid OAS 3.1)\n  if (!schema.type && schema.items) {\n    return {\n      kind: 'array',\n      items: schemaToTypeRef(schema.items, contextName, parentModelName),\n    };\n  }\n\n  // Handle object → ModelRef (if it has properties, it's a named model reference)\n  // When additionalProperties is also present, we still return a ModelRef so the\n  // named properties are preserved. The extractModel path will pick up the extra\n  // properties as a catch-all map field named `additionalProperties`.\n  if (schema.type === 'object' && schema.properties) {\n    const baseName = toPascalCase(contextName ?? 'UnknownModel');\n    return {\n      kind: 'model',\n      name: qualifyInlineModelName(baseName, parentModelName),\n    };\n  }\n\n  // Handle freeform object with additionalProperties or patternProperties → Map<string, T>\n  if (schema.type === 'object' && !schema.properties) {\n    let valueType: TypeRef = { kind: 'primitive', type: 'unknown' };\n    if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n      // Empty additionalProperties ({}) means \"any value\" — keep as unknown\n      const apKeys = Object.keys(schema.additionalProperties);\n      if (apKeys.length > 0) {\n        valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, contextName);\n      }\n    } else if (schema.patternProperties) {\n      // patternProperties: { \"pattern\": schema } → use the first pattern's schema as value type\n      const patterns = Object.values(schema.patternProperties);\n      if (patterns.length > 0) {\n        valueType = schemaToTypeRef(patterns[0], contextName);\n      }\n    }\n    return {\n      kind: 'map',\n      valueType,\n    };\n  }\n\n  // Handle primitives\n  const primitiveMap: Record<string, 'string' | 'integer' | 'number' | 'boolean'> = {\n    string: 'string',\n    integer: 'integer',\n    number: 'number',\n    boolean: 'boolean',\n  };\n\n  const typeStr = Array.isArray(schema.type) ? schema.type[0] : schema.type;\n  if (typeStr && primitiveMap[typeStr]) {\n    return {\n      kind: 'primitive',\n      type: primitiveMap[typeStr],\n      ...(schema.format ? { format: schema.format } : {}),\n    };\n  }\n\n  // Handle schemas with no type — if it has properties, treat as model\n  if (!schema.type && schema.properties) {\n    const baseName = toPascalCase(contextName ?? 'UnknownModel');\n    return {\n      kind: 'model',\n      name: qualifyInlineModelName(baseName, parentModelName),\n    };\n  }\n\n  // Empty schema {} → unknown\n  if (\n    !schema.type &&\n    !schema.$ref &&\n    !schema.oneOf &&\n    !schema.anyOf &&\n    !schema.allOf &&\n    !schema.enum &&\n    !schema.properties &&\n    !schema.items\n  ) {\n    return { kind: 'primitive', type: 'unknown' };\n  }\n\n  // Fallback: treat unknown schemas as unknown\n  if (contextName) {\n    console.warn(`[oagen] Warning: Unknown schema shape treated as unknown (context: ${contextName})`);\n  }\n  return { kind: 'primitive', type: 'unknown' };\n}\n\nimport { qualifyInlineModelName } from './inline-models.js';\n\nexport { qualifyInlineModelName, extractInlineModelsFromSchemas } from './inline-models.js';\n","import type { TypeRef, Parameter, PaginationMeta } from '../ir/types.js';\n\nconst CURSOR_PARAMS = ['cursor', 'after', 'before', 'starting_after', 'ending_before', 'page_token', 'next_token'];\n\nconst OFFSET_PARAMS = ['offset', 'page', 'page_number', 'skip'];\nconst LIMIT_PARAMS = ['limit', 'page_size', 'per_page', 'size', 'count'];\n\n/**\n * Detect if an operation uses pagination and return structured metadata\n * for auto-paging iterator generation.\n *\n * Supports two strategies:\n * 1. **Cursor-based**: query params include a cursor-like parameter\n * 2. **Offset-based**: query params include both an offset-like and limit-like parameter\n *\n * Returns null if no pagination pattern is detected.\n */\nexport function detectPagination(\n  response: TypeRef,\n  queryParams: Parameter[],\n  dataPath?: string,\n): PaginationMeta | null {\n  // Try cursor-based first (preferred). Scan in CURSOR_PARAMS priority order\n  // rather than queryParams order so that an endpoint exposing both `before`\n  // and `after` reports `after` (forward iteration) — matches the wire\n  // convention where `after` advances through pages.\n  const cursorParam = CURSOR_PARAMS.map((name) => queryParams.find((p) => p.name === name)).find(\n    (p): p is Parameter => p !== undefined,\n  );\n\n  if (cursorParam) {\n    const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n    return {\n      strategy: 'cursor',\n      param: cursorParam.name,\n      dataPath: dataPath,\n      itemType,\n    };\n  }\n\n  // Try offset-based pagination\n  const offsetParam = queryParams.find((p) => OFFSET_PARAMS.includes(p.name));\n  const limitParam = queryParams.find((p) => LIMIT_PARAMS.includes(p.name));\n\n  if (offsetParam && limitParam) {\n    const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n    return {\n      strategy: 'offset',\n      param: offsetParam.name,\n      limitParam: limitParam.name,\n      dataPath: dataPath,\n      itemType,\n    };\n  }\n\n  return null;\n}\n","import type { TypeRef, Model, Field } from '../ir/types.js';\nimport { toPascalCase, singularize, stripListItemMarkers } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\n\nexport interface ResponseExtractionResult {\n  /** The TypeRef to use as the operation's response type */\n  response: TypeRef;\n  /** Any inline models discovered during extraction (to merge into ir.models) */\n  inlineModels: Model[];\n  /** Whether this response indicates a paginated list */\n  isPaginated: boolean;\n  /** Path to the data array within the response envelope (e.g., 'data') */\n  dataPath?: string;\n  /** TypeRef of individual items in a paginated list */\n  itemType?: TypeRef;\n}\n\nexport function classifyAndExtractResponse(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n  // 1. If schema is a $ref, resolve to model name (Phase 1)\n  if (schema.$ref) {\n    return { response: schemaToTypeRef(schema, contextName), inlineModels: [], isPaginated: false };\n  }\n\n  // 2. Check for list envelope (structural detection: array prop + non-array companion)\n  const envelope = detectListEnvelope(schema);\n  if (envelope.isEnvelope) {\n    return extractListResponse(schema, contextName, envelope.dataPath!);\n  }\n\n  // 3. Check for single-resource wrapper ({ resource_name: { object: \"...\", ... } })\n  if (isSingleResourceWrapper(schema)) {\n    return extractWrappedResource(schema, contextName);\n  }\n\n  // 4. Direct resource or plain inline object\n  return extractDirectResource(schema, contextName);\n}\n\ninterface ListEnvelopeResult {\n  isEnvelope: boolean;\n  dataPath: string | null;\n}\n\nconst KNOWN_DATA_PATHS = new Set(['data', 'items', 'results', 'records', 'entries', 'values', 'nodes', 'edges']);\n\nconst PAGINATION_METADATA_PATTERNS = [\n  'meta',\n  'metadata',\n  'pagination',\n  'cursor',\n  'has_more',\n  'page_info',\n  'total',\n  'next_page',\n  'previous_page',\n  'offset',\n];\n\nfunction detectListEnvelope(schema: SchemaObject): ListEnvelopeResult {\n  // Collect all property sources (allOf sub-schemas or flat schema)\n  const propSources: Record<string, SchemaObject | undefined>[] = [];\n  if (schema.allOf) {\n    for (const sub of schema.allOf) {\n      if (sub.properties) propSources.push(sub.properties);\n    }\n  }\n  if (schema.properties) {\n    propSources.push(schema.properties);\n  }\n\n  if (propSources.length === 0) return { isEnvelope: false, dataPath: null };\n\n  // Merge all properties into a single view\n  const mergedProps: Record<string, SchemaObject | undefined> = {};\n  for (const source of propSources) {\n    Object.assign(mergedProps, source);\n  }\n\n  // Find array-typed properties and non-array companion properties\n  const arrayProps: string[] = [];\n  const nonArrayKeys: string[] = [];\n\n  for (const [key, propSchema] of Object.entries(mergedProps)) {\n    if (!propSchema) continue;\n    if (propSchema.type === 'array') {\n      arrayProps.push(key);\n    } else {\n      nonArrayKeys.push(key);\n    }\n  }\n\n  // List envelope heuristic: exactly one array property + at least one non-array companion\n  // that looks like pagination metadata.  A `data` array alone (e.g. with only an\n  // `object` discriminant companion) is NOT sufficient — the companion must indicate\n  // actual pagination (cursor, metadata, total, etc.).\n  if (arrayProps.length === 1 && nonArrayKeys.length >= 1) {\n    const arrayPropName = arrayProps[0];\n\n    const hasPaginationCompanion = nonArrayKeys.some((key) =>\n      PAGINATION_METADATA_PATTERNS.some((pattern) => key.toLowerCase().includes(pattern)),\n    );\n\n    if (KNOWN_DATA_PATHS.has(arrayPropName) && hasPaginationCompanion) {\n      return { isEnvelope: true, dataPath: arrayPropName };\n    }\n\n    // Non-standard array property name — still treat as envelope if pagination companion exists\n    if (hasPaginationCompanion) {\n      return { isEnvelope: true, dataPath: arrayPropName };\n    }\n  }\n\n  return { isEnvelope: false, dataPath: null };\n}\n\nfunction extractListResponse(schema: SchemaObject, contextName: string, dataPath: string): ResponseExtractionResult {\n  let itemTypeRef: TypeRef = { kind: 'primitive', type: 'string' };\n  const inlineModels: Model[] = [];\n\n  // Collect all property sources (allOf sub-schemas or flat schema)\n  const propSources: Record<string, SchemaObject | undefined>[] = [];\n  if (schema.allOf) {\n    for (const sub of schema.allOf) {\n      if (sub.properties) propSources.push(sub.properties);\n    }\n  }\n  if (schema.properties) {\n    propSources.push(schema.properties);\n  }\n\n  for (const props of propSources) {\n    const dataProp = props[dataPath];\n    if (!dataProp) continue;\n\n    if (dataProp.type === 'array' && dataProp.items) {\n      const items = dataProp.items;\n      if (items.$ref) {\n        itemTypeRef = schemaToTypeRef(items, contextName);\n      } else if (items.type === 'object' && items.properties) {\n        const itemName = contextName.replace(/Response$/, '') + 'Item';\n        itemTypeRef = { kind: 'model', name: itemName };\n        inlineModels.push(...extractInlineModel(itemName, items));\n      }\n    }\n  }\n\n  return {\n    response: { kind: 'array', items: itemTypeRef },\n    inlineModels,\n    isPaginated: true,\n    dataPath,\n    itemType: itemTypeRef,\n  };\n}\n\nfunction hasDiscriminantConstField(schema: SchemaObject): { property: string; value: string } | null {\n  if (!schema.properties) return null;\n\n  // Prefer well-known discriminant properties for backward compatibility\n  const preferred = ['object', 'type'];\n  for (const name of preferred) {\n    const field = schema.properties[name];\n    if (!field) continue;\n    if (field.const !== undefined && typeof field.const === 'string') {\n      return { property: name, value: field.const };\n    }\n    if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n      return { property: name, value: field.enum[0] };\n    }\n  }\n\n  // Fall back to any property with a const or single-value enum\n  for (const [name, field] of Object.entries(schema.properties)) {\n    if (!field) continue;\n    if (field.const !== undefined && typeof field.const === 'string') {\n      return { property: name, value: field.const };\n    }\n    if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n      return { property: name, value: field.enum[0] };\n    }\n  }\n\n  return null;\n}\n\nfunction isSingleResourceWrapper(schema: SchemaObject): boolean {\n  if (schema.type !== 'object') return false;\n  if (!schema.properties) return false;\n\n  // Find the wrapper property: use required[0] if available, or the single property key\n  let wrapperKey: string | undefined;\n  if (schema.required && schema.required.length === 1) {\n    wrapperKey = schema.required[0];\n  } else {\n    const propKeys = Object.keys(schema.properties);\n    if (propKeys.length === 1) {\n      wrapperKey = propKeys[0];\n    }\n  }\n  if (!wrapperKey) return false;\n\n  const propSchema = schema.properties[wrapperKey];\n  if (!propSchema) return false;\n\n  // Direct object with a discriminant const field\n  if (propSchema.type === 'object' && hasDiscriminantConstField(propSchema) !== null) return true;\n\n  // oneOf with object + null (nullable resource)\n  if (propSchema.oneOf) {\n    return propSchema.oneOf.some((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n  }\n\n  return false;\n}\n\nfunction extractWrappedResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n  const props = schema.properties!;\n  const wrapperKey = schema.required && schema.required.length === 1 ? schema.required[0] : Object.keys(props)[0];\n  const propSchema = props[wrapperKey]!;\n  const inlineModels: Model[] = [];\n\n  // Derive model name from the object const value or wrapper property name\n  const resourceName = contextName.replace(/Response$/, '');\n\n  if (propSchema.oneOf) {\n    const objectVariant = propSchema.oneOf.find((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n\n    if (objectVariant) {\n      const modelName = deriveModelName(objectVariant, resourceName);\n      inlineModels.push(...extractInlineModel(modelName, objectVariant));\n\n      const hasNullVariant = propSchema.oneOf.some(\n        (v) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n      );\n\n      const modelRef: TypeRef = { kind: 'model', name: modelName };\n      return {\n        response: hasNullVariant ? { kind: 'nullable', inner: modelRef } : modelRef,\n        inlineModels,\n        isPaginated: false,\n      };\n    }\n  }\n\n  // Direct object\n  const modelName = deriveModelName(propSchema, resourceName);\n  inlineModels.push(...extractInlineModel(modelName, propSchema));\n\n  return {\n    response: { kind: 'model', name: modelName },\n    inlineModels,\n    isPaginated: false,\n  };\n}\n\nfunction extractDirectResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n  const inlineModels: Model[] = [];\n\n  // Direct object with properties (with or without explicit type: 'object')\n  if (schema.properties && (schema.type === 'object' || !schema.type)) {\n    const modelName = deriveModelName(schema, contextName);\n    inlineModels.push(...extractInlineModel(modelName, schema));\n    return {\n      response: { kind: 'model', name: modelName },\n      inlineModels,\n      isPaginated: false,\n    };\n  }\n\n  // allOf with properties — merge into a single model\n  if (schema.allOf) {\n    const mergedProperties: Record<string, SchemaObject | undefined> = {};\n    const mergedRequired: string[] = [];\n    for (const sub of schema.allOf) {\n      if (sub.properties) {\n        Object.assign(mergedProperties, sub.properties);\n      }\n      if (sub.required) {\n        mergedRequired.push(...sub.required);\n      }\n    }\n    if (Object.keys(mergedProperties).length > 0) {\n      const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n      const modelName = deriveModelName(merged, contextName);\n      inlineModels.push(...extractInlineModel(modelName, merged));\n      return {\n        response: { kind: 'model', name: modelName },\n        inlineModels,\n        isPaginated: false,\n      };\n    }\n  }\n\n  // oneOf — delegate to schemaToTypeRef (returns union) but also extract inline models\n  // from object variants so the model refs resolve\n  if (schema.oneOf) {\n    for (const variant of schema.oneOf) {\n      if (variant.properties && (variant.type === 'object' || !variant.type)) {\n        const modelName = deriveModelName(variant, contextName);\n        const existingNames = new Set(inlineModels.map((m) => m.name));\n        if (!existingNames.has(modelName)) {\n          inlineModels.push(...extractInlineModel(modelName, variant));\n        }\n      }\n    }\n  }\n\n  // Array with inline object items — extract the item model\n  if (schema.type === 'array' && schema.items) {\n    const items = schema.items;\n    if (items.$ref) {\n      return {\n        response: { kind: 'array', items: schemaToTypeRef(items, contextName) },\n        inlineModels,\n        isPaginated: false,\n      };\n    }\n    if (items.properties && (items.type === 'object' || !items.type)) {\n      const itemName = contextName.replace(/Response$/, '') + 'Item';\n      inlineModels.push(...extractInlineModel(itemName, items));\n      return {\n        response: { kind: 'array', items: { kind: 'model', name: itemName } },\n        inlineModels,\n        isPaginated: false,\n      };\n    }\n  }\n\n  // Non-object schema (primitive, union, etc.) — delegate to schemaToTypeRef\n  return {\n    response: schemaToTypeRef(schema, contextName),\n    inlineModels,\n    isPaginated: false,\n  };\n}\n\nfunction deriveModelName(schema: SchemaObject, fallback: string): string {\n  if (!schema.properties) return toPascalCase(fallback);\n\n  // Prefer well-known discriminant properties for backward compatibility\n  const preferred = ['object', 'type'];\n  for (const name of preferred) {\n    const field = schema.properties[name];\n    if (field && field.const && typeof field.const === 'string') {\n      return toPascalCase(field.const);\n    }\n  }\n\n  // Fall back to any property with a const string value\n  for (const [, field] of Object.entries(schema.properties)) {\n    if (field && field.const && typeof field.const === 'string') {\n      return toPascalCase(field.const);\n    }\n  }\n\n  return toPascalCase(fallback);\n}\n\n/**\n * Qualify a nested inline model name with its parent to avoid generic names.\n * e.g., parent=\"Connection\" + field=\"domains\" → \"ConnectionDomain\" (singularized)\n * Only qualifies when the field name alone would be too generic.\n */\nfunction qualifyNestedName(parentName: string, fieldName: string): string {\n  const pascalField = toPascalCase(fieldName);\n  // If the field name already starts with the parent name, don't double-prefix\n  if (pascalField.startsWith(parentName)) return pascalField;\n  // Qualify with parent and singularize:\n  // Connection + Domains → ConnectionDomains → singularize lead word → ConnectionDomain\n  const cleanParent = stripListItemMarkers(parentName);\n  const qualified = `${cleanParent}${pascalField}`;\n  // Singularize the trailing word: ConnectionDomains → ConnectionDomain\n  const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n  if (match && match[2]) {\n    const trailing = singularize(match[2]);\n    return match[1] + trailing;\n  }\n  return qualified;\n}\n\nfunction extractInlineModel(name: string, schema: SchemaObject): Model[] {\n  const requiredSet = new Set(schema.required ?? []);\n  const fields: Field[] = [];\n  const properties = schema.properties ?? {};\n  const nestedModels: Model[] = [];\n\n  for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n    if (!fieldSchema) continue;\n    fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n    // Recursively extract nested inline objects — qualify with parent name\n    // to avoid generic names like \"Domains\" when multiple parents have a \"domains\" field\n    if (fieldSchema.type === 'object' && fieldSchema.properties) {\n      const nestedName = qualifyNestedName(name, fieldName);\n      nestedModels.push(...extractInlineModel(nestedName, fieldSchema));\n    }\n    if (fieldSchema.type === 'array' && fieldSchema.items) {\n      const items = fieldSchema.items;\n      if (items.type === 'object' && items.properties) {\n        const nestedName = qualifyNestedName(name, fieldName);\n        nestedModels.push(...extractInlineModel(nestedName, items));\n      }\n    }\n    // Handle allOf with inline object properties — merge into a single nested model\n    if (fieldSchema.allOf) {\n      const mergedProperties: Record<string, SchemaObject | undefined> = {};\n      const mergedRequired: string[] = [];\n      for (const sub of fieldSchema.allOf) {\n        if (sub.properties) Object.assign(mergedProperties, sub.properties);\n        if (sub.required) mergedRequired.push(...sub.required);\n      }\n      if (Object.keys(mergedProperties).length > 0) {\n        const nestedName = qualifyNestedName(name, fieldName);\n        const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n        const existingNames = new Set(nestedModels.map((m) => m.name));\n        if (!existingNames.has(nestedName)) {\n          nestedModels.push(...extractInlineModel(nestedName, merged));\n        }\n      }\n    }\n    // Handle oneOf containing inline objects — extract the first non-null object variant\n    if (fieldSchema.oneOf) {\n      const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n      if (objectVariant) {\n        const nestedName = qualifyNestedName(name, fieldName);\n        const existingNames = new Set(nestedModels.map((m) => m.name));\n        if (!existingNames.has(nestedName)) {\n          nestedModels.push(...extractInlineModel(nestedName, objectVariant));\n        }\n      }\n    }\n  }\n\n  return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n","import type {\n  Service,\n  Operation,\n  HttpMethod,\n  Parameter,\n  ParameterGroup,\n  TypeRef,\n  ErrorResponse,\n  SuccessResponse,\n  SecurityRequirement,\n  Model,\n  Field,\n  PaginationMeta,\n} from '../ir/types.js';\nimport { toPascalCase, toCamelCase, cleanSchemaName } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\nimport { detectPagination } from './pagination.js';\nimport { classifyAndExtractResponse } from './responses.js';\n\ninterface PathItem {\n  get?: OperationObject;\n  post?: OperationObject;\n  put?: OperationObject;\n  patch?: OperationObject;\n  delete?: OperationObject;\n  head?: OperationObject;\n  options?: OperationObject;\n  trace?: OperationObject;\n  parameters?: ParameterObject[];\n}\n\ninterface ParameterGroupExtension {\n  optional: boolean;\n  variants: Record<string, string[]>;\n}\n\ninterface OperationObject {\n  operationId?: string;\n  summary?: string;\n  description?: string;\n  tags?: string[];\n  parameters?: ParameterObject[];\n  requestBody?: RequestBodyObject;\n  responses?: Record<string, ResponseObject>;\n  deprecated?: boolean;\n  'x-oagen-async'?: boolean;\n  security?: Array<Record<string, string[]>>;\n  'x-mutually-exclusive-parameter-groups'?: Record<string, ParameterGroupExtension>;\n  'x-mutually-exclusive-body-groups'?: Record<string, ParameterGroupExtension>;\n}\n\ninterface ParameterObject {\n  name: string;\n  in: 'path' | 'query' | 'header' | 'cookie';\n  required?: boolean;\n  description?: string;\n  schema?: SchemaObject;\n  deprecated?: boolean;\n  example?: unknown;\n  style?: string;\n  explode?: boolean;\n}\n\ninterface RequestBodyObject {\n  required?: boolean;\n  content?: Record<string, { schema?: SchemaObject }>;\n}\n\ninterface ResponseObject {\n  description?: string;\n  content?: Record<string, { schema?: SchemaObject }>;\n}\n\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\nexport interface OperationExtractionResult {\n  services: Service[];\n  inlineModels: Model[];\n}\n\nexport function extractOperations(\n  paths: Record<string, PathItem> | undefined,\n  operationIdTransform?: (id: string) => string,\n  componentSchemas?: Record<string, SchemaObject>,\n): OperationExtractionResult {\n  if (!paths) return { services: [], inlineModels: [] };\n\n  const serviceMap = new Map<string, Operation[]>();\n  const inlineModels: Model[] = [];\n\n  for (const [path, pathItem] of Object.entries(paths)) {\n    const pathLevelParams = pathItem.parameters ?? [];\n\n    for (const method of HTTP_METHODS) {\n      const op = pathItem[method];\n      if (!op) continue;\n\n      const serviceName = inferServiceName(path, op.tags?.[0]);\n\n      const { operation, inlineModels: opModels } = buildOperation(\n        method,\n        path,\n        op,\n        pathLevelParams,\n        operationIdTransform,\n        serviceName,\n        componentSchemas,\n      );\n      inlineModels.push(...opModels);\n      const ops = serviceMap.get(serviceName) ?? [];\n      ops.push(operation);\n      serviceMap.set(serviceName, ops);\n    }\n  }\n\n  // Split services when a single tag groups operations from multiple path prefixes.\n  // Example: /organizations and /organization_domains both tagged \"organizations\"\n  // should become separate services based on their first path segment.\n  for (const [serviceName, operations] of serviceMap) {\n    const pathGroups = new Map<string, Operation[]>();\n    for (const op of operations) {\n      const firstSeg = op.path.split('/').filter(Boolean)[0] ?? '';\n      const groupKey = firstSeg.startsWith('{') ? serviceName : toPascalCase(firstSeg);\n      const group = pathGroups.get(groupKey) ?? [];\n      group.push(op);\n      pathGroups.set(groupKey, group);\n    }\n    // Only split if there are multiple distinct path-prefix groups AND\n    // at least one group name differs from the current service name\n    if (pathGroups.size > 1) {\n      const needsSplit = [...pathGroups.keys()].some((k) => k !== serviceName);\n      if (needsSplit) {\n        serviceMap.delete(serviceName);\n        for (const [groupName, groupOps] of pathGroups) {\n          const existing = serviceMap.get(groupName) ?? [];\n          existing.push(...groupOps);\n          serviceMap.set(groupName, existing);\n        }\n      }\n    }\n  }\n\n  // Disambiguate operation names within each service.\n  // Multiple operations can get the same name (e.g., several \"list\" endpoints\n  // in UserManagement for users, invitations, auth factors, etc.).\n  for (const [, operations] of serviceMap) {\n    disambiguateOperationNames(operations);\n  }\n\n  const services = Array.from(serviceMap.entries()).map(([name, operations]) => ({\n    name,\n    operations,\n  }));\n\n  return { services, inlineModels };\n}\n\nfunction inferServiceName(path: string, tag?: string): string {\n  // Prefer OpenAPI tag when available — tags represent the logical grouping\n  // (e.g., \"multi-factor-auth\" for /auth/factors/* endpoints).\n  if (tag) {\n    return toPascalCase(tag);\n  }\n  // Fallback: extract first meaningful path segment: /widgets/{id}/sub → \"Widgets\"\n  const segments = path.split('/').filter(Boolean);\n  const first = segments[0] ?? 'Default';\n  // Skip path params\n  if (first.startsWith('{')) return 'Default';\n  return toPascalCase(first);\n}\n\n/**\n * Strip overload indices (e.g. NestJS emits `Foo_bar[0]` when a controller\n * method handles multiple routes) from an operationId so derived names never\n * leak the bracketed digit. Without this, `authenticate[0]` would surface as\n * `authenticate0` in method names and `Authenticate0Request` in body model\n * names. Brackets at the end (or with trailing whitespace) are common in\n * NestJS-style backends; this regex is intentionally narrow to avoid eating\n * legitimate digits like `oauth2`.\n */\nfunction normalizeOperationIdForNaming(operationId: string): string {\n  return operationId.replace(/\\[\\d+\\]\\s*$/, '');\n}\n\nfunction inferOperationName(\n  method: HttpMethod,\n  path: string,\n  operationId?: string,\n  operationIdTransform?: (id: string) => string,\n): string {\n  if (operationId) {\n    const normalized = normalizeOperationIdForNaming(operationId);\n    if (operationIdTransform) {\n      return operationIdTransform(normalized);\n    }\n    return toCamelCase(normalized);\n  }\n\n  // Fallback when no operationId is available — use method + path to build\n  // a descriptive name like \"listUsers\", \"getOrganization\", \"deleteAuthFactor\"\n  const verb = inferVerb(method, path);\n  const resource = inferResourceFromPath(path);\n  return resource ? toCamelCase(`${verb}_${resource}`) : verb;\n}\n\n/**\n * Infer the CRUD verb from HTTP method and path shape.\n */\nfunction inferVerb(method: HttpMethod, path: string): string {\n  const segments = path.split('/').filter(Boolean);\n  const hasTrailingParam = segments.length > 0 && segments[segments.length - 1].startsWith('{');\n\n  switch (method) {\n    case 'get':\n      return hasTrailingParam ? 'get' : 'list';\n    case 'post':\n      return 'create';\n    case 'put':\n    case 'patch':\n      return 'update';\n    case 'delete':\n      return 'delete';\n    case 'head':\n      return 'check';\n    case 'options':\n      return 'options';\n    case 'trace':\n      return 'trace';\n    default:\n      return method;\n  }\n}\n\n/**\n * Extract a resource noun from the path for operation naming.\n * Uses the last non-param segment (the resource being operated on).\n *\n * Examples:\n *   /accounts/users → \"Users\"\n *   /accounts/users/{id} → \"User\" (singular for item operations)\n *   /accounts/users/{id}/auth_factors → \"AuthFactors\"\n *   /organizations/{id}/api_keys → \"ApiKeys\"\n *   /auth/authorize → \"Authorize\" (action endpoint)\n */\nfunction inferResourceFromPath(path: string): string | null {\n  const segments = path.split('/').filter(Boolean);\n  if (segments.length <= 1) return null;\n\n  // Find the last meaningful (non-param) segment\n  let resourceSegment: string | null = null;\n  for (let i = segments.length - 1; i >= 0; i--) {\n    if (!segments[i].startsWith('{')) {\n      resourceSegment = segments[i];\n      break;\n    }\n  }\n\n  if (!resourceSegment) return null;\n  // Skip the service name (first segment) — it would be redundant\n  if (resourceSegment === segments[0]) return null;\n\n  return toPascalCase(resourceSegment);\n}\n\n/**\n * Detect and resolve name collisions within a service's operations.\n *\n * When multiple operations share the same name (e.g., several \"list\" from\n * different sub-resources), disambiguate by appending the resource noun\n * from the path. Only renames operations on DIFFERENT paths — same-name\n * operations on the same path (e.g., PUT + PATCH both \"update\") are left as-is\n * since they represent the same logical resource.\n */\nfunction disambiguateOperationNames(operations: Operation[]): void {\n  // Group by name\n  const byName = new Map<string, Operation[]>();\n  for (const op of operations) {\n    const group = byName.get(op.name) ?? [];\n    group.push(op);\n    byName.set(op.name, group);\n  }\n\n  for (const [name, group] of byName) {\n    if (group.length <= 1) continue;\n\n    // Check if these are genuinely different resources (different paths)\n    // vs the same resource with different methods (PUT + PATCH)\n    const uniquePaths = new Set(group.map((op) => op.path));\n    if (uniquePaths.size <= 1) continue; // same path, different methods — no disambiguation needed\n\n    for (const op of group) {\n      const resource = inferResourceFromPath(op.path);\n      if (resource) {\n        const newName = toCamelCase(`${name}_${resource}`);\n        (op as { name: string }).name = newName;\n      }\n    }\n\n    // If disambiguation still left collisions (same sub-resource),\n    // use the full distinguishing path segment chain\n    const renamed = new Map<string, Operation[]>();\n    for (const op of group) {\n      const rGroup = renamed.get(op.name) ?? [];\n      rGroup.push(op);\n      renamed.set(op.name, rGroup);\n    }\n    for (const [, rGroup] of renamed) {\n      if (rGroup.length <= 1) continue;\n      // Still colliding — different paths map to same resource name.\n      // Use deeper path context to disambiguate.\n      for (const op of rGroup) {\n        const deeper = inferDeeperContext(op.path);\n        if (deeper) {\n          (op as { name: string }).name = toCamelCase(`${op.name}_${deeper}`);\n        }\n      }\n    }\n  }\n}\n\n/**\n * Extract a deeper disambiguation context from the path when the last\n * segment isn't unique enough. Uses the second-to-last non-param segment.\n *\n * /users/{id}/auth_factors → already captured as \"AuthFactors\"\n * /users/external_id/{external_id} → \"ExternalId\" (special path, not a sub-resource)\n */\nfunction inferDeeperContext(path: string): string | null {\n  const segments = path.split('/').filter(Boolean);\n  const nonParams = segments.filter((s) => !s.startsWith('{'));\n  // Skip first (service) and last (already used) — use the middle ones\n  if (nonParams.length >= 3) {\n    return toPascalCase(nonParams.slice(1, -1).join('_'));\n  }\n  return null;\n}\n\n/**\n * Extract mutually-exclusive parameter groups from the `x-mutually-exclusive-parameter-groups`\n * operation extension. Cross-references grouped parameter names against the already-extracted\n * IR parameter arrays so emitters get object-identity references.\n */\nfunction extractParameterGroups(\n  op: OperationObject,\n  allIRParams: Parameter[],\n  operationContext: string,\n): ParameterGroup[] | undefined {\n  const raw = op['x-mutually-exclusive-parameter-groups'];\n  if (!raw || typeof raw !== 'object') return undefined;\n\n  const paramByName = new Map<string, Parameter>();\n  for (const p of allIRParams) {\n    paramByName.set(p.name, p);\n  }\n\n  const groups: ParameterGroup[] = [];\n\n  for (const [groupName, groupDef] of Object.entries(raw)) {\n    if (!groupDef || typeof groupDef !== 'object') {\n      throw new Error(\n        `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: expected an object with \"optional\" and \"variants\".`,\n      );\n    }\n\n    if (typeof groupDef.optional !== 'boolean') {\n      throw new Error(\n        `Malformed x-mutually-exclusive-parameter-groups.${groupName}.optional in ${operationContext}: expected a boolean.`,\n      );\n    }\n\n    if (!groupDef.variants || typeof groupDef.variants !== 'object') {\n      throw new Error(\n        `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants in ${operationContext}: expected an object mapping variant names to parameter name arrays.`,\n      );\n    }\n\n    if (Object.keys(groupDef.variants).length === 0) {\n      throw new Error(\n        `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: group has zero variants.`,\n      );\n    }\n\n    const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n      if (!Array.isArray(paramNames) || paramNames.length === 0) {\n        throw new Error(\n          `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n        );\n      }\n      const parameters: Parameter[] = paramNames.map((pName) => {\n        const irParam = paramByName.get(pName);\n        if (!irParam) {\n          throw new Error(\n            `x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} references parameter \"${pName}\" which does not exist in the operation's parameters[] (${operationContext}).`,\n          );\n        }\n        return irParam;\n      });\n      return { name: variantName, parameters };\n    });\n\n    groups.push({\n      name: groupName,\n      optional: groupDef.optional,\n      variants,\n    });\n  }\n\n  return groups.length > 0 ? groups : undefined;\n}\n\n/**\n * Extract mutually-exclusive body parameter groups from the\n * `x-mutually-exclusive-body-groups` operation extension. Unlike query\n * parameter groups (whose parameters live in operation.queryParams), body\n * group parameters are synthetic — built from the oneOf variant schemas in\n * the request body. Emitters use the group's presence to generate sum-type\n * interfaces and custom JSON marshalling instead of flat optional fields.\n */\nfunction extractBodyParameterGroups(op: OperationObject, operationContext: string): ParameterGroup[] | undefined {\n  const raw = op['x-mutually-exclusive-body-groups'];\n  if (!raw || typeof raw !== 'object') return undefined;\n\n  // Collect the body schema's oneOf variant fields so we can resolve types.\n  // The body schema has been structurally rewritten to allOf: [base, { oneOf: [...] }]\n  // by the spec generator; the variant properties live inside oneOf branches.\n  const bodySchema = op.requestBody?.content?.['application/json']?.schema;\n  const variantFieldSchemas = new Map<string, SchemaObject>();\n\n  if (bodySchema) {\n    // Walk allOf → oneOf → variant.properties to find all variant fields\n    for (const sub of bodySchema.allOf ?? []) {\n      for (const variant of sub.oneOf ?? []) {\n        if (variant.properties) {\n          for (const [name, fieldSchema] of Object.entries(variant.properties)) {\n            if (fieldSchema) variantFieldSchemas.set(name, fieldSchema);\n          }\n        }\n      }\n    }\n    // Also check top-level oneOf (for inline schemas that aren't wrapped in allOf)\n    for (const variant of bodySchema.oneOf ?? []) {\n      if (variant.properties) {\n        for (const [name, fieldSchema] of Object.entries(variant.properties)) {\n          if (fieldSchema) variantFieldSchemas.set(name, fieldSchema);\n        }\n      }\n    }\n  }\n\n  const groups: ParameterGroup[] = [];\n\n  for (const [groupName, groupDef] of Object.entries(raw)) {\n    if (!groupDef || typeof groupDef !== 'object') continue;\n    if (typeof groupDef.optional !== 'boolean') continue;\n    if (!groupDef.variants || typeof groupDef.variants !== 'object') continue;\n    if (Object.keys(groupDef.variants).length === 0) continue;\n\n    const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n      if (!Array.isArray(paramNames) || paramNames.length === 0) {\n        throw new Error(\n          `Malformed x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n        );\n      }\n      const parameters: Parameter[] = paramNames.map((pName) => {\n        const fieldSchema = variantFieldSchemas.get(pName);\n        const fieldType: TypeRef = fieldSchema\n          ? schemaToTypeRef(fieldSchema, toPascalCase(pName))\n          : { kind: 'primitive', type: 'string' };\n        return {\n          name: pName,\n          type: fieldType,\n          required: false, // group variant fields are always optional at the struct level\n          description: fieldSchema?.description,\n        };\n      });\n      return { name: variantName, parameters };\n    });\n\n    groups.push({\n      name: groupName,\n      optional: groupDef.optional,\n      variants,\n    });\n  }\n\n  return groups.length > 0 ? groups : undefined;\n}\n\nfunction buildOperation(\n  method: HttpMethod,\n  path: string,\n  op: OperationObject,\n  pathLevelParams: ParameterObject[],\n  operationIdTransform?: (id: string) => string,\n  serviceName?: string,\n  componentSchemas?: Record<string, SchemaObject>,\n): { operation: Operation; inlineModels: Model[] } {\n  const allParams = [...pathLevelParams, ...(op.parameters ?? [])];\n\n  const hasIdempotencyHeader = allParams.some((p) => p.in === 'header' && p.name.toLowerCase() === 'idempotency-key');\n\n  // Use the service name as context so inline parameter enums get qualified\n  // names. e.g., service \"Auth\" + param \"provider\" → \"AuthProvider\".\n  const opContext = serviceName;\n  const pathParams = extractParams(allParams, 'path', opContext, componentSchemas);\n  const queryParams = extractParams(allParams, 'query', opContext, componentSchemas);\n  const headerParams = extractParams(allParams, 'header', opContext, componentSchemas).filter(\n    (p) => p.name.toLowerCase() !== 'idempotency-key',\n  );\n  const cookieParams = extractParams(allParams, 'cookie', opContext, componentSchemas);\n\n  const reqBodyModels: Model[] = [];\n  const { body: requestBody, encoding: requestBodyEncoding } = extractRequestBody(op.requestBody, op, reqBodyModels);\n  const {\n    response,\n    successResponses,\n    errors,\n    inlineModels,\n    isPaginated,\n    dataPath: responseDataPath,\n    itemType: responseItemType,\n  } = extractResponses(op.responses, op, path, method);\n  inlineModels.push(...reqBodyModels);\n\n  // Build structured pagination metadata from response classification and query param detection\n  const paginationFromParams = detectPagination(response, queryParams, responseDataPath);\n  let pagination: PaginationMeta | undefined;\n  if (isPaginated) {\n    const itemType = responseItemType ?? (response.kind === 'array' ? response.items : response);\n    pagination = {\n      strategy: paginationFromParams?.strategy ?? 'cursor',\n      param: paginationFromParams?.param ?? 'after',\n      limitParam: paginationFromParams?.limitParam,\n      dataPath: responseDataPath ?? paginationFromParams?.dataPath,\n      itemType,\n    };\n  } else if (paginationFromParams) {\n    pagination = paginationFromParams;\n  }\n\n  // Extract per-operation security overrides\n  const security = extractOperationSecurity(op.security);\n\n  // Extract mutually-exclusive parameter groups (query/path/header/cookie)\n  const allIRParams = [...pathParams, ...queryParams, ...headerParams, ...cookieParams];\n  const opLabel = op.operationId ?? `${method.toUpperCase()} ${path}`;\n  const queryParamGroups = extractParameterGroups(op, allIRParams, opLabel);\n\n  // Extract mutually-exclusive body parameter groups\n  const bodyParamGroups = extractBodyParameterGroups(op, opLabel);\n\n  // Merge both sources into a single parameterGroups array\n  const parameterGroups =\n    queryParamGroups || bodyParamGroups ? [...(queryParamGroups ?? []), ...(bodyParamGroups ?? [])] : undefined;\n\n  return {\n    operation: {\n      name: inferOperationName(method, path, op.operationId, operationIdTransform),\n      description: buildDescription(op.summary, op.description),\n      httpMethod: method,\n      path,\n      pathParams,\n      queryParams,\n      headerParams,\n      cookieParams: cookieParams.length > 0 ? cookieParams : undefined,\n      requestBody,\n      requestBodyEncoding,\n      response,\n      successResponses,\n      errors,\n      pagination,\n      injectIdempotencyKey: hasIdempotencyHeader,\n      deprecated: op.deprecated || undefined,\n      async: op['x-oagen-async'],\n      security,\n      parameterGroups,\n    },\n    inlineModels,\n  };\n}\n\n/**\n * Extract per-operation security requirements from an OpenAPI security directive.\n * Returns undefined when the operation uses the spec-level default security.\n *\n * OpenAPI security format: `security: [{ schemeName: [scope1, scope2] }]`\n */\nfunction extractOperationSecurity(\n  security: Array<Record<string, string[]>> | undefined,\n): SecurityRequirement[] | undefined {\n  if (!security || security.length === 0) return undefined;\n\n  const requirements: SecurityRequirement[] = [];\n  for (const entry of security) {\n    for (const [schemeName, scopes] of Object.entries(entry)) {\n      requirements.push({ schemeName, scopes: scopes ?? [] });\n    }\n  }\n  return requirements.length > 0 ? requirements : undefined;\n}\n\nfunction buildDescription(summary: string | undefined, description: string | undefined): string | undefined {\n  if (summary && description && summary !== description) {\n    return `${summary}\\n\\n${description}`;\n  }\n  return description ?? summary;\n}\n\nfunction extractParams(\n  params: ParameterObject[],\n  location: 'path' | 'query' | 'header' | 'cookie',\n  operationContext?: string,\n  componentSchemas?: Record<string, SchemaObject>,\n): Parameter[] {\n  return params\n    .filter((p) => p.in === location)\n    .map((p) => {\n      const refTarget = resolveParamSchemaRef(p.schema, componentSchemas);\n      return {\n        name: p.name,\n        type: p.schema\n          ? schemaToTypeRef(p.schema, p.name, operationContext ? toPascalCase(operationContext) : undefined)\n          : ({ kind: 'primitive', type: 'string' } as TypeRef),\n        required: p.required ?? false,\n        description: p.description,\n        deprecated: p.deprecated || p.schema?.deprecated || refTarget?.deprecated || undefined,\n        default: p.schema?.default ?? refTarget?.default,\n        example: p.example ?? p.schema?.example ?? refTarget?.example,\n        style: p.style as Parameter['style'],\n        explode: p.explode,\n      };\n    });\n}\n\n/**\n * If a parameter's schema is a `$ref` to `#/components/schemas/X`, return the\n * referenced component schema. Used to surface schema-level metadata (default,\n * example, deprecated) that wouldn't otherwise be visible at the param level.\n *\n * Refs are not pre-resolved by the bundler (`dereference: false` in refs.ts),\n * so without this, a param like `schema: { $ref: '.../PaginationOrder' }`\n * silently loses the target's `default: desc` and the SDK stops emitting the\n * spec-mandated default value in generated method signatures.\n */\nfunction resolveParamSchemaRef(\n  schema: SchemaObject | undefined,\n  componentSchemas: Record<string, SchemaObject> | undefined,\n): SchemaObject | undefined {\n  if (!schema || !componentSchemas) return undefined;\n  const ref = (schema as { $ref?: string }).$ref;\n  if (!ref) return undefined;\n  const match = /^#\\/components\\/schemas\\/(.+)$/.exec(ref);\n  if (!match) return undefined;\n  return componentSchemas[match[1]];\n}\n\nfunction extractRequestBody(\n  body: RequestBodyObject | undefined,\n  op: OperationObject | undefined,\n  inlineModels: Model[],\n): { body?: TypeRef; encoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' } {\n  if (!body?.content) return {};\n\n  // Detect encoding and find schema from content type in priority order\n  let encoding: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' = 'json';\n  let schema: SchemaObject | undefined;\n\n  if (body.content['application/json']?.schema) {\n    encoding = 'json';\n    schema = body.content['application/json']!.schema;\n  } else if (body.content['multipart/form-data']?.schema) {\n    encoding = 'form-data';\n    schema = body.content['multipart/form-data']!.schema;\n  } else if (body.content['application/x-www-form-urlencoded']?.schema) {\n    encoding = 'form-urlencoded';\n    schema = body.content['application/x-www-form-urlencoded']!.schema;\n  } else if (body.content['application/octet-stream']) {\n    encoding = 'binary';\n    schema = body.content['application/octet-stream']!.schema;\n  } else if (body.content['text/plain']) {\n    encoding = 'text';\n    schema = body.content['text/plain']!.schema;\n  }\n\n  if (!schema) {\n    // For binary/text, a schema is optional — produce a primitive TypeRef\n    if (encoding === 'binary') {\n      return { body: { kind: 'primitive', type: 'string', format: 'binary' }, encoding };\n    }\n    if (encoding === 'text') {\n      return { body: { kind: 'primitive', type: 'string' }, encoding };\n    }\n    return {};\n  }\n\n  const rawName = op?.operationId\n    ? toPascalCase(normalizeOperationIdForNaming(op.operationId)) + 'Request'\n    : 'RequestBody';\n  const contextName = cleanSchemaName(rawName);\n\n  // If the request body is an inline object with properties, extract it as a model\n  if (schema.properties && (schema.type === 'object' || !schema.type)) {\n    const requiredSet = new Set(schema.required ?? []);\n    const fields: Field[] = [];\n    for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {\n      if (!fieldSchema) continue;\n      fields.push(buildFieldFromSchema(fieldName, fieldSchema, contextName, requiredSet));\n    }\n    inlineModels.push({ name: contextName, description: undefined, fields });\n    return { body: { kind: 'model', name: contextName }, encoding };\n  }\n\n  // If the request body is a oneOf, extract each variant as an inline model\n  // and build a union type pointing to them by name.\n  if (schema.oneOf) {\n    const variants: TypeRef[] = [];\n\n    for (const variant of schema.oneOf) {\n      if (variant.$ref) {\n        const ref = schemaToTypeRef(variant, contextName);\n        variants.push(ref);\n      } else if (variant.type === 'null') {\n        // skip null variant in union, handle separately\n      } else if (variant.properties && (variant.type === 'object' || !variant.type)) {\n        const variantName = deriveOneOfVariantName(variant, contextName, inlineModels);\n        const requiredSet = new Set(variant.required ?? []);\n        const fields: Field[] = [];\n        for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n          if (!fieldSchema) continue;\n          fields.push(buildFieldFromSchema(fieldName, fieldSchema, variantName, requiredSet));\n        }\n        inlineModels.push({ name: variantName, description: variant.description, fields });\n        variants.push({ kind: 'model', name: variantName });\n      } else {\n        variants.push(schemaToTypeRef(variant, contextName));\n      }\n    }\n\n    const hasNull = schema.oneOf.some(\n      (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n    );\n    const union: TypeRef = {\n      kind: 'union',\n      variants,\n      ...(schema.discriminator\n        ? {\n            discriminator: { property: schema.discriminator.propertyName, mapping: schema.discriminator.mapping ?? {} },\n          }\n        : {}),\n    };\n    const body = hasNull ? ({ kind: 'nullable', inner: union } as TypeRef) : union;\n    return { body, encoding };\n  }\n\n  return { body: schemaToTypeRef(schema, contextName), encoding };\n}\n\n/** Derive a unique variant name for a oneOf inline model. */\nfunction deriveOneOfVariantName(variant: SchemaObject, baseName: string, existingModels: Model[]): string {\n  // Try to use a distinguishing property (e.g., \"grant_type\" field's const/enum value)\n  if (variant.properties) {\n    for (const [, propSchema] of Object.entries(variant.properties)) {\n      if (propSchema?.const && typeof propSchema.const === 'string') {\n        return toPascalCase(propSchema.const) + baseName.replace(/Request$/, '') + 'Request';\n      }\n    }\n  }\n  // Fallback: append a numeric suffix\n  const existingNames = new Set(existingModels.map((m) => m.name));\n  let name = baseName;\n  let suffix = 2;\n  while (existingNames.has(name)) {\n    name = `${baseName}${suffix}`;\n    suffix++;\n  }\n  return name;\n}\n\nfunction deriveResponseName(op: OperationObject | undefined, path: string, method: HttpMethod): string {\n  if (op?.operationId) {\n    return cleanSchemaName(toPascalCase(normalizeOperationIdForNaming(op.operationId)) + 'Response');\n  }\n  const segments = path.split('/').filter(Boolean);\n  const resource = segments[0] ?? 'Unknown';\n  return toPascalCase(resource) + toPascalCase(method) + 'Response';\n}\n\nfunction extractResponses(\n  responses?: Record<string, ResponseObject>,\n  op?: OperationObject,\n  path?: string,\n  method?: HttpMethod,\n): {\n  response: TypeRef;\n  successResponses?: SuccessResponse[];\n  errors: ErrorResponse[];\n  inlineModels: Model[];\n  isPaginated: boolean;\n  dataPath?: string;\n  itemType?: TypeRef;\n} {\n  const errors: ErrorResponse[] = [];\n  let response: TypeRef = { kind: 'primitive', type: 'string' };\n  let inlineModels: Model[] = [];\n  let isPaginated = false;\n  let dataPath: string | undefined;\n  let itemType: TypeRef | undefined;\n\n  if (!responses) return { response, errors, inlineModels, isPaginated };\n\n  const allSuccessResponses: SuccessResponse[] = [];\n\n  for (const [statusCode, resp] of Object.entries(responses)) {\n    const code = parseInt(statusCode, 10);\n\n    if (code >= 200 && code < 300) {\n      let extractedType: TypeRef = { kind: 'primitive', type: 'unknown' };\n      const jsonContent = resp.content?.['application/json'];\n      if (jsonContent?.schema) {\n        const contextName = deriveResponseName(op, path ?? '/', method ?? 'get');\n        const result = classifyAndExtractResponse(jsonContent.schema, contextName);\n        extractedType = result.response;\n        // Keep track of inline models and pagination from the latest 2xx with a schema\n        inlineModels = result.inlineModels;\n        isPaginated = result.isPaginated;\n        dataPath = result.dataPath;\n        itemType = result.itemType;\n      } else if (resp.content) {\n        // Handle non-JSON response content types (text/plain, binary, XML, etc.)\n        if (resp.content['application/octet-stream'] || resp.content['application/pdf']) {\n          extractedType = { kind: 'primitive', type: 'string', format: 'binary' };\n        } else if (\n          resp.content['text/plain'] ||\n          resp.content['text/html'] ||\n          resp.content['text/xml'] ||\n          resp.content['application/xml']\n        ) {\n          extractedType = { kind: 'primitive', type: 'string' };\n        } else {\n          // Try the first available content type's schema\n          const firstKey = Object.keys(resp.content)[0];\n          if (firstKey) {\n            const firstContent = resp.content[firstKey];\n            if (firstContent?.schema) {\n              extractedType = schemaToTypeRef(\n                firstContent.schema,\n                deriveResponseName(op, path ?? '/', method ?? 'get'),\n              );\n            }\n          }\n        }\n      }\n      allSuccessResponses.push({ statusCode: code, type: extractedType });\n    } else if (code >= 300 && code < 400) {\n      // 3xx redirects — include so emitter can detect redirect endpoints\n      allSuccessResponses.push({ statusCode: code, type: { kind: 'primitive', type: 'unknown' } });\n    } else if (code >= 400) {\n      const jsonContent = resp.content?.['application/json'];\n      const type = jsonContent?.schema ? schemaToTypeRef(jsonContent.schema, `Error${code}`) : undefined;\n      errors.push({ statusCode: code, type });\n    }\n  }\n\n  // Primary response = lowest 2xx with a body schema, falling back to first 2xx\n  if (allSuccessResponses.length > 0) {\n    const sorted = [...allSuccessResponses].sort((a, b) => a.statusCode - b.statusCode);\n    const primary =\n      sorted.find((r) => r.type.kind !== 'primitive' || (r.type as { type: string }).type !== 'unknown') ?? sorted[0];\n    response = primary.type;\n  }\n\n  const successResponses = allSuccessResponses.length > 1 ? allSuccessResponses : undefined;\n\n  return { response, successResponses, errors, inlineModels, isPaginated, dataPath, itemType };\n}\n","import type { Model, Service, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nfunction keepLargestByName(models: Model[]): Model[] {\n  const byName = new Map<string, Model>();\n  for (const model of models) {\n    const existing = byName.get(model.name);\n    if (!existing || model.fields.length > existing.fields.length) {\n      byName.set(model.name, model);\n    }\n  }\n  return [...byName.values()];\n}\n\nfunction rewriteModelRef(ref: TypeRef, oldName: string, newName: string): void {\n  walkTypeRef(ref, {\n    model: (r) => {\n      if (r.name === oldName) (r as { name: string }).name = newName;\n    },\n  });\n}\n\nfunction rewriteModelRefs(models: Model[], services: Service[], oldName: string, newName: string): void {\n  for (const model of models) {\n    for (const field of model.fields) {\n      rewriteModelRef(field.type, oldName, newName);\n    }\n  }\n  for (const service of services) {\n    for (const op of service.operations) {\n      rewriteModelRef(op.response, oldName, newName);\n      if (op.requestBody) {\n        rewriteModelRef(op.requestBody, oldName, newName);\n      }\n    }\n  }\n}\n\nexport function mergeInlineResponseModels(schemaModels: Model[], inlineModels: Model[]): Model[] {\n  const mergedSchemaModels = [...schemaModels];\n  const schemaModelNames = new Set(mergedSchemaModels.map((m) => m.name));\n  const schemaModelsByName = new Map(mergedSchemaModels.map((m) => [m.name, m]));\n\n  const deduplicatedInlineModels = inlineModels.filter((model) => {\n    if (!schemaModelNames.has(model.name)) return true;\n\n    const existing = schemaModelsByName.get(model.name)!;\n    const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n    const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n    const hasDifference =\n      model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n      existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n    if (hasDifference && model.fields.length > existing.fields.length) {\n      const idx = mergedSchemaModels.indexOf(existing);\n      if (idx !== -1) mergedSchemaModels[idx] = model;\n      schemaModelsByName.set(model.name, model);\n      console.warn(\n        `[oagen] Warning: Inline model \"${model.name}\" has more fields than component schema (${model.fields.length} vs ${existing.fields.length}) — using inline response model`,\n      );\n    } else if (hasDifference) {\n      console.warn(\n        `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n      );\n    }\n\n    return false;\n  });\n\n  return [...mergedSchemaModels, ...keepLargestByName(deduplicatedInlineModels)];\n}\n\nexport function mergeFieldInlineModels(existingModels: Model[], fieldInlineModels: Model[]): Model[] {\n  const modelNames = new Set(existingModels.map((m) => m.name));\n  const modelsByName = new Map(existingModels.map((m) => [m.name, m]));\n\n  const deduplicatedFieldModels = fieldInlineModels.filter((model) => {\n    if (!modelNames.has(model.name)) return true;\n\n    const existing = modelsByName.get(model.name)!;\n    const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n    const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n    const hasDifference =\n      model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n      existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n    if (hasDifference) {\n      console.warn(\n        `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n      );\n    }\n\n    return false;\n  });\n\n  return [...existingModels, ...keepLargestByName(deduplicatedFieldModels)];\n}\n\nfunction hasModelConstDiscriminant(model: Model): boolean {\n  return model.fields.some(\n    (f) => (f.name === 'object' || f.name === 'type') && f.type.kind === 'literal' && typeof f.type.value === 'string',\n  );\n}\n\nfunction isModelReferencedByOthers(name: string, models: Model[], excludeNames: Set<string>): boolean {\n  for (const model of models) {\n    if (excludeNames.has(model.name)) continue;\n    for (const field of model.fields) {\n      let found = false;\n      walkTypeRef(field.type, {\n        model: (r) => {\n          if (r.name === name) found = true;\n        },\n      });\n      if (found) return true;\n    }\n  }\n  return false;\n}\n\nexport function collapseJsonSuffixModels(models: Model[], services: Service[]): Model[] {\n  const normalizedModels = [...models];\n  const byName = new Map(normalizedModels.map((m) => [m.name, m]));\n\n  // Pass 1: collect merge candidates\n  const mergeCandidates: Array<{ jsonModel: Model; baseModel: Model }> = [];\n  for (const model of normalizedModels) {\n    if (!model.name.endsWith('Json')) continue;\n\n    const baseName = model.name.slice(0, -4);\n    const baseModel = byName.get(baseName);\n    if (!baseModel || model.fields.length <= baseModel.fields.length) continue;\n\n    const isSuperset = baseModel.fields.every((f) => model.fields.some((mf) => mf.name === f.name));\n    if (!isSuperset) continue;\n\n    // Guard: both models have a const discriminant — they are distinct entities\n    if (hasModelConstDiscriminant(model) && hasModelConstDiscriminant(baseModel)) continue;\n\n    // Guard: a third model explicitly references the Json-suffix model\n    if (isModelReferencedByOthers(model.name, normalizedModels, new Set([model.name, baseName]))) continue;\n\n    mergeCandidates.push({ jsonModel: model, baseModel });\n  }\n\n  // Pass 2: apply merges\n  const toRemove = new Set<string>();\n  for (const { jsonModel, baseModel } of mergeCandidates) {\n    baseModel.fields = jsonModel.fields;\n    toRemove.add(jsonModel.name);\n    rewriteModelRefs(normalizedModels, services, jsonModel.name, baseModel.name);\n    console.warn(\n      `[oagen] Merged \"${jsonModel.name}\" into \"${baseModel.name}\" (${jsonModel.fields.length} fields, superset)`,\n    );\n  }\n\n  // Pass 3: cascade renames to inline children of collapsed Json-suffix models.\n  // e.g. when AuditLogSchemaJson → AuditLogSchema, also rename\n  // AuditLogSchemaJsonTarget → AuditLogSchemaTarget.\n  for (const { jsonModel, baseModel } of mergeCandidates) {\n    const jsonPrefix = jsonModel.name;\n    const basePrefix = baseModel.name;\n\n    for (const model of normalizedModels) {\n      if (toRemove.has(model.name)) continue;\n      if (model.name.length <= jsonPrefix.length) continue;\n      if (!model.name.startsWith(jsonPrefix)) continue;\n\n      const newName = basePrefix + model.name.slice(jsonPrefix.length);\n      const existing = byName.get(newName);\n\n      if (existing && !toRemove.has(existing.name)) {\n        toRemove.add(model.name);\n        rewriteModelRefs(normalizedModels, services, model.name, newName);\n        console.warn(`[oagen] Collapsed child \"${model.name}\" into existing \"${newName}\"`);\n      } else {\n        rewriteModelRefs(normalizedModels, services, model.name, newName);\n        model.name = newName;\n        byName.set(newName, model);\n        console.warn(`[oagen] Renamed child \"${jsonPrefix}…\" → \"${newName}\"`);\n      }\n    }\n  }\n\n  return normalizedModels.filter((m) => !toRemove.has(m.name));\n}\n","import type { Enum, Model, Service } from '../ir/types.js';\nimport { collectInlineEnumFromRef } from './schemas.js';\n\nexport function collectInlineEnumsFromModels(models: Model[], enums: Enum[]): void {\n  const enumNames = new Set(enums.map((e) => e.name));\n  for (const model of models) {\n    for (const field of model.fields) {\n      collectInlineEnumFromRef(field.type, enums, enumNames);\n    }\n  }\n}\n\n/**\n * Collect inline enum definitions from operation parameters (query, path, header)\n * and promote them to top-level enums so emitters can generate typed enum files.\n */\nexport function collectInlineEnumsFromOperations(services: Service[], enums: Enum[]): void {\n  const enumNames = new Set(enums.map((e) => e.name));\n  for (const service of services) {\n    for (const op of service.operations) {\n      for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n        collectInlineEnumFromRef(param.type, enums, enumNames);\n      }\n    }\n  }\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nexport function validateModelRefs(spec: ApiSpec): void {\n  const knownNames = new Set<string>();\n  for (const m of spec.models) knownNames.add(m.name);\n  for (const e of spec.enums) knownNames.add(e.name);\n\n  function walkRef(ref: TypeRef, context: string): void {\n    walkTypeRef(ref, {\n      model: (r) => {\n        if (!knownNames.has(r.name)) {\n          console.warn(`[oagen] Warning: Unresolved model reference \"${r.name}\" (context: ${context})`);\n        }\n      },\n    });\n  }\n\n  for (const model of spec.models) {\n    for (const field of model.fields) {\n      walkRef(field.type, `${model.name}.${field.name}`);\n    }\n  }\n\n  for (const service of spec.services) {\n    for (const op of service.operations) {\n      for (const p of [...op.pathParams, ...op.queryParams, ...op.headerParams]) {\n        walkRef(p.type, `${service.name}.${op.name}.${p.name}`);\n      }\n      if (op.requestBody) walkRef(op.requestBody, `${service.name}.${op.name}.requestBody`);\n      walkRef(op.response, `${service.name}.${op.name}.response`);\n    }\n  }\n}\n","import type { ApiSpec, AuthScheme, ServerEntry } from '../ir/types.js';\nimport { defaultSdkBehavior } from '../ir/sdk-behavior.js';\nimport { SpecParseError } from '../errors.js';\nimport { loadAndBundleSpec } from './refs.js';\nimport { extractSchemas, extractInlineModelsFromSchemas, clearSchemaNameTransform } from './schemas.js';\nimport { extractOperations } from './operations.js';\nimport {\n  mergeInlineResponseModels,\n  collapseJsonSuffixModels,\n  mergeFieldInlineModels,\n} from './normalize-inline-models.js';\nimport { collectInlineEnumsFromModels, collectInlineEnumsFromOperations } from './collect-inline-enums.js';\nimport { validateModelRefs } from './normalize-model-refs.js';\n\n/**\n * A bundled OpenAPI document, post-`$ref` resolution but pre-IR extraction.\n *\n * This is the shape the spec author wrote, with external refs inlined and\n * internal refs left intact. It is intentionally loose (`Record<string,\n * unknown>`) so `transformSpec` can reach arbitrary spec extensions without\n * fighting types — narrow with `as` at use sites.\n */\nexport type OpenApiDocument = Record<string, unknown>;\n\nexport interface ParseOptions {\n  operationIdTransform?: (id: string) => string;\n  schemaNameTransform?: (name: string) => string;\n  /**\n   * Domain-facing field-name overrides, keyed by IR model name then wire field\n   * name: `{ Connection: { connection_type: 'type' } }`. Sets `Field.domainName`\n   * so emitters expose the field under the friendlier name while keeping the\n   * wire key. Language-agnostic — honored by any emitter that reads `domainName`.\n   */\n  fieldHints?: Record<string, Record<string, string>>;\n  /**\n   * Pre-IR overlay applied to the bundled OpenAPI document before any IR\n   * extraction runs. Use this when the upstream spec can't be changed but you\n   * need to patch around a spec quirk that would otherwise emit a breaking SDK\n   * change — e.g. rewriting a path's response `$ref` back to its prior schema,\n   * merging the new fields onto the prior schema, and dropping the fork.\n   *\n   * The function may mutate the document in place and return it, or return a\n   * new object; the returned value is what the rest of oagen sees.\n   *\n   * Runs once, after `$ref` bundling and before schema/operation extraction.\n   * If you need to inspect the resulting IR instead, post-process the\n   * `ApiSpec` returned by `parseSpec`.\n   */\n  transformSpec?: (spec: OpenApiDocument) => OpenApiDocument;\n}\n\nexport async function parseSpec(specPath: string, options?: ParseOptions): Promise<ApiSpec> {\n  const { parsed } = await loadAndBundleSpec(specPath);\n  const transformed = options?.transformSpec ? options.transformSpec(parsed) : parsed;\n\n  const spec = transformed as {\n    openapi?: string;\n    info?: { title?: string; version?: string; description?: string };\n    servers?: Array<{ url?: string; description?: string }>;\n    paths?: Record<string, unknown>;\n    components?: {\n      schemas?: Record<string, unknown>;\n      securitySchemes?: Record<\n        string,\n        { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n      >;\n    };\n  };\n\n  // Validate OpenAPI version\n  const version = spec.openapi ?? '';\n  if (!version.startsWith('3.')) {\n    throw new SpecParseError(\n      `Unsupported OpenAPI version: ${version}. oagen requires OpenAPI 3.x`,\n      `Update the spec to OpenAPI 3.0 or 3.1. If you are using Swagger 2.x, convert it first with \\`npx swagger2openapi ${specPath}\\`.`,\n    );\n  }\n\n  const { models, enums } = extractSchemas(\n    spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n    { schemaNameTransform: options?.schemaNameTransform },\n  );\n\n  const { services, inlineModels } = extractOperations(\n    spec.paths as Record<string, Record<string, unknown>> | undefined,\n    options?.operationIdTransform,\n    spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n  );\n\n  const responseNormalizedModels = mergeInlineResponseModels(models, inlineModels);\n\n  // Extract inline models from model field definitions (objects/arrays with properties).\n  // schemaNameTransform is kept active so inline child names use the\n  // transformed parent name (e.g. AuditLogSchemaJson→AuditLogSchema yields\n  // AuditLogSchemaTarget, not AuditLogSchemaJsonTarget).\n  const fieldInlineModels = extractInlineModelsFromSchemas(\n    spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n  );\n  clearSchemaNameTransform();\n  const fieldMergedModels = mergeFieldInlineModels(responseNormalizedModels, fieldInlineModels);\n  const finalModels = collapseJsonSuffixModels(fieldMergedModels, services);\n  applyFieldHints(finalModels, options?.fieldHints);\n  collectInlineEnumsFromModels(finalModels, enums);\n  collectInlineEnumsFromOperations(services, enums);\n\n  const auth = extractAuthSchemes(spec.components?.securitySchemes);\n\n  const serverEntries: ServerEntry[] = (spec.servers ?? [])\n    .map((s) => ({ url: s.url ?? '', description: s.description }))\n    .filter((s) => s.url);\n\n  const result: ApiSpec = {\n    name: spec.info?.title ?? 'Unknown API',\n    version: spec.info?.version ?? '0.0.0',\n    description: spec.info?.description,\n    baseUrl: serverEntries[0]?.url ?? '',\n    servers: serverEntries.length > 0 ? serverEntries : undefined,\n    services,\n    models: finalModels,\n    enums,\n    auth,\n    sdk: defaultSdkBehavior(),\n  };\n\n  validateModelRefs(result);\n\n  return result;\n}\n/**\n * Apply `fieldHints` onto the built models, setting `Field.domainName` for each\n * matching (model name, wire field name) pair. Serialization still uses\n * `Field.name`; only the domain-facing identifier changes.\n */\nfunction applyFieldHints(\n  models: import('../ir/types.js').Model[],\n  fieldHints: Record<string, Record<string, string>> | undefined,\n): void {\n  if (!fieldHints) return;\n  for (const model of models) {\n    const hints = fieldHints[model.name];\n    if (!hints) continue;\n    for (const field of model.fields) {\n      const domainName = hints[field.name];\n      if (domainName) field.domainName = domainName;\n    }\n  }\n}\n\n/** Extract authentication schemes from OpenAPI securitySchemes. */\nfunction extractAuthSchemes(\n  securitySchemes?: Record<\n    string,\n    { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n  >,\n): AuthScheme[] | undefined {\n  if (!securitySchemes) return undefined;\n  const schemes: AuthScheme[] = [];\n  for (const [, scheme] of Object.entries(securitySchemes)) {\n    if (scheme.type === 'http' && scheme.scheme === 'bearer') {\n      schemes.push({ kind: 'bearer' });\n    } else if (scheme.type === 'apiKey' && scheme.in && scheme.name) {\n      schemes.push({ kind: 'apiKey', in: scheme.in as 'header' | 'query' | 'cookie', name: scheme.name });\n    } else if (scheme.type === 'oauth2' && scheme.flows) {\n      schemes.push({ kind: 'oauth2', flows: scheme.flows });\n    }\n  }\n  return schemes.length > 0 ? schemes : undefined;\n}\n","/**\n * Shared infrastructure for smoke tests.\n *\n * Types, operation planning, payload generation, ID registry, and capture format\n * used by both raw HTTP and SDK smoke test scripts.\n */\n\nimport 'dotenv/config';\nimport { readFileSync } from 'node:fs';\nimport type { ApiSpec, Operation, Parameter, TypeRef } from '../../src/ir/types.js';\nimport { toSnakeCase, toCamelCase } from '../../src/utils/naming.js';\n\n// Re-export types and functions that external smoke runners need from oagen core.\n// External runners import from '@workos/oagen/smoke' which bundles this module.\nexport { parseSpec } from '../../src/parser/parse.js';\nexport { toCamelCase, toSnakeCase } from '../../src/utils/naming.js';\n\n// ---------------------------------------------------------------------------\n// Capture format\n// ---------------------------------------------------------------------------\n\nexport interface ExchangeProvenance {\n  resolutionTier: 'exact' | 'crud-prefix' | 'fuzzy' | 'manifest';\n  resolutionConfidence: number;\n  sdkMethodName: string;\n  captureIndex: number;\n  totalCaptures: number;\n}\n\nexport interface CapturedExchange {\n  operationId: string;\n  service: string;\n  operationName: string;\n  request: {\n    method: string;\n    path: string;\n    queryParams: Record<string, string>;\n    body: unknown | null;\n  };\n  response: {\n    status: number;\n    body: unknown | null;\n  };\n  outcome: 'success' | 'api-error' | 'skipped';\n  error?: string;\n  /** True when the response status code is not declared in the OpenAPI spec for this operation */\n  unexpectedStatus?: boolean;\n  /** Status codes declared in the OpenAPI spec (success + error codes) */\n  expectedStatusCodes?: number[];\n  durationMs: number;\n  /** How the SDK method was resolved and which capture was selected */\n  provenance?: ExchangeProvenance;\n}\n\nexport interface SmokeResults {\n  source: 'raw' | 'spec-baseline' | `sdk-${string}`;\n  timestamp: string;\n  specVersion: string;\n  exchanges: CapturedExchange[];\n}\n\n// ---------------------------------------------------------------------------\n// Operation planning\n// ---------------------------------------------------------------------------\n\nexport interface PlannedOperation {\n  service: string;\n  operation: Operation;\n}\n\nexport interface PlannedGroup {\n  service: string;\n  operations: PlannedOperation[];\n}\n\n// ---------------------------------------------------------------------------\n// Smoke config — mutable state populated by loadSmokeConfig()\n// ---------------------------------------------------------------------------\n\n/** Operations that require complex preconditions and can't be auto-tested */\nexport let SKIP_OPERATIONS = new Set<string>();\n\n/** Services to skip entirely */\nexport let SKIP_SERVICES = new Set<string>();\n\n/**\n * Services that produce IDs other services depend on should run first.\n * Lower number = runs earlier. Unlisted services default to 50.\n */\nlet SERVICE_PRIORITY: Record<string, number> = {};\n\n/**\n * Map IR service names to SDK property names on the client object.\n * Empty = use toCamelCase(serviceName) as fallback.\n */\nexport let SERVICE_PROPERTY_MAP: Record<string, string> = {};\n\nexport interface SmokeConfig {\n  skipOperations: string[];\n  skipServices: string[];\n  servicePriority: Record<string, number>;\n  servicePropertyMap: Record<string, string>;\n}\n\n/** Load smoke test configuration from a JSON file */\nexport function loadSmokeConfig(configPath?: string): void {\n  if (!configPath) return;\n  const raw = readFileSync(configPath, 'utf-8');\n  const config: SmokeConfig = JSON.parse(raw);\n\n  if (config.skipOperations) SKIP_OPERATIONS = new Set(config.skipOperations);\n  if (config.skipServices) SKIP_SERVICES = new Set(config.skipServices);\n  if (config.servicePriority) SERVICE_PRIORITY = config.servicePriority;\n  if (config.servicePropertyMap) SERVICE_PROPERTY_MAP = config.servicePropertyMap;\n}\n\n/** Return the current smoke config values (for diff.ts to consume) */\nexport function getSmokeConfig() {\n  return {\n    skipOperations: SKIP_OPERATIONS,\n    skipServices: SKIP_SERVICES,\n    servicePriority: SERVICE_PRIORITY,\n    servicePropertyMap: SERVICE_PROPERTY_MAP,\n  };\n}\n\n/**\n * Assign a numeric sort key to an operation so that ID-producing operations\n * (parameterless creates and lists) run before ID-consuming ones.\n */\nfunction operationSortKey(op: Operation): number {\n  const hasParams = op.pathParams.length > 0;\n  const method = op.httpMethod;\n\n  if (method === 'post' && !hasParams) return 0; // top-level create\n  if (method === 'get' && !hasParams && op.pagination) return 1; // top-level list\n  if (method === 'get' && !hasParams) return 2; // top-level singular GET\n  if (method === 'post' && hasParams) return 3; // sub-entity create\n  if (method === 'get' && hasParams && op.pagination) return 4; // sub-entity list\n  if (method === 'get' && hasParams) return 5; // singular GET by ID\n  if (method === 'put' || method === 'patch') return 6; // update\n  if (method === 'delete') return 7; // delete\n  return 99;\n}\n\nexport function planOperations(spec: ApiSpec): PlannedGroup[] {\n  const groups: PlannedGroup[] = [];\n\n  for (const service of spec.services) {\n    if (SKIP_SERVICES.has(service.name)) continue;\n\n    const ops: PlannedOperation[] = [];\n    for (const op of service.operations) {\n      if (SKIP_OPERATIONS.has(op.name)) continue;\n\n      ops.push({ service: service.name, operation: op });\n    }\n\n    if (ops.length === 0) continue;\n\n    // Sort to maximize ID availability:\n    //   1. Parameterless POSTs (create new top-level entities → produce IDs)\n    //   2. Parameterless list GETs (discover existing IDs)\n    //   3. Parameterized POSTs (create sub-entities, need parent IDs)\n    //   4. Parameterized list GETs\n    //   5. Parameterized singular GETs (retrieve by ID)\n    //   6. PUT/PATCH (update)\n    //   7. DELETE\n    ops.sort((a, b) => {\n      return operationSortKey(a.operation) - operationSortKey(b.operation);\n    });\n\n    groups.push({ service: service.name, operations: ops });\n  }\n\n  // Sort service groups so ID-producing services run first\n  groups.sort((a, b) => {\n    const aPri = SERVICE_PRIORITY[a.service] ?? 50;\n    const bPri = SERVICE_PRIORITY[b.service] ?? 50;\n    return aPri - bPri;\n  });\n\n  return groups;\n}\n\n// ---------------------------------------------------------------------------\n// Wave-based operation planning for batched runners\n// ---------------------------------------------------------------------------\n\n/**\n * A single wave of operations that can be planned and executed together.\n * Wave 0 contains parameterless operations. Subsequent waves contain\n * operations whose path params became resolvable after earlier waves ran.\n */\nexport interface OperationWave {\n  /** Operations in this wave, with pre-resolved path params */\n  calls: Array<{\n    op: Operation;\n    irService: string;\n    pathParams: Record<string, string>;\n  }>;\n}\n\n/**\n * Plan operations in waves so that batched runners can execute each wave,\n * extract IDs from responses, then plan the next wave.\n *\n * Returns an iterator that yields one wave at a time. The caller must\n * execute each wave and populate the IdRegistry before calling next().\n *\n * @param groups - service groups from planOperations()\n * @param ids - the IdRegistry (mutated by the caller between waves)\n * @param resolveMethod - optional filter; return null to skip an operation\n */\nexport function* planWaves(\n  groups: PlannedGroup[],\n  ids: IdRegistry,\n  resolveMethod?: (op: Operation, irService: string) => boolean,\n): Generator<OperationWave, PlannedOperation[], void> {\n  // Flatten all operations into a single ordered list\n  const remaining: PlannedOperation[] = [];\n  for (const group of groups) {\n    for (const planned of group.operations) {\n      remaining.push(planned);\n    }\n  }\n\n  // Track which operations have been emitted\n  const emitted = new Set<number>();\n  const skipped: PlannedOperation[] = [];\n\n  // Pre-filter: mark operations that fail the resolveMethod check as skipped\n  for (let i = 0; i < remaining.length; i++) {\n    const { operation: op, service: irService } = remaining[i];\n    if (resolveMethod && !resolveMethod(op, irService)) {\n      emitted.add(i);\n      skipped.push(remaining[i]);\n    }\n  }\n\n  // Wave 0: operations with no path params\n  let wave: OperationWave = { calls: [] };\n  for (let i = 0; i < remaining.length; i++) {\n    if (emitted.has(i)) continue;\n    const { operation: op, service: irService } = remaining[i];\n    if (op.pathParams.length === 0) {\n      wave.calls.push({ op, irService, pathParams: {} });\n      emitted.add(i);\n    }\n  }\n\n  if (wave.calls.length > 0) {\n    yield wave;\n  }\n\n  // Subsequent waves: try to resolve remaining operations\n  let madeProgress = true;\n  while (madeProgress) {\n    madeProgress = false;\n    wave = { calls: [] };\n\n    for (let i = 0; i < remaining.length; i++) {\n      if (emitted.has(i)) continue;\n      const { operation: op, service: irService } = remaining[i];\n\n      const resolved = ids.resolvePathParams(op, irService);\n      if (resolved) {\n        wave.calls.push({ op, irService, pathParams: resolved });\n        emitted.add(i);\n        madeProgress = true;\n      }\n    }\n\n    if (wave.calls.length > 0) {\n      yield wave;\n    }\n  }\n\n  // Collect truly unresolvable operations for the caller to mark as skipped\n  const unresolved: PlannedOperation[] = [];\n  for (let i = 0; i < remaining.length; i++) {\n    if (!emitted.has(i)) {\n      unresolved.push(remaining[i]);\n    }\n  }\n  return unresolved;\n}\n\n// ---------------------------------------------------------------------------\n// Payload generation\n// ---------------------------------------------------------------------------\n\nexport function generateFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n  switch (typeRef.kind) {\n    case 'primitive':\n      return generatePrimitiveFixture(typeRef.type, typeRef.format, fieldName);\n    case 'array':\n      return [generateFixtureValue(typeRef.items, fieldName, spec)];\n    case 'model': {\n      const model = spec.models.find((m) => m.name === typeRef.name);\n      if (model) {\n        const obj: Record<string, unknown> = {};\n        for (const field of model.fields) {\n          if (field.required) {\n            obj[toSnakeCase(field.name)] = generateFixtureValue(field.type, field.name, spec);\n          }\n        }\n        return obj;\n      }\n      return {};\n    }\n    case 'enum': {\n      const e = spec.enums.find((en) => en.name === typeRef.name);\n      return e?.values[0]?.value ?? 'unknown';\n    }\n    case 'nullable':\n      return generateFixtureValue(typeRef.inner, fieldName, spec);\n    case 'union':\n      if (typeRef.variants.length > 0) {\n        return generateFixtureValue(typeRef.variants[0], fieldName, spec);\n      }\n      return null;\n  }\n}\n\nfunction generatePrimitiveFixture(type: string, format: string | undefined, fieldName: string): unknown {\n  if (type === 'string') {\n    if (format === 'uuid') return '550e8400-e29b-41d4-a716-446655440000';\n    if (format === 'date') return '2024-01-01';\n    if (format === 'date-time') return '2024-01-01T00:00:00Z';\n    if (format === 'email') return 'test@example.com';\n    if (format === 'uri' || format === 'url') return 'https://example.com';\n    return `test_${toSnakeCase(fieldName)}`;\n  }\n  if (type === 'integer') return 1;\n  if (type === 'number') return 1.0;\n  if (type === 'boolean') return true;\n  return null;\n}\n\n/** Generate a snake_case request body payload from an operation's requestBody type */\nexport function generatePayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n  if (!op.requestBody) return null;\n\n  const bodyType = op.requestBody;\n  if (bodyType.kind === 'model') {\n    const model = spec.models.find((m) => m.name === bodyType.name);\n    if (!model) return {};\n\n    const payload: Record<string, unknown> = {};\n    for (const field of model.fields) {\n      if (!field.required) continue;\n      const key = toSnakeCase(field.name);\n      let value = generateFixtureValue(field.type, field.name, spec);\n\n      // Inject uniqueness markers for name/slug fields\n      if ((key === 'name' || key === 'slug') && typeof value === 'string') {\n        value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n      }\n      payload[key] = value;\n    }\n    return payload;\n  }\n\n  // Fallback for non-model body types\n  return {};\n}\n\n/** Generate a fixture value with SDK-friendly types (e.g. Date objects for date-time) */\nfunction generateSDKFixtureValue(typeRef: TypeRef, fieldName: string, spec: ApiSpec): unknown {\n  const value = generateFixtureValue(typeRef, fieldName, spec);\n  // SDK methods expect Date objects for date-time fields, not ISO strings\n  if (typeRef.kind === 'primitive' && typeRef.format === 'date-time' && typeof value === 'string') {\n    return new Date(value);\n  }\n  return value;\n}\n\n/** Generate a camelCase payload for SDK method calls */\nexport function generateCamelPayload(op: Operation, spec: ApiSpec): Record<string, unknown> | null {\n  if (!op.requestBody) return null;\n\n  const bodyType = op.requestBody;\n  if (bodyType.kind === 'model') {\n    const model = spec.models.find((m) => m.name === bodyType.name);\n    if (!model) return {};\n\n    const payload: Record<string, unknown> = {};\n    for (const field of model.fields) {\n      if (!field.required) continue;\n      const key = toCamelCase(field.name);\n      let value = generateSDKFixtureValue(field.type, field.name, spec);\n\n      if ((field.name === 'name' || field.name === 'slug') && typeof value === 'string') {\n        value = `smoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n      }\n      payload[key] = value;\n    }\n    return payload;\n  }\n\n  return {};\n}\n\n/** Generate query params for an operation (required params only, plus limit=1 for lists) */\nexport function generateQueryParams(op: Operation, spec: ApiSpec): Record<string, string> {\n  const params: Record<string, string> = {};\n\n  if (op.pagination) {\n    params['limit'] = '1';\n  }\n\n  for (const p of op.queryParams) {\n    if (!p.required) continue;\n    const value = generateFixtureValue(p.type, p.name, spec);\n    params[toSnakeCase(p.name)] = String(value);\n  }\n\n  // Sort by key\n  const sorted: Record<string, string> = {};\n  for (const key of Object.keys(params).sort()) {\n    sorted[key] = params[key];\n  }\n  return sorted;\n}\n\n/** Generate camelCase query params for SDK method calls */\nexport function generateCamelQueryParams(op: Operation, spec: ApiSpec): Record<string, unknown> {\n  const params: Record<string, unknown> = {};\n\n  if (op.pagination) {\n    params['limit'] = 1;\n  }\n\n  for (const p of op.queryParams) {\n    if (!p.required) continue;\n    const value = generateFixtureValue(p.type, p.name, spec);\n    params[toCamelCase(p.name)] = value;\n  }\n\n  return params;\n}\n\n// ---------------------------------------------------------------------------\n// ID Registry\n// ---------------------------------------------------------------------------\n\nexport class IdRegistry {\n  private ids = new Map<string, string>();\n\n  set(service: string, field: string, value: string): void {\n    this.ids.set(`${service}.${field}`, value);\n  }\n\n  get(service: string, field: string): string | undefined {\n    return this.ids.get(`${service}.${field}`);\n  }\n\n  /** Resolve path parameters for an operation using stored IDs */\n  resolvePathParams(op: Operation, service: string): Record<string, string> | null {\n    const resolved: Record<string, string> = {};\n    for (const p of op.pathParams) {\n      const value =\n        this.get(service, p.name) ||\n        this.get(service, 'id') ||\n        this.findAcrossServices(p.name) ||\n        this.resolveFromParamName(p.name) ||\n        this.resolveFromExample(p);\n\n      if (!value) return null;\n      resolved[p.name] = value;\n    }\n    return resolved;\n  }\n\n  /** Try to find a param value across all services */\n  private findAcrossServices(field: string): string | undefined {\n    for (const [key, value] of this.ids.entries()) {\n      if (key.endsWith(`.${field}`)) return value;\n    }\n    // Also try snake_case variant: \"organizationId\" → \"organization_id\"\n    const snakeField = toSnakeCase(field);\n    if (snakeField !== field) {\n      for (const [key, value] of this.ids.entries()) {\n        if (key.endsWith(`.${snakeField}`)) return value;\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * Resolve a path param like \"organizationId\" by mapping it to the\n   * service that stores that entity's ID (e.g. Organizations.id).\n   * Also handles snake_case suffixed with _id by stripping the suffix\n   * and looking up the pluralized service name.\n   */\n  private resolveFromParamName(paramName: string): string | undefined {\n    // Infer from param name: \"resource_id\" → \"Resources\", \"role_assignment_id\" → \"RoleAssignments\"\n    // Handle snake_case: strip trailing _id, PascalCase+pluralize the rest\n    if (paramName.endsWith('_id')) {\n      const base = paramName.slice(0, -3); // e.g. \"resource_type\" from \"resource_type_id\"\n      const pascal = base\n        .split('_')\n        .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n        .join('');\n      const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n      const val = this.get(plural, 'id') || this.get(plural, 'slug');\n      if (val) return val;\n\n      // Fallback: find any service whose name ends with the plural suffix\n      // e.g. \"user_id\" → \"Users\" not found → try \"UserManagementUsers\"\n      const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n      if (suffixVal) return suffixVal;\n    }\n\n    // Handle camelCase: \"resourceId\" → strip \"Id\", pluralize → \"Resources\"\n    if (paramName.endsWith('Id') && paramName.length > 2) {\n      const base = paramName.slice(0, -2); // e.g. \"organization\"\n      const pascal = base.charAt(0).toUpperCase() + base.slice(1);\n      const plural = pascal.endsWith('s') ? pascal : pascal + 's';\n      const val = this.get(plural, 'id') || this.get(plural, 'slug');\n      if (val) return val;\n\n      // Fallback: find any service whose name ends with the plural suffix\n      const suffixVal = this.findByServiceSuffix(plural, 'id') || this.findByServiceSuffix(plural, 'slug');\n      if (suffixVal) return suffixVal;\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Find a value by looking for any service name that ends with the given suffix.\n   * e.g. suffix \"Users\" matches \"UserManagementUsers.id\"\n   */\n  private findByServiceSuffix(suffix: string, field: string): string | undefined {\n    for (const [key, value] of this.ids.entries()) {\n      if (key.endsWith(`.${field}`)) {\n        const servicePart = key.slice(0, -(field.length + 1));\n        if (servicePart.endsWith(suffix)) {\n          return value;\n        }\n      }\n    }\n    return undefined;\n  }\n\n  /**\n   * Last-resort fallback: use the spec's example or default value for a parameter.\n   * Many path params (e.g. actionName, slug, type) have example values in the spec.\n   */\n  private resolveFromExample(param: Parameter): string | undefined {\n    const value = param.example ?? param.default;\n    if (value !== undefined && value !== null) {\n      return String(value);\n    }\n    return undefined;\n  }\n\n  /**\n   * Extract IDs from a response body and store them.\n   * @param isTopLevel - true for operations without path params (their `id` belongs to this service).\n   *                     false for sub-resource operations (their `id` is a child entity, don't overwrite).\n   */\n  extractAndStore(service: string, responseBody: unknown, isTopLevel = true): void {\n    if (!responseBody || typeof responseBody !== 'object') return;\n\n    const body = responseBody as Record<string, unknown>;\n\n    // Only store direct ID from top-level operations to avoid overwriting\n    // e.g. Organizations.id with an API key ID from /organizations/{id}/api_keys\n    if (isTopLevel) {\n      if (typeof body.id === 'string') {\n        this.set(service, 'id', body.id);\n      }\n\n      // List response: extract from first item\n      if (Array.isArray(body.data) && body.data.length > 0) {\n        const first = body.data[0] as Record<string, unknown> | undefined;\n        if (first && typeof first === 'object') {\n          if (typeof first.id === 'string') {\n            this.set(service, 'id', first.id);\n          }\n          this.extractNestedIds(service, first);\n        }\n      }\n\n      if (typeof body.slug === 'string') this.set(service, 'slug', body.slug);\n      if (typeof body.key === 'string') this.set(service, 'key', body.key);\n    }\n\n    // Always extract nested reference IDs (e.g. organization_id, connection_id)\n    this.extractNestedIds(service, body);\n    if (Array.isArray(body.data) && body.data.length > 0) {\n      const first = body.data[0] as Record<string, unknown> | undefined;\n      if (first && typeof first === 'object') {\n        this.extractNestedIds(service, first);\n      }\n    }\n  }\n\n  /** Extract fields ending in _id or Id and store them for cross-service resolution */\n  private extractNestedIds(service: string, obj: Record<string, unknown>): void {\n    for (const [key, value] of Object.entries(obj)) {\n      if (typeof value !== 'string') continue;\n      if (key === 'id') continue; // already handled\n      // Store fields like \"organization_id\", \"connection_id\" directly\n      if (key.endsWith('_id') || (key.endsWith('Id') && key.length > 2)) {\n        this.set(service, key, value);\n      }\n    }\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Status code checking\n// ---------------------------------------------------------------------------\n\n/** Get the set of status codes declared in the spec for an operation (success + errors) */\nexport function getExpectedStatusCodes(op: Operation): number[] {\n  const codes: number[] = [];\n  // The success response code is implied by HTTP method if not explicit in errors\n  // Common defaults: POST→201, GET→200, PUT→200, PATCH→200, DELETE→204\n  const defaultSuccess: Record<string, number> = {\n    post: 201,\n    get: 200,\n    put: 200,\n    patch: 200,\n    delete: 204,\n  };\n  codes.push(defaultSuccess[op.httpMethod] ?? 200);\n  // Add declared error codes from the spec\n  for (const err of op.errors) {\n    if (!codes.includes(err.statusCode)) {\n      codes.push(err.statusCode);\n    }\n  }\n  return codes.sort((a, b) => a - b);\n}\n\n/** Check if a status code is unexpected (not declared in the spec) */\nexport function isUnexpectedStatus(status: number, op: Operation): boolean {\n  if (status === 0) return false; // skipped or network error, not a status mismatch\n  const expected = getExpectedStatusCodes(op);\n  return !expected.includes(status);\n}\n\n// ---------------------------------------------------------------------------\n// Path resolution\n// ---------------------------------------------------------------------------\n\nexport function resolvePath(op: Operation, pathParams: Record<string, string>): string {\n  let path = op.path;\n  for (const [name, value] of Object.entries(pathParams)) {\n    path = path.replace(`{${name}}`, value);\n  }\n  return path;\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nexport function delay(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function parseCliArgs(): { spec: string; sdkPath?: string; smokeConfig?: string } {\n  const args = process.argv.slice(2);\n  const specIdx = args.indexOf('--spec');\n  const spec = specIdx !== -1 && args[specIdx + 1] ? args[specIdx + 1] : process.env.OPENAPI_SPEC_PATH;\n  if (!spec) {\n    console.error('OpenAPI spec path is required. Set OPENAPI_SPEC_PATH env var or pass --spec <path>.');\n    process.exit(1);\n  }\n  const sdkPathIdx = args.indexOf('--sdk-path');\n  const sdkPath = sdkPathIdx !== -1 && args[sdkPathIdx + 1] ? args[sdkPathIdx + 1] : undefined;\n  const configIdx = args.indexOf('--smoke-config');\n  const smokeConfig = configIdx !== -1 && args[configIdx + 1] ? args[configIdx + 1] : process.env.SMOKE_CONFIG;\n  return { spec, sdkPath, smokeConfig };\n}\n","/**\n * Spec-only baseline generator.\n *\n * Generates expected request structure from the OpenAPI spec alone — no live\n * API needed. Produces a SmokeResults file that the diff tool can compare\n * against SDK smoke test output for offline CRITICAL-level verification.\n *\n * Usage:\n *   OPENAPI_SPEC_PATH=path/to/spec.yaml npm run smoke:baseline\n */\n\nimport { writeFileSync } from 'node:fs';\nimport { parseSpec } from '../../src/parser/parse.js';\nimport {\n  planOperations,\n  generatePayload,\n  generateQueryParams,\n  resolvePath,\n  parseCliArgs,\n  loadSmokeConfig,\n  type CapturedExchange,\n  type SmokeResults,\n} from './shared.js';\n\nasync function main() {\n  const { spec: specPath, smokeConfig } = parseCliArgs();\n  loadSmokeConfig(smokeConfig);\n\n  console.log('Parsing spec...');\n  const spec = await parseSpec(specPath);\n  console.log(`Spec: ${spec.name} v${spec.version}`);\n\n  const groups = planOperations(spec);\n  const exchanges: CapturedExchange[] = [];\n\n  for (const group of groups) {\n    for (const planned of group.operations) {\n      const op = planned.operation;\n      const operationId = `${group.service}.${op.name}`;\n\n      // Build path with placeholder IDs for path params\n      const placeholderParams: Record<string, string> = {};\n      for (const p of op.pathParams) {\n        placeholderParams[p.name] = '<ID>';\n      }\n      const path = resolvePath(op, placeholderParams);\n\n      const queryParams = generateQueryParams(op, spec);\n      const body = generatePayload(op, spec);\n\n      // Default success status by HTTP method\n      const defaultSuccess: Record<string, number> = {\n        post: 201,\n        get: 200,\n        put: 200,\n        patch: 200,\n        delete: 204,\n      };\n      const status = defaultSuccess[op.httpMethod] ?? 200;\n\n      exchanges.push({\n        operationId,\n        service: group.service,\n        operationName: op.name,\n        request: {\n          method: op.httpMethod.toUpperCase(),\n          path,\n          queryParams,\n          body,\n        },\n        response: {\n          status,\n          body: null,\n        },\n        outcome: 'success',\n        durationMs: 0,\n      });\n    }\n  }\n\n  const results: SmokeResults = {\n    source: 'spec-baseline',\n    timestamp: new Date().toISOString(),\n    specVersion: spec.version,\n    exchanges,\n  };\n\n  writeFileSync('smoke-results-spec-baseline.json', JSON.stringify(results, null, 2));\n\n  console.log(`\\nGenerated ${exchanges.length} operations from spec`);\n  console.log('Written to smoke-results-spec-baseline.json');\n}\n\nmain().catch((err) => {\n  console.error('Baseline generation failed:', err);\n  process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqLA,SAAgB,qBAAkC;AAChD,QAAO;EACL,OAAO;GACL,sBAAsB;IAAC;IAAK;IAAK;IAAK;IAAK;IAAI;GAC/C,YAAY;GACZ,wBAAwB;GACxB,gBAAgB;GAChB,SAAS;IACP,cAAc;IACd,YAAY;IACZ,UAAU;IACV,cAAc;IACf;GACF;EACD,QAAQ;GACN,eAAe;IACb,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACN;GACD,iBAAiB;GACjB,iBAAiB;GAClB;EACD,WAAW;GACT,kBAAkB;GAClB,YAAY;GACZ,iBAAiB;GAClB;EACD,YAAY,EACV,iBAAiB,GAClB;EACD,aAAa;GACX,YAAY;GACZ,qBAAqB;GACtB;EACD,SAAS;GACP,SAAS;GACT,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACD;GACF;EACD,WAAW;GACT,uBAAuB;GACvB,uBAAuB;GACvB,cAAc;GACd,gBAAgB;IACd;KAAE,QAAQ;KAAe,WAAW;KAAc;IAClD;KAAE,QAAQ;KAAgB,WAAW;KAAU;IAC/C;KAAE,QAAQ;KAAgB,WAAW;KAAS;IAC9C;KAAE,QAAQ;KAAmB,WAAW;KAAY;IACpD;KAAE,QAAQ;KAAiB,WAAW;KAAW;IAClD;GACF;EACD,cAAc,EACZ,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,EACF;EACD,SAAS,EACP,uBAAuB,IACxB;EACF;;;;;;;;;;;AC5PH,IAAa,aAAb,cAAgC,MAAM;CACpC;CAEA,YAAY,SAAiB,MAAc;EACzC,MAAM,cAAc,OAAO,GAAG,QAAQ,UAAU,SAAS;AACzD,QAAM,YAAY;AAClB,OAAK,OAAO;AACZ,OAAK,OAAO;;;;AAgBhB,IAAa,iBAAb,cAAoC,WAAW;CAC7C,YAAY,SAAiB,MAAc;AACzC,QAAM,SAAS,KAAK;AACpB,OAAK,OAAO;;;;;ACvBhB,eAAsB,kBAAkB,UAAwC;CAC9E,MAAM,eAAe,QAAQ,SAAS;CAOtC,MAAM,SAAS,MAAM,eAAe;EAClC,UANe,uBADD,MAAM,SAAS,cAAc,QAAQ,EACJ,cAAc,aAAa,CAAC,KAAK;EAOhF,QALa,MAAM,aAAa,EAAE,CAAC;EAMnC,OAAO;EACP,qBANe,IAAI,cAAc;EAOjC,aAAa;EACd,CAAC;AAEF,KAAI,OAAO,SAAS,MAAM,MAAM,EAAE,aAAa,QAAQ,CAKrD,OAAM,IAAI,eACR,yBALa,OAAO,SACnB,QAAQ,MAAM,EAAE,aAAa,QAAQ,CACrC,KAAK,MAAM,EAAE,QAAQ,CACrB,KAAK,KAAK,IAGX,8BAA8B,aAAa,oEAAoE,SAAS,wBACzH;AAGH,QAAO;EACL,QAAQ,OAAO,OAAO;EACtB,UAAU;EACX;;;;;;;;;;;;;;;;;ACoNH,SAAgB,YAAY,GAAiB;CAE3C,MAAM,OAAQ,EAAc;CAC5B,MAAM,sBAAM,IAAI,MACd,4BAA4B,KAAK,oGAClC;AACD,KAAI,OAAO;AACX,OAAM;;;;;;;;AASR,SAAgB,YACd,KACA,SAMM;AACN,SAAQ,IAAI,MAAZ;EACE,KAAK;AACH,WAAQ,QAAQ,IAAI;AACpB;EACF,KAAK;AACH,WAAQ,OAAO,IAAI;AACnB;EACF,KAAK;AACH,eAAY,IAAI,OAAO,QAAQ;AAC/B;EACF,KAAK;AACH,eAAY,IAAI,OAAO,QAAQ;AAC/B;EACF,KAAK;AACH,QAAK,MAAM,KAAK,IAAI,SAAU,aAAY,GAAG,QAAQ;AACrD;EACF,KAAK;AACH,OAAI,IAAI,QAAS,aAAY,IAAI,SAAS,QAAQ;AAClD,eAAY,IAAI,WAAW,QAAQ;AACnC;EACF,KAAK;AACH,WAAQ,UAAU,IAAI;AACtB;EACF,KAAK;AACH,WAAQ,YAAY,IAAI;AACxB;EACF,QACE,aAAY,IAAI;;;;;;;;;;AC5StB,MAAM,iBAAuC,CAC3C,CAAC;CAAC;CAAK;CAAK;CAAI,EAAE,MAAM,EACxB,CAAC,CAAC,KAAK,OAAO,EAAE,QAAQ,CACzB;;;;AAKD,SAAS,mBAAmB,OAA2B;CACrD,MAAM,SAAmB,EAAE;CAC3B,IAAI,IAAI;AACR,QAAO,IAAI,MAAM,QAAQ;EACvB,IAAI,UAAU;AACd,OAAK,MAAM,CAAC,SAAS,cAAc,eACjC,KAAI,IAAI,QAAQ,UAAU,MAAM;OACd,QAAQ,OAAO,GAAG,MAAM,MAAM,IAAI,GAAG,aAAa,KAAK,EAAE,EAC5D;AACX,WAAO,KAAK,UAAU;AACtB,SAAK,QAAQ;AACb,cAAU;AACV;;;AAIN,MAAI,CAAC,SAAS;AACZ,UAAO,KAAK,MAAM,GAAG;AACrB;;;AAGJ,QAAO;;;;;;;;;;AAWT,SAAgB,WAAW,GAAqB;AAC9C,KAAI,CAAC,EAAG,QAAO,EAAE;AAWjB,QAAO,mBATO,EACX,QAAQ,uBAAuB,IAAI,CACnC,QAAQ,mBAAmB,SAAS,CACpC,QAAQ,yBAAyB,SAAS,CAC1C,QAAQ,mBAAmB,SAAS,CACpC,QAAQ,mBAAmB,SAAS,CACpC,MAAM,cAAc,CACpB,QAAQ,MAAM,EAAE,SAAS,EAAE,CAEE;;AAGlC,MAAa,cAAc,IAAI,IAAI;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAO;CAAQ;CAAM,CAAC;AAExF,SAAgB,aAAa,GAAW,UAAgC;CACtE,MAAM,SAAS,WAAW,IAAI,IAAI,CAAC,GAAG,aAAa,GAAG,SAAS,CAAC,GAAG;AACnE,QAAO,WAAW,EAAE,CACjB,KAAK,MAAM;EACV,MAAM,QAAQ,EAAE,aAAa;AAC7B,MAAI,OAAO,IAAI,MAAM,CAAE,QAAO;AAE9B,MAAI,UAAU,QAAS,QAAO;AAC9B,SAAO,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,aAAa;GAC3D,CACD,KAAK,GAAG;;AAGb,SAAgB,YAAY,GAAW,UAAgC;CACrE,MAAM,SAAS,WAAW,IAAI,IAAI,CAAC,GAAG,aAAa,GAAG,SAAS,CAAC,GAAG;CACnE,MAAM,QAAQ,WAAW,EAAE;AAC3B,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAO,MACJ,KAAK,GAAG,MAAM;AACb,MAAI,MAAM,EAAG,QAAO,EAAE,aAAa;EACnC,MAAM,QAAQ,EAAE,aAAa;AAC7B,MAAI,OAAO,IAAI,MAAM,CAAE,QAAO;AAC9B,MAAI,UAAU,QAAS,QAAO;AAC9B,SAAO,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,aAAa;GAC3D,CACD,KAAK,GAAG;;AAGb,SAAgB,YAAY,GAAmB;AAC7C,QAAO,WAAW,EAAE,CACjB,KAAK,MAAM,EAAE,aAAa,CAAC,CAC3B,KAAK,IAAI;;AASd,SAAgB,iBAAiB,GAAmB;AAClD,QAAO,WAAW,EAAE,CACjB,KAAK,MAAM,EAAE,aAAa,CAAC,CAC3B,KAAK,IAAI;;AAGd,MAAM,mBAAmB,CAAC,aAAa;AAEvC,SAAgB,qBAAqB,MAAsB;AACzD,MAAK,MAAM,UAAU,iBACnB,KAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,OAAO,OAChD,QAAO,KAAK,MAAM,GAAG,CAAC,OAAO,OAAO;AAGxC,QAAO;;AAGT,SAAgB,qBAAqB,MAAsB;AACzD,QAAO,KAAK,QAAQ,aAAa,GAAG,CAAC,QAAQ,eAAe,GAAG;;;;;;AAOjE,SAAgB,qBAAqB,MAAsB;AACzD,QAAO,KACJ,QAAQ,aAAa,GAAG,CACxB,QAAQ,iBAAiB,GAAG,CAC5B,QAAQ,iBAAiB,GAAG,CAC5B,QAAQ,gBAAgB,GAAG;;;AAIhC,MAAM,qBAAqB,IAAI,IAAI;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;AASF,SAAgB,YAAY,MAAsB;AAChD,KAAI,mBAAmB,IAAI,KAAK,CAAE,QAAO;AACzC,KAAI,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,EACxC,QAAO,KAAK,MAAM,GAAG,GAAG,GAAG;AAE7B,KAAI,KAAK,SAAS,MAAM,IAAI,KAAK,SAAS,EAExC,QAAO,KAAK,MAAM,GAAG,GAAG;AAE1B,KAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,SAAS,KAAK,IAAI,KAAK,SAAS,EAC9D,QAAO,KAAK,MAAM,GAAG,GAAG;AAE1B,QAAO;;AAiBT,SAAgB,gBAAgB,MAAsB;CACpD,IAAI,SAAS,qBAAqB,qBAAqB,KAAK,CAAC;AAC7D,UAAS,qBAAqB,OAAO;CAGrC,MAAM,QAAQ,OAAO,MAAM,iBAAiB;AAC5C,KAAI,OAAO;EACT,MAAM,WAAW,MAAM;EACvB,MAAM,WAAW,YAAY,SAAS;AACtC,MAAI,aAAa,SACf,UAAS,WAAW,OAAO,MAAM,SAAS,OAAO;;AAIrD,QAAO;;;;;;;;;;AC/LT,SAAgB,uBAAuB,UAAkB,YAA6B;AACpF,KAAI,CAAC,WAAY,QAAO;CAIxB,MAAM,cAAc,qBAAqB,WAAW;AACpD,KAAI,SAAS,WAAW,YAAY,CAAE,QAAO;CAG7C,MAAM,gBAAgB,SAAS,MAAM,uBAAuB;AAC5D,KAAI,eAAe;EACjB,MAAM,GAAG,QAAQ,gBAAgB;AAEjC,SAAO,GAAG,cAAc,SADP,YAAY,aAAa;;AAG5C,QAAO,GAAG,cAAc;;;;;;;AAQ1B,SAAgB,+BAA+B,SAA4D;AACzG,KAAI,CAAC,QAAS,QAAO,EAAE;CAEvB,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,YAAY,WAAW,OAAO,QAAQ,QAAQ,CAExD,mCAAkC,QAAQ,cADvB,kBAAkB,WAAW,CACmB;AAGrE,QAAO;;AAGT,SAAS,kCAAkC,QAAsB,SAAkB,YAA2B;CAC5G,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAe,OAAO,SAAS,EAAE;AAEvC,MAAK,MAAM,OAAO,aAChB,KAAI,IAAI,WACN,mCAAkC,KAAK,SAAS,WAAW;AAI/D,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAElB,MAAI,YAAY,eAAe,YAAY,SAAS,YAAY,CAAC,YAAY,OAAO;GAElF,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;AAC9D,WAAQ,KAAK,iBAAiB,WAAW,YAAY,CAAC;AACtD,qCAAkC,aAAa,SAAS,UAAU;;AAIpE,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO;GACrD,MAAM,QAAQ,YAAY;AAC1B,OAAI,MAAM,eAAe,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;IAEhE,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;AAC9D,YAAQ,KAAK,iBAAiB,WAAW,MAAM,CAAC;AAChD,sCAAkC,OAAO,SAAS,UAAU;;;AAYhE,MAAI,YAAY,OAAO;GACrB,MAAM,uBAAuB,YAAY,MAAM,QAC5C,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAC9D;AACD,OAAI,qBAAqB,SAAS,GAAG;IAEnC,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;IAC9D,MAAM,gBAAgB,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC;IACzD,MAAM,iBAAiB,+BAA+B,qBAAqB;IAC3E,MAAM,eAAyB,EAAE;AACjC,SAAK,MAAM,WAAW,sBAAsB;KAC1C,MAAM,cAAc,iBAAiB,SAAS,WAAW,cAAc,eAAe;AACtF,kBAAa,KAAK,YAAY;AAC9B,SAAI,CAAC,cAAc,IAAI,YAAY,EAAE;AACnC,oBAAc,IAAI,YAAY;AAC9B,cAAQ,KAAK,iBAAiB,aAAa,QAAQ,CAAC;AACpD,wCAAkC,SAAS,SAAS,YAAY;;;;;;;;;;AAW5E,SAAS,+BAA+B,UAAyC;AAC/E,KAAI,SAAS,SAAS,EAAG,QAAO;CAChC,MAAM,aAAa,OAAO,KAAK,SAAS,IAAI,cAAc,EAAE,CAAC;AAC7D,MAAK,MAAM,YAAY,YAAY;EACjC,MAAM,SAAS,SAAS,KAAK,MAAM,gBAAgB,EAAE,aAAa,UAAU,CAAC;AAC7E,MAAI,OAAO,MAAM,MAAM,MAAM,KAAK,CAAE;AACpC,MAAI,IAAI,IAAI,OAAO,CAAC,SAAS,OAAO,OAAQ;AAC5C,SAAO;;AAET,QAAO;;AAGT,SAAS,gBAAgB,MAA+C;AACtE,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,OAAO,KAAK,UAAU,SAAU,QAAO,KAAK;AAChD,KAAI,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,KAAK,OAAO,SAChF,QAAO,KAAK,KAAK;AAEnB,QAAO;;;;;;;AAQT,SAAS,iBACP,SACA,YACA,gBACA,uBACQ;AACR,KAAI,eAAe,WAAW,EAAG,QAAO;AACxC,KAAI,uBAAuB;EACzB,MAAM,aAAa,gBAAgB,QAAQ,aAAa,uBAAuB;AAC/E,MAAI,YAAY;GACd,MAAM,SAAS,aAAa,WAAW;AACvC,OAAI,QAAQ;IACV,MAAM,YAAY,WAAW,WAAW,OAAO,GAAG,aAAa,GAAG,SAAS;AAE3E,QAAI,EADc,cAAc,cAAc,eAAe,SAAS,UAAU,EAChE,QAAO;;;;AAI7B,QAAO,GAAG,aAAa,eAAe,SAAS;;AAGjD,SAAS,iBAAiB,MAAc,QAA6B;CACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,cAAc,EAAE,CAAC,EAAE;AAC9E,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;;AAG9E,QAAO;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ;;;;;;;;AC1J1D,IAAI,4BAA+D;;;;;;;;AASnE,IAAI,wCAAqC,IAAI,KAAK;;AAGlD,SAAgB,kBAAkB,SAAyB;CACzD,IAAI,OAAO,gBAAgB,aAAa,QAAQ,CAAC;AACjD,KAAI,0BAA2B,QAAO,0BAA0B,KAAK;AACrE,QAAO;;AAqCT,SAAgB,eACd,SACA,SACkB;CAClB,MAAM,QAAgB,EAAE;AAExB,KAAI,CAAC,QAAS,QAAO;EAAE,QAAQ,EAAE;EAAE;EAAO;AAG1C,KAAI,SAAS,qBAAqB;EAChC,MAAM,YAAY,QAAQ;EAE1B,MAAM,eADW,OAAO,KAAK,QAAQ,CACP,KAAK,MAAM,gBAAgB,aAAa,EAAE,CAAC,CAAC;EAC1E,MAAM,yCAAyB,IAAI,KAAuB;AAC1D,OAAK,MAAM,WAAW,cAAc;GAClC,MAAM,cAAc,UAAU,QAAQ;AACtC,OAAI,CAAC,uBAAuB,IAAI,YAAY,CAAE,wBAAuB,IAAI,aAAa,EAAE,CAAC;AACzF,0BAAuB,IAAI,YAAY,CAAE,KAAK,QAAQ;;EAExD,MAAM,oCAAoB,IAAI,KAAa;AAC3C,OAAK,MAAM,GAAG,cAAc,uBAC1B,KAAI,UAAU,SAAS,EACrB,MAAK,MAAM,KAAK,UAAW,mBAAkB,IAAI,EAAE;AAGvD,+BAA6B,SAAkB,kBAAkB,IAAI,KAAK,GAAG,OAAO,UAAU,KAAK;OAEnG,6BAA4B;AAQ9B,yCAAwB,IAAI,KAAK;AACjC,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,CAClD,KAAI,OAAO,KAAM,uBAAsB,IAAI,kBAAkB,KAAK,CAAC;CAGrE,MAAM,oCAAoB,IAAI,KAAoB;AAElD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,aAAa,kBAAkB,KAAK;AAE1C,MAAI,OAAO,KACT,OAAM,KAAK,YAAY,YAAY,OAAO,CAAC;OACtC;GACL,MAAM,QAAQ,aAAa,YAAY,QAAQ,QAAQ;GACvD,MAAM,WAAW,kBAAkB,IAAI,WAAW;AAClD,OAAI;QAEE,MAAM,OAAO,SAAS,SAAS,OAAO,OACxC,mBAAkB,IAAI,YAAY,MAAM;SAG1C,mBAAkB,IAAI,YAAY,MAAM;AAG1C,QAAK,MAAM,eAAe,uCAAuC,QAAQ,WAAW,EAAE;IACpF,MAAM,iBAAiB,kBAAkB,IAAI,YAAY,KAAK;AAC9D,QAAI;SACE,YAAY,OAAO,SAAS,eAAe,OAAO,OACpD,mBAAkB,IAAI,YAAY,MAAM,YAAY;UAGtD,mBAAkB,IAAI,YAAY,MAAM,YAAY;;;;CAM5D,MAAM,SAAS,CAAC,GAAG,kBAAkB,QAAQ,CAAC;CAI9C,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;CACrD,MAAM,cAAuB,CAAC,GAAG,OAAO;AACxC,QAAO,YAAY,SAAS,GAAG;EAC7B,MAAM,QAAQ,YAAY,KAAK;AAC/B,OAAK,MAAM,SAAS,MAAM,OACxB,2BAA0B,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WAAW,EAAE,EAAE,QAAQ,YAAY,YAAY;;AAKjH,MAAK,MAAM,SAAS,OAClB,oBAAmB,MAAM,QAAQ,MAAM;AAOzC,QAAO;EAAE;EAAQ;EAAO;;;AAI1B,SAAgB,2BAAiC;AAC/C,6BAA4B;AAC5B,yCAAwB,IAAI,KAAK;;;;;;AAOnC,SAAgB,yBAAyB,KAAc,OAAe,MAAyB;AAC7F,aAAY,KAAK,EACf,OAAO,MAAM;AACX,MAAI,EAAE,UAAU,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE;AACjC,QAAK,IAAI,EAAE,KAAK;AAChB,SAAM,KAAK;IACT,MAAM,EAAE;IACR,QAAQ,EAAE,OAAO,KAAK,OAAO;KAC3B,MAAM,iBAAiB,OAAO,EAAE,CAAC;KACjC,OAAO;KACP,aAAa,KAAA;KACd,EAAE;IACJ,CAAC;;IAGP,CAAC;;;;;;AAOJ,SAAS,mBAAmB,QAAiB,OAAqB;CAChE,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AAC9C,MAAK,MAAM,SAAS,OAClB,0BAAyB,MAAM,MAAM,OAAO,KAAK;;;;;;;;AAUrD,SAAS,0BACP,KACA,WACA,iBACA,SACA,QACA,YACA,OACM;AACN,aAAY,KAAK,EACf,QAAQ,aAAa;AACnB,MAAI,WAAW,IAAI,SAAS,KAAK,CAAE;AAInC,MADoB,OAAO,KAAK,QAAQ,CAAC,MAAM,MAAM,kBAAkB,EAAE,KAAK,SAAS,KAAK,CAC3E;EAIjB,MAAM,eAAe,iBAAiB,iBAAiB,QAAQ;AAC/D,MAAI,CAAC,aAAc;EAEnB,MAAM,cAAc,sBAAsB,WAAW,cAAc,QAAQ;AAC3E,MAAI,CAAC,YAAa;EAGlB,MAAM,YAAY,oBAAoB,SAAS,MAAM,YAAY;AACjE,OAAK,MAAM,KAAK,UACd,KAAI,CAAC,WAAW,IAAI,EAAE,KAAK,EAAE;AAC3B,UAAO,KAAK,EAAE;AACd,cAAW,IAAI,EAAE,KAAK;AACtB,SAAM,KAAK,EAAE;;IAIpB,CAAC;;;AAIJ,SAAS,iBAAiB,YAAoB,SAA4D;AACxG,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAC1C,KAAI,kBAAkB,EAAE,KAAK,WAAY,QAAO;AAElD,QAAO;;;AAIT,SAAS,sBACP,WACA,cACA,SACqB;AACrB,KAAI,aAAa,aAAa,WAC5B,QAAO,aAAa,WAAW;AAEjC,KAAI,aAAa,MACf,MAAK,MAAM,OAAO,aAAa,OAAO;EACpC,IAAI,WAAW;AACf,MAAI,IAAI,MAAM;GACZ,MAAM,WAAW,IAAI,KAAK,MAAM,IAAI;GACpC,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SAAU,YAAW,QAAQ;;AAEtD,MAAI,SAAS,aAAa,WACxB,QAAO,SAAS,WAAW;;AAMjC,MAAK,MAAM,WAAW,CAAC,GAAI,aAAa,SAAS,EAAE,EAAG,GAAI,aAAa,SAAS,EAAE,CAAE,EAAE;EACpF,IAAI,WAAW;AACf,MAAI,QAAQ,MAAM;GAChB,MAAM,WAAW,QAAQ,KAAK,MAAM,IAAI;GACxC,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SAAU,YAAW,QAAQ;;AAEtD,MAAI,SAAS,aAAa,WACxB,QAAO,SAAS,WAAW;;AAG/B,QAAO;;;AAIT,SAAS,oBAAoB,MAAc,QAA+B;AAExE,KAAI,OAAO,OAAO;EAChB,MAAM,SAAkB,EAAE;EAS1B,MAAM,2BAA2B,+BAHY,OAAO,MAAM,QACvD,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAC9D,CACoF;AAErF,OAAK,MAAM,WAAW,OAAO,OAAO;AAClC,OAAI,QAAQ,KAAM;AAClB,OAAI,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;IACtE,MAAM,cAAc,IAAI,IAAI,QAAQ,YAAY,EAAE,CAAC;IACnD,MAAM,SAAkB,EAAE;AAC1B,SAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzD,SAAI,CAAC,GAAI;AACT,YAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;IAE9D,MAAM,cAAc,iBAAiB,SAAS,MAAM,QAAQ,yBAAyB;AACrF,WAAO,KAAK;KAAE,MAAM;KAAa,aAAa,QAAQ;KAAa;KAAQ,CAAC;;;AAGhF,SAAO;;AAIT,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;EAClD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,OAAO,WAAW,EAAE;AACxD,OAAI,CAAC,GAAI;AACT,UAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;AAE9D,SAAO,CAAC;GAAE;GAAM,aAAa,OAAO;GAAa;GAAQ,CAAC;;AAI5D,KAAI,OAAO,SAAS,WAAW,OAAO,OAAO,YAAY;EACvD,MAAM,cAAc,IAAI,IAAI,OAAO,MAAM,YAAY,EAAE,CAAC;EACxD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,OAAO,MAAM,WAAW,EAAE;AAC9D,OAAI,CAAC,GAAI;AACT,UAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;AAE9D,SAAO,CAAC;GAAE;GAAM,aAAa,OAAO,MAAM;GAAa;GAAQ,CAAC;;AAGlE,QAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BX,SAAS,iBACP,SACA,YACA,gBACA,eACQ;AAGR,KAAI,eAAe,WAAW,EAAG,QAAO;AAExC,KAAI,eAAe;EACjB,MAAM,aAAa,sBAAsB,SAAS,cAAc,SAAS;AACzE,MAAI,YAAY;GACd,MAAM,SAAS,aAAa,WAAW;AACvC,OAAI,QAAQ;IACV,MAAM,YAAY,WAAW,WAAW,OAAO,GAAG,aAAa,GAAG,SAAS;AAE3E,QAAI,EADc,cAAc,cAAc,eAAe,MAAM,MAAM,EAAE,SAAS,UAAU,EAC9E,QAAO;;;;AAI7B,QAAO,GAAG,aAAa,eAAe,SAAS;;;;;;;;;;;;;AAcjD,SAAS,+BAA+B,UAAuD;AAC7F,KAAI,SAAS,SAAS,EAAG,QAAO;CAChC,MAAM,aAAa,OAAO,KAAK,SAAS,IAAI,cAAc,EAAE,CAAC;AAC7D,MAAK,MAAM,YAAY,YAAY;EACjC,MAAM,SAAS,SAAS,KAAK,MAAM,sBAAsB,GAAG,SAAS,CAAC;AACtE,MAAI,OAAO,MAAM,MAAM,MAAM,KAAK,CAAE;AACpC,MAAI,IAAI,IAAI,OAAO,CAAC,SAAS,OAAO,OAAQ;AAC5C,SAAO,EAAE,UAAU,UAAU;;AAE/B,QAAO;;;AAIT,SAAgB,qBACd,WACA,aACA,aACA,aACO;AACP,QAAO;EACL,MAAM;EACN,MAAM,gBAAgB,aAAa,WAAW,YAAY;EAC1D,UAAU,YAAY,IAAI,UAAU;EACpC,aAAa,YAAY;EACzB,UAAU,YAAY,YAAY,KAAA;EAClC,WAAW,YAAY,aAAa,KAAA;EACpC,YAAY,YAAY,cAAc,KAAA;EACtC,SAAS,YAAY;EACrB,SAAS,YAAY;EACtB;;;;;;;;AASH,SAAS,2BAA2B,UAA2C;AAC7E,KAAI,SAAS,WAAW,EAAG,QAAO;CAClC,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,KAAK,UAAU;AAExB,MAAI,OAAO,EAAE,UAAU,UAAU;AAC/B,UAAO,KAAK,EAAE,MAAM;AACpB;;AAEF,MAAI,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,KAAK,OAAO,EAAE,KAAK,OAAO,UAAU;AACjF,UAAO,KAAK,EAAE,KAAK,GAAG;AACtB;;AAEF,SAAO;;AAET,QAAO;;;AAIT,SAAS,sBACP,QACA,aACA,iBACS;CACT,MAAM,WAAW,aAAa,eAAe,cAAc;CAC3D,MAAM,cAAc,kBAAkB,qBAAqB,gBAAgB,GAAG,KAAA;CAC9E,MAAM,gBAAgB,eAAe,CAAC,SAAS,WAAW,YAAY,GAAG,GAAG,cAAc,aAAa;AAKvG,QAAO;EAAE,MAAM;EAAQ,MADL,4BAA4B,0BAA0B,cAAc,GAAG;EACjD;EAAQ;;;;;;;;;;;;;;;AAgBlD,SAAS,iCACP,UAC8D;AAC9D,KAAI,SAAS,SAAS,EAAG,QAAO;CAGhC,IAAI,oBAAmC;CACvC,MAAM,aAAa,OAAO,KAAK,SAAS,IAAI,cAAc,EAAE,CAAC;AAC7D,MAAK,MAAM,YAAY,WACrB,KAAI,SAAS,OAAO,MAAM,sBAAsB,GAAG,SAAS,KAAK,KAAK,EAAE;AACtE,sBAAoB;AACpB;;AAIJ,KAAI,CAAC,kBAAmB,QAAO;CAE/B,MAAM,UAAkC,EAAE;AAC1C,MAAK,MAAM,KAAK,UAAU;EACxB,MAAM,QAAQ,sBAAsB,GAAG,kBAAkB;AACzD,MAAI,UAAU,KAAM,QAAO;EAE3B,MAAM,cAAc,wBAAwB,EAAE;AAC9C,MAAI,CAAC,YAAa,QAAO;AACzB,UAAQ,SAAS;;AAGnB,QAAO;EAAE,UAAU;EAAmB;EAAS;;AAGjD,SAAS,sBAAsB,QAAsB,UAAiC;CACpF,MAAM,OAAO,OAAO,aAAa;AACjC,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,OAAO,KAAK,UAAU,SAAU,QAAO,KAAK;AAChD,KAAI,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,KAAK,OAAO,SAChF,QAAO,KAAK,KAAK;AAEnB,QAAO;;AAGT,SAAS,wBAAwB,QAAqC;AACpE,KAAI,OAAO,KACT,QAAO,kBAAkB,OAAO,KAAK,QAAQ,6BAA6B,GAAG,CAAC;CAEhF,MAAM,QAAQ,OAAO,OAAO,aAAa,WAAY,OAAO,WAAsB;AAClF,KAAI,MAAO,QAAO,kBAAkB,MAAM;AAC1C,QAAO;;;;;;AAOT,SAAS,+BACP,SACA,eACe;CACf,MAAM,QAAQ,sBAAsB,SAAS,cAAc,SAAS;AACpE,KAAI,UAAU,KAAM,QAAO;AAC3B,QAAO,cAAc,QAAQ,UAAU;;;;;;;;;;;;;;;;;;AAmBzC,SAAS,2BACP,UACA,uBACA,aACA,iBAC+B;AAC/B,KAAI,SAAS,WAAW,KAAK,CAAC,YAAa,QAAO;CAClD,MAAM,uBAAuB,SAAS,QAAQ,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAAM;AAChH,KAAI,qBAAqB,WAAW,SAAS,OAAQ,QAAO;CAE5D,MAAM,iBAAiB,uBAAuB,aAAa,YAAY,EAAE,gBAAgB;CACzF,MAAM,sBAAsB,EAAE,UAAU,uBAAuB;CAC/D,MAAM,UAAkC,EAAE;CAC1C,MAAM,eAAwB,EAAE;AAChC,MAAK,MAAM,WAAW,sBAAsB;EAC1C,MAAM,aAAa,sBAAsB,SAAS,sBAAsB;AACxE,MAAI,eAAe,KAAM,QAAO;EAChC,MAAM,cAAc,iBAAiB,SAAS,gBAAgB,cAAc,oBAAoB;AAChG,UAAQ,cAAc;AACtB,eAAa,KAAK;GAAE,MAAM;GAAa,QAAQ,EAAE;GAAE,CAAC;;AAEtD,QAAO;;AAGT,SAAS,YAAY,MAAc,QAA4B;CAC7D,MAAM,UAAuB,OAAO,QAAQ,EAAE,EAAE,KAAK,OAAO;EAC1D,MAAM,iBAAiB,OAAO,EAAE,CAAC;EACjC,OAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE;EAC5C,aAAa,KAAA;EACd,EAAE;CAEH,MAAM,aAAa,OAAO;AAM1B,QAAO;EAAE;EAAM;EAAQ,SAJrB,eAAe,KAAA,KAAa,OAAO,MAAM,MAAM,EAAE,UAAU,WAAW,GACjE,aACD,KAAA;EAE+B;;AAEvC,SAAS,aAAa,MAAc,QAAsB,SAA+C;AACvG,KAAI,OAAO,MACT,QAAO,kBAAkB,MAAM,QAAQ,QAAQ;CAGjD,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,cAAc,EAAE,CAAC,EAAE;AAC9E,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;;AAM9E,KAAI,OAAO,WAAW,MAAM,OAAO,SAAS,OAAO,QAAQ;EACzD,MAAM,WAAW,OAAO,SAAS,OAAO,SAAS,EAAE;EACnD,MAAM,gCAAgB,IAAI,KAAa;EACvC,MAAM,iCAAiB,IAAI,KAAa;AACxC,OAAK,MAAM,WAAW,UAAU;AAC9B,OAAI,CAAC,QAAQ,WAAY;AACzB,QAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,QAAI,CAAC,eAAe,eAAe,IAAI,UAAU,CAAE;AACnD,mBAAe,IAAI,UAAU;AAC7B,WAAO,KAAK,qBAAqB,WAAW,aAA6B,MAAM,cAAc,CAAC;;;;AAOpG,KAAI,OAAO,wBAAwB,OAAO,OAAO,yBAAyB,YAAY,OAAO;MAC5E,OAAO,KAAK,OAAO,qBAAqB,CAC5C,SAAS,GAAG;GACrB,MAAM,YAAY,gBAAgB,OAAO,sBAAsC,wBAAwB,KAAK;AAC5G,UAAO,KAAK;IACV,MAAM;IACN,MAAM;KAAE,MAAM;KAAO;KAAW;IAChC,UAAU;IACV,aAAa;IACd,CAAC;;;AAIN,QAAO;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ;;AAG1D,SAAS,kBAAkB,MAAc,QAAsB,SAA+C;CAC5G,MAAM,SAAkB,EAAE;CAC1B,MAAM,8BAAc,IAAI,KAAa;CACrC,IAAI;AAEJ,MAAK,MAAM,aAAa,OAAO,SAAS,EAAE,EAAE;EAE1C,IAAI,WAAW;AACf,MAAI,UAAU,QAAQ,SAAS;GAC7B,MAAM,WAAW,UAAU,KAAK,MAAM,IAAI;GAC1C,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SACrB,YAAW,QAAQ;;AAKvB,MAAI,SAAS,OAAO;GAClB,MAAM,SAAS,kBAAkB,MAAM,UAAU,QAAQ;AACzD,QAAK,MAAM,KAAK,OAAO,QAAQ;AAC7B,WAAO,KAAK;KAAE,GAAG;KAAG,UAAU;KAAO,CAAC;AACtC,QAAI,EAAE,SAAU,aAAY,IAAI,EAAE,KAAK;;aAEhC,SAAS,SAAS,SAAS,OAAO;GAC3C,MAAM,WAAW,SAAS,SAAS,SAAS,SAAS,EAAE;GAKvD,MAAM,oBAAoB,gCAAgC,UAAU,KAAK;AACzE,OAAI,kBACF,uBAAsB;QACjB;IAIL,MAAM,gCAAgB,IAAI,KAAa;IACvC,MAAM,iBAAiB,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AACzD,SAAK,MAAM,WAAW,UAAU;AAC9B,SAAI,CAAC,QAAQ,WAAY;AACzB,UAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,UAAI,CAAC,eAAe,eAAe,IAAI,UAAU,CAAE;AACnD,qBAAe,IAAI,UAAU;AAC7B,aAAO,KAAK,qBAAqB,WAAW,aAA6B,MAAM,cAAc,CAAC;;;;SAO/F;AACL,OAAI,SAAS,SACX,MAAK,MAAM,KAAK,SAAS,SAAU,aAAY,IAAI,EAAE;AAEvD,OAAI,SAAS,YAAY;IAEvB,MAAM,gCAAgB,IAAI,KAAa;AACvC,SAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,SAAS,WAAW,EAAE;AAC1E,SAAI,CAAC,YAAa;AAClB,YAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,cAAc,CAAC;;;;;AAOtF,KAAI,OAAO,SACT,MAAK,MAAM,KAAK,OAAO,SAAU,aAAY,IAAI,EAAE;AAIrD,MAAK,MAAM,KAAK,OACd,GAAE,WAAW,YAAY,IAAI,EAAE,KAAK;AAGtC,QAAO;EACL;EACA,aAAa,OAAO;EACpB;EACA,GAAI,sBAAsB,EAAE,eAAe,qBAAqB,GAAG,EAAE;EACtE;;;;;;;;;;;;AAaH,SAAS,uBAAuB,QAAoD;CAClF,MAAM,QAAsC,EAAE;CAC9C,MAAM,SAAS,MAA0B;AACvC,MAAI,EAAE;QACC,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAE,WAAW,CAC/C,KAAI,EAAE,KAAK,UAAU,EAAG,OAAM,KAAK;;AAGvC,MAAI,EAAE,MACJ,MAAK,MAAM,OAAO,EAAE,MAAO,OAAM,IAAI;;AAKzC,OAAM,OAAO;AACb,QAAO;;AAGT,SAAS,+BAA+B,QAAsB,UAAiC;CAC7F,MAAM,SAAS,sBAAsB,QAAQ,SAAS;AACtD,KAAI,WAAW,KAAM,QAAO;CAC5B,MAAM,YAAY,uBAAuB,OAAO,CAAC;AACjD,KAAI,CAAC,UAAW,QAAO;AACvB,KAAI,OAAO,UAAU,UAAU,SAAU,QAAO,UAAU;AAC1D,KAAI,MAAM,QAAQ,UAAU,KAAK,IAAI,UAAU,KAAK,WAAW,KAAK,OAAO,UAAU,KAAK,OAAO,SAC/F,QAAO,UAAU,KAAK;AAExB,QAAO;;;;;;;;;;;;;;;;AAiBT,SAAS,gCACP,UACA,cAC8D;AAC9D,KAAI,SAAS,SAAS,EAAG,QAAO;CAIhC,MAAM,aAAa,uBAAuB,SAAS,MAAM,EAAE,CAAC;CAC5D,IAAI,oBAAmC;AACvC,MAAK,MAAM,YAAY,OAAO,KAAK,WAAW,CAC5C,KAAI,SAAS,OAAO,MAAM,+BAA+B,GAAG,SAAS,KAAK,KAAK,EAAE;AAC/E,sBAAoB;AACpB;;AAGJ,KAAI,CAAC,kBAAmB,QAAO;CAE/B,MAAM,UAAkC,EAAE;CAC1C,MAAM,iCAAiB,IAAI,KAAa;AACxC,MAAK,MAAM,KAAK,UAAU;EACxB,MAAM,QAAQ,+BAA+B,GAAG,kBAAkB;AAClE,MAAI,UAAU,KAAM,QAAO;EAC3B,MAAM,YAAY,+BAA+B,GAAG,aAAa;AAEjE,MAAI,eAAe,IAAI,UAAU,CAAE,QAAO;AAC1C,iBAAe,IAAI,UAAU;AAC7B,UAAQ,SAAS;;AAGnB,QAAO;EAAE,UAAU;EAAmB;EAAS;;AAGjD,SAAS,uCAAuC,QAAsB,cAA+B;CACnG,MAAM,SAAkB,EAAE;CAC1B,MAAM,4BAAY,IAAI,KAAa;CAQnC,MAAM,iBAA+C,EAAE;CACvD,MAAM,+BAAe,IAAI,KAAa;AACtC,MAAK,MAAM,aAAa,OAAO,SAAS,EAAE,EAAE;AAC1C,MAAI,UAAU,MAAO;EACrB,MAAM,OAAO,UAAU,QAAQ,4BAA4B,UAAU,GAAG;AACxE,MAAI,KAAK;QACF,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,WAAW,CAClD,KAAI,EAAE,KAAK,mBAAmB,EAAG,gBAAe,KAAK;;AAGzD,MAAI,KAAK,SAAU,MAAK,MAAM,KAAK,KAAK,SAAU,cAAa,IAAI,EAAE;;AAGvE,MAAK,MAAM,aAAa,OAAO,SAAS,EAAE,CACxC,MAAK,MAAM,WAAW,UAAU,SAAS,EAAE,EAAE;EAM3C,MAAM,OAAO,4BAA4B,QAAQ;AACjD,MAAI,CAAC,KAAK,cAAe,KAAK,SAAS,KAAA,KAAa,KAAK,SAAS,SAAW;EAK7E,MAAM,mBAAiD,EAAE,GAAG,gBAAgB;AAC5E,OAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,KAAK,WAAW,CAClD,KAAI,EAAG,kBAAiB,KAAK;EAG/B,MAAM,SAAuB;GAC3B,MAAM;GACN,YAAY;GACZ,UAAU,CAAC,GAJU,IAAI,IAAY,CAAC,GAAG,cAAc,GAAI,KAAK,YAAY,EAAE,CAAE,CAAC,CAIpD;GAC9B;EAED,MAAM,cAAc,+BAA+B,SAAS,aAAa;AACzE,OAAK,MAAM,SAAS,uBAAuB,aAAa,OAAO,EAAE;AAC/D,OAAI,UAAU,IAAI,MAAM,KAAK,CAAE;AAC/B,aAAU,IAAI,MAAM,KAAK;AACzB,UAAO,KAAK,MAAM;;;AAKxB,QAAO;;;;;;;;;AAUT,SAAS,4BAA4B,SAAqC;AACxE,KAAI,CAAC,QAAQ,MAAO,QAAO;CAE3B,MAAM,mBAAiD,EAAE;CACzD,MAAM,iCAAiB,IAAI,KAAa;CACxC,MAAM,eAAiC,EAAE;CAEzC,MAAM,WAAW,MAA0B;AACzC,MAAI,EAAE;QACC,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,EAAE,WAAW,CAC/C,KAAI,EAAE,KAAK,qBAAqB,EAAG,kBAAiB,KAAK;;AAG7D,MAAI,EAAE,SACJ,MAAK,MAAM,KAAK,EAAE,SAAU,gBAAe,IAAI,EAAE;AAEnD,MAAI,EAAE,MACJ,MAAK,MAAM,OAAO,EAAE,MAAO,SAAQ,IAAI;AAEzC,MAAI,EAAE,MAAO,cAAa,KAAK,EAAE,MAAM;;AAEzC,SAAQ,QAAQ;AAOhB,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,eAAe,SAAS,IAAI,4BAA4B;EAC9D,MAAM,6BAAa,IAAI,KAAa;AACpC,OAAK,MAAM,KAAK,aACd,MAAK,MAAM,KAAK,OAAO,KAAK,EAAE,cAAc,EAAE,CAAC,CAAE,YAAW,IAAI,EAAE;AAEpE,OAAK,MAAM,OAAO,YAAY;GAC5B,MAAM,UAA0B,EAAE;AAClC,QAAK,MAAM,KAAK,cAAc;IAC5B,MAAM,IAAI,EAAE,aAAa;AACzB,QAAI,EAAG,SAAQ,KAAK,EAAE;;GAExB,MAAM,SAAS,2BAA2B,QAAQ;AAClD,OAAI,EAAE,OAAO,kBAAmB,kBAAiB,OAAO;AAGxD,OAFsB,aAAa,OAAO,MAAM,EAAE,cAAc,OAAO,EAAE,WAAW,IAC7C,aAAa,OAAO,OAAO,EAAE,YAAY,EAAE,EAAE,SAAS,IAAI,CAAC,CAC/E,gBAAe,IAAI,IAAI;;;AAI9C,QAAO;EACL,MAAM;EACN,YAAY;EACZ,UAAU,CAAC,GAAG,eAAe;EAC9B;;;;;;;;;AAUH,SAAS,2BAA2B,SAAuC;AACzE,KAAI,QAAQ,WAAW,EAAG,QAAO,EAAE;AACnC,KAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ;AAGzC,KADqB,QAAQ,OAAO,MAAM,EAAE,SAAS,aAAa,OAAO,EAAE,UAAU,UAAU,CAE7F,QAAO;EAAE,MAAM;EAAW,aAAa,QAAQ,GAAG;EAAa;AAGjE,KADuB,QAAQ,OAAO,MAAM,EAAE,SAAS,YAAY,OAAO,EAAE,UAAU,SAAS,EAC3E;EAClB,MAAM,SAAS,QAAQ,KAAK,MAAM,EAAE,MAAgB;AACpD,MAAI,IAAI,IAAI,OAAO,CAAC,SAAS,EAAG,QAAO,QAAQ;AAC/C,SAAO;GAAE,MAAM;GAAU,aAAa,QAAQ,GAAG;GAAa;;AAEhE,QAAO,QAAQ;;AAGjB,SAAS,+BAA+B,QAAsB,cAA8B;CAI1F,MAAM,YAAY,uBAAuB,OAAO;AAChD,KAAI,OAAO,KAAK,UAAU,CAAC,WAAW,EAAG,QAAO;CAEhD,MAAM,aAAa,SAAgC;EACjD,MAAM,QAAQ,UAAU;AACxB,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,OAAO,MAAM,UAAU,SAAU,QAAO,MAAM;AAClD,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO,MAAM,KAAK;AAEpB,SAAO;;CAGT,IAAI,aAA4B;AAChC,MAAK,MAAM,aAAa;EAAC;EAAS;EAAQ;EAAS,EAAE;AACnD,eAAa,UAAU,UAAU;AACjC,MAAI,WAAY;;AAElB,KAAI,eAAe,KACjB,MAAK,MAAM,QAAQ,OAAO,KAAK,UAAU,EAAE;AACzC,eAAa,UAAU,KAAK;AAC5B,MAAI,WAAY;;AAGpB,KAAI,eAAe,KAAM,QAAO;CAEhC,MAAM,SAAS,aAAa,WAAW;AACvC,KAAI,CAAC,OAAQ,QAAO;AASpB,KADkB,WAAW,WAAW,CAAC,UACxB,EAAG,QAAO;AAC3B,KAAI,WAAW,aAAc,QAAO;AACpC,KAAI,aAAa,WAAW,OAAO,CAAE,QAAO;AAC5C,KAAI,OAAO,SAAS,aAAa,CAAE,QAAO;AAC1C,QAAO,GAAG,eAAe;;AAG3B,SAAS,uBAAuB,MAAc,QAA+B;CAC3E,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;CAC1B,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;AAE5E,MAAI,YAAY,SAAS,YAAY,YAAY,WAC/C,cAAa,KAAK,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE,YAAY,CAAC;AAGrG,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO,WACrD,cAAa,KAAK,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE,YAAY,MAAM,CAAC;AAG3G,MAAI,YAAY,OAAO;GACrB,MAAM,mBAA6D,EAAE;GACrE,MAAM,iBAA2B,EAAE;AACnC,QAAK,MAAM,OAAO,YAAY,OAAO;AACnC,QAAI,IAAI,WAAY,QAAO,OAAO,kBAAkB,IAAI,WAAW;AACnE,QAAI,IAAI,SAAU,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAExD,OAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,EACzC,cAAa,KACX,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE;IAClE,MAAM;IACN,YAAY;IACZ,UAAU;IACX,CAAC,CACH;;AAIL,MAAI,YAAY,OAAO;GACrB,MAAM,uBAAuB,YAAY,MAAM,QAC5C,MAAM,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAC9D;AACD,OAAI,qBAAqB,SAAS,GAAG;IACnC,MAAM,gBAAgB,wBAAwB,MAAM,UAAU;IAC9D,MAAM,aAAa,+BAA+B,qBAAqB;IACvE,MAAM,UAAmB,EAAE;AAC3B,SAAK,MAAM,WAAW,sBAAsB;KAC1C,MAAM,cAAc,iBAAiB,SAAS,eAAe,SAAS,WAAW;AACjF,aAAQ,KAAK;MAAE,MAAM;MAAa,QAAQ,EAAE;MAAE,CAAC;AAC/C,kBAAa,KAAK,GAAG,uBAAuB,aAAa,QAAQ,CAAC;;;;;AAM1E,QAAO,CAAC;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ,EAAE,GAAG,aAAa;;AAG7E,SAAS,wBAAwB,YAAoB,WAA2B;CAC9E,MAAM,cAAc,aAAa,UAAU;AAC3C,KAAI,YAAY,WAAW,WAAW,CAAE,QAAO;CAG/C,MAAM,YAAY,GADE,qBAAqB,WAAW,GACjB;CACnC,MAAM,QAAQ,UAAU,MAAM,yBAAyB;AACvD,KAAI,SAAS,MAAM,GACjB,QAAO,MAAM,KAAK,YAAY,MAAM,GAAG;AAEzC,QAAO;;AAGT,SAAgB,gBAAgB,QAAsB,aAAsB,iBAAmC;AAO7G,KAAI,OAAO,MAAM;EACf,MAAM,WAAW,OAAO,KAAK,MAAM,IAAI;EACvC,MAAM,UAAU,SAAS,SAAS,SAAS;EAC3C,MAAM,WAAW,kBAAkB,QAAQ;AAC3C,MAAI,sBAAsB,IAAI,SAAS,CACrC,QAAO;GAAE,MAAM;GAAQ,MAAM;GAAU;AAEzC,SAAO;GAAE,MAAM;GAAS,MAAM;GAAU;;AAI1C,KAAI,MAAM,QAAQ,OAAO,KAAK,EAAE;EAC9B,MAAM,eAAe,OAAO,KAAK,QAAQ,MAAc,MAAM,OAAO;AAEpE,MAAI,aAAa,WAAW,EAC1B,QAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE;AAE5E,MAAI,OAAO,KAAK,SAAS,OAAO,IAAI,aAAa,WAAW,EAC1D,QAAO;GACL,MAAM;GACN,OAAO,gBAAgB;IAAE,GAAG;IAAQ,MAAM,aAAa;IAAI,UAAU;IAAO,EAAE,YAAY;GAC3F;AAGH,MAAI,aAAa,SAAS,GAAG;GAE3B,MAAM,MAAe;IAAE,MAAM;IAAS,UADrB,aAAa,KAAK,MAAc,gBAAgB;KAAE,GAAG;KAAQ,MAAM;KAAG,EAAE,YAAY,CAAC;IACtD;AAChD,OAAI,OAAO,KAAK,SAAS,OAAO,CAC9B,QAAO;IAAE,MAAM;IAAY,OAAO;IAAK;AAEzC,UAAO;;;AAKX,KAAI,OAAO,YAAY,OAAO,KAC5B,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB;GAAE,GAAG;GAAQ,UAAU;GAAO,EAAE,YAAY;EACpE;AAMH,KAAI,OAAO,OAAO;EAEhB,MAAM,UAAU,OAAO,MAAM,MAAM,MAAoB,EAAE,KAAK;AAC9D,MAAI,SAAS;AAIX,OADwB,OAAO,MAAM,MAAM,MAAoB,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,UAAU,CAG9G,QAAO;IAAE,MAAM;IAAS,MAAM,uBADb,aAAa,eAAe,eAAe,EACG,gBAAgB;IAAE;AAEnF,UAAO,gBAAgB,SAAS,aAAa,gBAAgB;;AAG/D,MAAI,OAAO,MAAM,WAAW,EAC1B,QAAO,gBAAgB,OAAO,MAAM,IAAI,aAAa,gBAAgB;AAIvE,MADsB,OAAO,MAAM,MAAM,MAAoB,EAAE,WAAW,CAGxE,QAAO;GACL,MAAM;GACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;GACxD;;AAQL,KAAI,OAAO,SAAS,OAAO,OAAO;EAChC,MAAM,kBAAqC,OAAO,QAAQ,UAAU;EACpE,MAAM,cAA8B,OAAO,SAAS,OAAO,SAAS,EAAE;EAGtE,MAAM,cAAc,YAAY,MAC7B,MAAoB,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,KAAK,EAAE,KAAK,OAAO,OAC1G;EACD,MAAM,kBAAkB,YAAY,QAAQ,MAAM,MAAM,YAAY;AAEpE,MAAI,eAAe,gBAAgB,WAAW,EAE5C,QAAO;GACL,MAAM;GACN,OAAO,gBAAgB,gBAAgB,IAAI,aAAa,gBAAgB;GACzE;EAQH,MAAM,iBAAiB,2BAA2B,gBAAgB;AAClE,MAAI,mBAAmB,QAAQ,eAAe,UAAU,GAAG;GACzD,MAAM,UAAU,sBAAsB,gBAAgB,aAAa,gBAAgB;AACnF,UAAO,cAAc;IAAE,MAAM;IAAY,OAAO;IAAS,GAAG;;EAoB9D,IAAI;AACJ,MAAI,OAAO,eAAe;GACxB,MAAM,WAAW,OAAO,cAAc;GACtC,MAAM,kBAAkB,OAAO,cAAc,WAAW,EAAE;GAC1D,IAAI,UAAkC,OAAO,YAC3C,OAAO,QAAQ,gBAAgB,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,6BAA6B,GAAG,CAAC,CAAC,CACjG;AACD,OAAI,OAAO,KAAK,QAAQ,CAAC,WAAW,GAAG;IACrC,MAAM,gBAAgB,2BAA2B,iBAAiB,UAAU,aAAa,gBAAgB;AACzG,QAAI,cAAe,WAAU;;AAE/B,2BAAwB;IAAE;IAAU;IAAS;aACpC,oBAAoB,SAAS;GACtC,MAAM,YAAY,iCAAiC,gBAAgB;AACnE,OAAI,UACF,yBAAwB;QACnB;IACL,MAAM,aAAa,+BAA+B,gBAAgB;AAClE,QAAI,YAAY;KACd,MAAM,gBAAgB,2BACpB,iBACA,WAAW,UACX,aACA,gBACD;AACD,SAAI,cACF,yBAAwB;MAAE,UAAU,WAAW;MAAU,SAAS;MAAe;;;;EAYzF,MAAM,WAAsB,EAAE;AAC9B,OAAK,MAAM,KAAK,aAAa;AAC3B,OAAI,MAAM,YAAa;GACvB,MAAM,oBACJ,yBAAyB,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,QAC3E,+BAA+B,GAAG,sBAAsB,GACxD;AACN,OAAI,kBACF,UAAS,KAAK;IAAE,MAAM;IAAS,MAAM;IAAmB,CAAC;OAEzD,UAAS,KAAK,gBAAgB,GAAG,aAAa,gBAAgB,CAAC;;EAGnE,MAAM,UAAU,CAAC,CAAC;EAElB,MAAM,QAAiB;GACrB,MAAM;GACN;GACA;GACA,GAAI,wBAAwB,EAAE,eAAe,uBAAuB,GAAG,EAAE;GAC1E;AACD,SAAO,UAAU;GAAE,MAAM;GAAY,OAAO;GAAO,GAAG;;AAIxD,KAAI,OAAO,UAAU,KAAA,GAAW;AAC9B,MAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,UAClG,QAAO;GAAE,MAAM;GAAW,OAAO,OAAO;GAAO;AAGjD,MAAI,OAAO,UAAU,KACnB,QAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE;AAG5E,MAAI,OAAO,OAAO,UAAU,UAAU;AACpC,OAAI,MAAM,QAAQ,OAAO,MAAM,CAC7B,QAAO;IAAE,MAAM;IAAS,OAAO;KAAE,MAAM;KAAa,MAAM;KAAW;IAAE;AAEzE,UAAO;IAAE,MAAM;IAAO,WAAW;KAAE,MAAM;KAAa,MAAM;KAAW;IAAE;;;AAG7E,KAAI,OAAO,QAAQ,OAAO,KAAK,WAAW,GAAG;EAC3C,MAAM,IAAI,OAAO,KAAK;AACtB,SAAO;GAAE,MAAM;GAAW,OAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE;GAAE;;AAI1E,KAAI,OAAO,MAAM;EACf,MAAM,WAAW,aAAa,eAAe,cAAc;EAG3D,MAAM,cAAc,kBAAkB,qBAAqB,gBAAgB,GAAG,KAAA;EAE9E,MAAM,gBAAgB,eAAe,CAAC,SAAS,WAAW,YAAY,GAAG,GAAG,cAAc,aAAa;AAMvG,SAAO;GACL,MAAM;GACN,MAHgB,4BAA4B,0BAA0B,cAAc,GAAG;GAIvF,QAAQ,OAAO,KAAK,KAAK,MAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE,CAAE;GACxE;;AAIH,KAAI,OAAO,SAAS,WAAW,OAAO,MACpC,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB,OAAO,OAAO,aAAa,gBAAgB;EACnE;AAGH,KAAI,CAAC,OAAO,QAAQ,OAAO,MACzB,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB,OAAO,OAAO,aAAa,gBAAgB;EACnE;AAOH,KAAI,OAAO,SAAS,YAAY,OAAO,WAErC,QAAO;EACL,MAAM;EACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;EACxD;AAIH,KAAI,OAAO,SAAS,YAAY,CAAC,OAAO,YAAY;EAClD,IAAI,YAAqB;GAAE,MAAM;GAAa,MAAM;GAAW;AAC/D,MAAI,OAAO,wBAAwB,OAAO,OAAO,yBAAyB;OAEzD,OAAO,KAAK,OAAO,qBAAqB,CAC5C,SAAS,EAClB,aAAY,gBAAgB,OAAO,sBAAsC,YAAY;aAE9E,OAAO,mBAAmB;GAEnC,MAAM,WAAW,OAAO,OAAO,OAAO,kBAAkB;AACxD,OAAI,SAAS,SAAS,EACpB,aAAY,gBAAgB,SAAS,IAAI,YAAY;;AAGzD,SAAO;GACL,MAAM;GACN;GACD;;CAIH,MAAM,eAA4E;EAChF,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,SAAS;EACV;CAED,MAAM,UAAU,MAAM,QAAQ,OAAO,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO;AACrE,KAAI,WAAW,aAAa,SAC1B,QAAO;EACL,MAAM;EACN,MAAM,aAAa;EACnB,GAAI,OAAO,SAAS,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EACnD;AAIH,KAAI,CAAC,OAAO,QAAQ,OAAO,WAEzB,QAAO;EACL,MAAM;EACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;EACxD;AAIH,KACE,CAAC,OAAO,QACR,CAAC,OAAO,QACR,CAAC,OAAO,SACR,CAAC,OAAO,SACR,CAAC,OAAO,SACR,CAAC,OAAO,QACR,CAAC,OAAO,cACR,CAAC,OAAO,MAER,QAAO;EAAE,MAAM;EAAa,MAAM;EAAW;AAI/C,KAAI,YACF,SAAQ,KAAK,sEAAsE,YAAY,GAAG;AAEpG,QAAO;EAAE,MAAM;EAAa,MAAM;EAAW;;;;ACz4C/C,MAAM,gBAAgB;CAAC;CAAU;CAAS;CAAU;CAAkB;CAAiB;CAAc;CAAa;AAElH,MAAM,gBAAgB;CAAC;CAAU;CAAQ;CAAe;CAAO;AAC/D,MAAM,eAAe;CAAC;CAAS;CAAa;CAAY;CAAQ;CAAQ;;;;;;;;;;;AAYxE,SAAgB,iBACd,UACA,aACA,UACuB;CAKvB,MAAM,cAAc,cAAc,KAAK,SAAS,YAAY,MAAM,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC,MACvF,MAAsB,MAAM,KAAA,EAC9B;AAED,KAAI,aAAa;EACf,MAAM,WAAoB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACvE,SAAO;GACL,UAAU;GACV,OAAO,YAAY;GACT;GACV;GACD;;CAIH,MAAM,cAAc,YAAY,MAAM,MAAM,cAAc,SAAS,EAAE,KAAK,CAAC;CAC3E,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,SAAS,EAAE,KAAK,CAAC;AAEzE,KAAI,eAAe,YAAY;EAC7B,MAAM,WAAoB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACvE,SAAO;GACL,UAAU;GACV,OAAO,YAAY;GACnB,YAAY,WAAW;GACb;GACV;GACD;;AAGH,QAAO;;;;ACrCT,SAAgB,2BAA2B,QAAsB,aAA+C;AAE9G,KAAI,OAAO,KACT,QAAO;EAAE,UAAU,gBAAgB,QAAQ,YAAY;EAAE,cAAc,EAAE;EAAE,aAAa;EAAO;CAIjG,MAAM,WAAW,mBAAmB,OAAO;AAC3C,KAAI,SAAS,WACX,QAAO,oBAAoB,QAAQ,aAAa,SAAS,SAAU;AAIrE,KAAI,wBAAwB,OAAO,CACjC,QAAO,uBAAuB,QAAQ,YAAY;AAIpD,QAAO,sBAAsB,QAAQ,YAAY;;AAQnD,MAAM,mBAAmB,IAAI,IAAI;CAAC;CAAQ;CAAS;CAAW;CAAW;CAAW;CAAU;CAAS;CAAQ,CAAC;AAEhH,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,mBAAmB,QAA0C;CAEpE,MAAM,cAA0D,EAAE;AAClE,KAAI,OAAO;OACJ,MAAM,OAAO,OAAO,MACvB,KAAI,IAAI,WAAY,aAAY,KAAK,IAAI,WAAW;;AAGxD,KAAI,OAAO,WACT,aAAY,KAAK,OAAO,WAAW;AAGrC,KAAI,YAAY,WAAW,EAAG,QAAO;EAAE,YAAY;EAAO,UAAU;EAAM;CAG1E,MAAM,cAAwD,EAAE;AAChE,MAAK,MAAM,UAAU,YACnB,QAAO,OAAO,aAAa,OAAO;CAIpC,MAAM,aAAuB,EAAE;CAC/B,MAAM,eAAyB,EAAE;AAEjC,MAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,YAAY,EAAE;AAC3D,MAAI,CAAC,WAAY;AACjB,MAAI,WAAW,SAAS,QACtB,YAAW,KAAK,IAAI;MAEpB,cAAa,KAAK,IAAI;;AAQ1B,KAAI,WAAW,WAAW,KAAK,aAAa,UAAU,GAAG;EACvD,MAAM,gBAAgB,WAAW;EAEjC,MAAM,yBAAyB,aAAa,MAAM,QAChD,6BAA6B,MAAM,YAAY,IAAI,aAAa,CAAC,SAAS,QAAQ,CAAC,CACpF;AAED,MAAI,iBAAiB,IAAI,cAAc,IAAI,uBACzC,QAAO;GAAE,YAAY;GAAM,UAAU;GAAe;AAItD,MAAI,uBACF,QAAO;GAAE,YAAY;GAAM,UAAU;GAAe;;AAIxD,QAAO;EAAE,YAAY;EAAO,UAAU;EAAM;;AAG9C,SAAS,oBAAoB,QAAsB,aAAqB,UAA4C;CAClH,IAAI,cAAuB;EAAE,MAAM;EAAa,MAAM;EAAU;CAChE,MAAM,eAAwB,EAAE;CAGhC,MAAM,cAA0D,EAAE;AAClE,KAAI,OAAO;OACJ,MAAM,OAAO,OAAO,MACvB,KAAI,IAAI,WAAY,aAAY,KAAK,IAAI,WAAW;;AAGxD,KAAI,OAAO,WACT,aAAY,KAAK,OAAO,WAAW;AAGrC,MAAK,MAAM,SAAS,aAAa;EAC/B,MAAM,WAAW,MAAM;AACvB,MAAI,CAAC,SAAU;AAEf,MAAI,SAAS,SAAS,WAAW,SAAS,OAAO;GAC/C,MAAM,QAAQ,SAAS;AACvB,OAAI,MAAM,KACR,eAAc,gBAAgB,OAAO,YAAY;YACxC,MAAM,SAAS,YAAY,MAAM,YAAY;IACtD,MAAM,WAAW,YAAY,QAAQ,aAAa,GAAG,GAAG;AACxD,kBAAc;KAAE,MAAM;KAAS,MAAM;KAAU;AAC/C,iBAAa,KAAK,GAAG,mBAAmB,UAAU,MAAM,CAAC;;;;AAK/D,QAAO;EACL,UAAU;GAAE,MAAM;GAAS,OAAO;GAAa;EAC/C;EACA,aAAa;EACb;EACA,UAAU;EACX;;AAGH,SAAS,0BAA0B,QAAkE;AACnG,KAAI,CAAC,OAAO,WAAY,QAAO;AAI/B,MAAK,MAAM,QADO,CAAC,UAAU,OAAO,EACN;EAC5B,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,CAAC,MAAO;AACZ,MAAI,MAAM,UAAU,KAAA,KAAa,OAAO,MAAM,UAAU,SACtD,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM;GAAO;AAE/C,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM,KAAK;GAAI;;AAKnD,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,WAAW,EAAE;AAC7D,MAAI,CAAC,MAAO;AACZ,MAAI,MAAM,UAAU,KAAA,KAAa,OAAO,MAAM,UAAU,SACtD,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM;GAAO;AAE/C,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM,KAAK;GAAI;;AAInD,QAAO;;AAGT,SAAS,wBAAwB,QAA+B;AAC9D,KAAI,OAAO,SAAS,SAAU,QAAO;AACrC,KAAI,CAAC,OAAO,WAAY,QAAO;CAG/B,IAAI;AACJ,KAAI,OAAO,YAAY,OAAO,SAAS,WAAW,EAChD,cAAa,OAAO,SAAS;MACxB;EACL,MAAM,WAAW,OAAO,KAAK,OAAO,WAAW;AAC/C,MAAI,SAAS,WAAW,EACtB,cAAa,SAAS;;AAG1B,KAAI,CAAC,WAAY,QAAO;CAExB,MAAM,aAAa,OAAO,WAAW;AACrC,KAAI,CAAC,WAAY,QAAO;AAGxB,KAAI,WAAW,SAAS,YAAY,0BAA0B,WAAW,KAAK,KAAM,QAAO;AAG3F,KAAI,WAAW,MACb,QAAO,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,YAAY,0BAA0B,EAAE,KAAK,KAAK;AAGnG,QAAO;;AAGT,SAAS,uBAAuB,QAAsB,aAA+C;CACnG,MAAM,QAAQ,OAAO;CAErB,MAAM,aAAa,MADA,OAAO,YAAY,OAAO,SAAS,WAAW,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK,MAAM,CAAC;CAE7G,MAAM,eAAwB,EAAE;CAGhC,MAAM,eAAe,YAAY,QAAQ,aAAa,GAAG;AAEzD,KAAI,WAAW,OAAO;EACpB,MAAM,gBAAgB,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,YAAY,0BAA0B,EAAE,KAAK,KAAK;AAEhH,MAAI,eAAe;GACjB,MAAM,YAAY,gBAAgB,eAAe,aAAa;AAC9D,gBAAa,KAAK,GAAG,mBAAmB,WAAW,cAAc,CAAC;GAElE,MAAM,iBAAiB,WAAW,MAAM,MACrC,MAAM,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,OAAO,CAC9E;GAED,MAAM,WAAoB;IAAE,MAAM;IAAS,MAAM;IAAW;AAC5D,UAAO;IACL,UAAU,iBAAiB;KAAE,MAAM;KAAY,OAAO;KAAU,GAAG;IACnE;IACA,aAAa;IACd;;;CAKL,MAAM,YAAY,gBAAgB,YAAY,aAAa;AAC3D,cAAa,KAAK,GAAG,mBAAmB,WAAW,WAAW,CAAC;AAE/D,QAAO;EACL,UAAU;GAAE,MAAM;GAAS,MAAM;GAAW;EAC5C;EACA,aAAa;EACd;;AAGH,SAAS,sBAAsB,QAAsB,aAA+C;CAClG,MAAM,eAAwB,EAAE;AAGhC,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,YAAY,gBAAgB,QAAQ,YAAY;AACtD,eAAa,KAAK,GAAG,mBAAmB,WAAW,OAAO,CAAC;AAC3D,SAAO;GACL,UAAU;IAAE,MAAM;IAAS,MAAM;IAAW;GAC5C;GACA,aAAa;GACd;;AAIH,KAAI,OAAO,OAAO;EAChB,MAAM,mBAA6D,EAAE;EACrE,MAAM,iBAA2B,EAAE;AACnC,OAAK,MAAM,OAAO,OAAO,OAAO;AAC9B,OAAI,IAAI,WACN,QAAO,OAAO,kBAAkB,IAAI,WAAW;AAEjD,OAAI,IAAI,SACN,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAGxC,MAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,GAAG;GAC5C,MAAM,SAAuB;IAAE,MAAM;IAAU,YAAY;IAAkB,UAAU;IAAgB;GACvG,MAAM,YAAY,gBAAgB,QAAQ,YAAY;AACtD,gBAAa,KAAK,GAAG,mBAAmB,WAAW,OAAO,CAAC;AAC3D,UAAO;IACL,UAAU;KAAE,MAAM;KAAS,MAAM;KAAW;IAC5C;IACA,aAAa;IACd;;;AAML,KAAI,OAAO;OACJ,MAAM,WAAW,OAAO,MAC3B,KAAI,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;GACtE,MAAM,YAAY,gBAAgB,SAAS,YAAY;AAEvD,OAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,UAAU,CAC/B,cAAa,KAAK,GAAG,mBAAmB,WAAW,QAAQ,CAAC;;;AAOpE,KAAI,OAAO,SAAS,WAAW,OAAO,OAAO;EAC3C,MAAM,QAAQ,OAAO;AACrB,MAAI,MAAM,KACR,QAAO;GACL,UAAU;IAAE,MAAM;IAAS,OAAO,gBAAgB,OAAO,YAAY;IAAE;GACvE;GACA,aAAa;GACd;AAEH,MAAI,MAAM,eAAe,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;GAChE,MAAM,WAAW,YAAY,QAAQ,aAAa,GAAG,GAAG;AACxD,gBAAa,KAAK,GAAG,mBAAmB,UAAU,MAAM,CAAC;AACzD,UAAO;IACL,UAAU;KAAE,MAAM;KAAS,OAAO;MAAE,MAAM;MAAS,MAAM;MAAU;KAAE;IACrE;IACA,aAAa;IACd;;;AAKL,QAAO;EACL,UAAU,gBAAgB,QAAQ,YAAY;EAC9C;EACA,aAAa;EACd;;AAGH,SAAS,gBAAgB,QAAsB,UAA0B;AACvE,KAAI,CAAC,OAAO,WAAY,QAAO,aAAa,SAAS;AAIrD,MAAK,MAAM,QADO,CAAC,UAAU,OAAO,EACN;EAC5B,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,SAAS,MAAM,SAAS,OAAO,MAAM,UAAU,SACjD,QAAO,aAAa,MAAM,MAAM;;AAKpC,MAAK,MAAM,GAAG,UAAU,OAAO,QAAQ,OAAO,WAAW,CACvD,KAAI,SAAS,MAAM,SAAS,OAAO,MAAM,UAAU,SACjD,QAAO,aAAa,MAAM,MAAM;AAIpC,QAAO,aAAa,SAAS;;;;;;;AAQ/B,SAAS,kBAAkB,YAAoB,WAA2B;CACxE,MAAM,cAAc,aAAa,UAAU;AAE3C,KAAI,YAAY,WAAW,WAAW,CAAE,QAAO;CAI/C,MAAM,YAAY,GADE,qBAAqB,WAAW,GACjB;CAEnC,MAAM,QAAQ,UAAU,MAAM,yBAAyB;AACvD,KAAI,SAAS,MAAM,IAAI;EACrB,MAAM,WAAW,YAAY,MAAM,GAAG;AACtC,SAAO,MAAM,KAAK;;AAEpB,QAAO;;AAGT,SAAS,mBAAmB,MAAc,QAA+B;CACvE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;CAC1B,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;AAI5E,MAAI,YAAY,SAAS,YAAY,YAAY,YAAY;GAC3D,MAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,gBAAa,KAAK,GAAG,mBAAmB,YAAY,YAAY,CAAC;;AAEnE,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO;GACrD,MAAM,QAAQ,YAAY;AAC1B,OAAI,MAAM,SAAS,YAAY,MAAM,YAAY;IAC/C,MAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,iBAAa,KAAK,GAAG,mBAAmB,YAAY,MAAM,CAAC;;;AAI/D,MAAI,YAAY,OAAO;GACrB,MAAM,mBAA6D,EAAE;GACrE,MAAM,iBAA2B,EAAE;AACnC,QAAK,MAAM,OAAO,YAAY,OAAO;AACnC,QAAI,IAAI,WAAY,QAAO,OAAO,kBAAkB,IAAI,WAAW;AACnE,QAAI,IAAI,SAAU,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAExD,OAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,GAAG;IAC5C,MAAM,aAAa,kBAAkB,MAAM,UAAU;IACrD,MAAM,SAAuB;KAAE,MAAM;KAAU,YAAY;KAAkB,UAAU;KAAgB;AAEvG,QAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,WAAW,CAChC,cAAa,KAAK,GAAG,mBAAmB,YAAY,OAAO,CAAC;;;AAKlE,MAAI,YAAY,OAAO;GACrB,MAAM,gBAAgB,YAAY,MAAM,MAAM,MAAM,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAAM;AACrG,OAAI,eAAe;IACjB,MAAM,aAAa,kBAAkB,MAAM,UAAU;AAErD,QAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,WAAW,CAChC,cAAa,KAAK,GAAG,mBAAmB,YAAY,cAAc,CAAC;;;;AAM3E,QAAO,CAAC;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ,EAAE,GAAG,aAAa;;;;ACxW7E,MAAM,eAA6B;CAAC;CAAO;CAAQ;CAAO;CAAS;CAAU;CAAQ;CAAW;CAAQ;AAOxG,SAAgB,kBACd,OACA,sBACA,kBAC2B;AAC3B,KAAI,CAAC,MAAO,QAAO;EAAE,UAAU,EAAE;EAAE,cAAc,EAAE;EAAE;CAErD,MAAM,6BAAa,IAAI,KAA0B;CACjD,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,MAAM,EAAE;EACpD,MAAM,kBAAkB,SAAS,cAAc,EAAE;AAEjD,OAAK,MAAM,UAAU,cAAc;GACjC,MAAM,KAAK,SAAS;AACpB,OAAI,CAAC,GAAI;GAET,MAAM,cAAc,iBAAiB,MAAM,GAAG,OAAO,GAAG;GAExD,MAAM,EAAE,WAAW,cAAc,aAAa,eAC5C,QACA,MACA,IACA,iBACA,sBACA,aACA,iBACD;AACD,gBAAa,KAAK,GAAG,SAAS;GAC9B,MAAM,MAAM,WAAW,IAAI,YAAY,IAAI,EAAE;AAC7C,OAAI,KAAK,UAAU;AACnB,cAAW,IAAI,aAAa,IAAI;;;AAOpC,MAAK,MAAM,CAAC,aAAa,eAAe,YAAY;EAClD,MAAM,6BAAa,IAAI,KAA0B;AACjD,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,WAAW,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,MAAM;GAC1D,MAAM,WAAW,SAAS,WAAW,IAAI,GAAG,cAAc,aAAa,SAAS;GAChF,MAAM,QAAQ,WAAW,IAAI,SAAS,IAAI,EAAE;AAC5C,SAAM,KAAK,GAAG;AACd,cAAW,IAAI,UAAU,MAAM;;AAIjC,MAAI,WAAW,OAAO;OACD,CAAC,GAAG,WAAW,MAAM,CAAC,CAAC,MAAM,MAAM,MAAM,YAAY,EACxD;AACd,eAAW,OAAO,YAAY;AAC9B,SAAK,MAAM,CAAC,WAAW,aAAa,YAAY;KAC9C,MAAM,WAAW,WAAW,IAAI,UAAU,IAAI,EAAE;AAChD,cAAS,KAAK,GAAG,SAAS;AAC1B,gBAAW,IAAI,WAAW,SAAS;;;;;AAS3C,MAAK,MAAM,GAAG,eAAe,WAC3B,4BAA2B,WAAW;AAQxC,QAAO;EAAE,UALQ,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,iBAAiB;GAC7E;GACA;GACD,EAAE;EAEgB;EAAc;;AAGnC,SAAS,iBAAiB,MAAc,KAAsB;AAG5D,KAAI,IACF,QAAO,aAAa,IAAI;CAI1B,MAAM,QADW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACzB,MAAM;AAE7B,KAAI,MAAM,WAAW,IAAI,CAAE,QAAO;AAClC,QAAO,aAAa,MAAM;;;;;;;;;;;AAY5B,SAAS,8BAA8B,aAA6B;AAClE,QAAO,YAAY,QAAQ,eAAe,GAAG;;AAG/C,SAAS,mBACP,QACA,MACA,aACA,sBACQ;AACR,KAAI,aAAa;EACf,MAAM,aAAa,8BAA8B,YAAY;AAC7D,MAAI,qBACF,QAAO,qBAAqB,WAAW;AAEzC,SAAO,YAAY,WAAW;;CAKhC,MAAM,OAAO,UAAU,QAAQ,KAAK;CACpC,MAAM,WAAW,sBAAsB,KAAK;AAC5C,QAAO,WAAW,YAAY,GAAG,KAAK,GAAG,WAAW,GAAG;;;;;AAMzD,SAAS,UAAU,QAAoB,MAAsB;CAC3D,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,mBAAmB,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,GAAG,WAAW,IAAI;AAE7F,SAAQ,QAAR;EACE,KAAK,MACH,QAAO,mBAAmB,QAAQ;EACpC,KAAK,OACH,QAAO;EACT,KAAK;EACL,KAAK,QACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,QACE,QAAO;;;;;;;;;;;;;;AAeb,SAAS,sBAAsB,MAA6B;CAC1D,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;AAChD,KAAI,SAAS,UAAU,EAAG,QAAO;CAGjC,IAAI,kBAAiC;AACrC,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,IACxC,KAAI,CAAC,SAAS,GAAG,WAAW,IAAI,EAAE;AAChC,oBAAkB,SAAS;AAC3B;;AAIJ,KAAI,CAAC,gBAAiB,QAAO;AAE7B,KAAI,oBAAoB,SAAS,GAAI,QAAO;AAE5C,QAAO,aAAa,gBAAgB;;;;;;;;;;;AAYtC,SAAS,2BAA2B,YAA+B;CAEjE,MAAM,yBAAS,IAAI,KAA0B;AAC7C,MAAK,MAAM,MAAM,YAAY;EAC3B,MAAM,QAAQ,OAAO,IAAI,GAAG,KAAK,IAAI,EAAE;AACvC,QAAM,KAAK,GAAG;AACd,SAAO,IAAI,GAAG,MAAM,MAAM;;AAG5B,MAAK,MAAM,CAAC,MAAM,UAAU,QAAQ;AAClC,MAAI,MAAM,UAAU,EAAG;AAKvB,MADoB,IAAI,IAAI,MAAM,KAAK,OAAO,GAAG,KAAK,CAAC,CACvC,QAAQ,EAAG;AAE3B,OAAK,MAAM,MAAM,OAAO;GACtB,MAAM,WAAW,sBAAsB,GAAG,KAAK;AAC/C,OAAI,SAED,IAAwB,OADT,YAAY,GAAG,KAAK,GAAG,WAAW;;EAOtD,MAAM,0BAAU,IAAI,KAA0B;AAC9C,OAAK,MAAM,MAAM,OAAO;GACtB,MAAM,SAAS,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;AACzC,UAAO,KAAK,GAAG;AACf,WAAQ,IAAI,GAAG,MAAM,OAAO;;AAE9B,OAAK,MAAM,GAAG,WAAW,SAAS;AAChC,OAAI,OAAO,UAAU,EAAG;AAGxB,QAAK,MAAM,MAAM,QAAQ;IACvB,MAAM,SAAS,mBAAmB,GAAG,KAAK;AAC1C,QAAI,OACD,IAAwB,OAAO,YAAY,GAAG,GAAG,KAAK,GAAG,SAAS;;;;;;;;;;;;AAc7E,SAAS,mBAAmB,MAA6B;CAEvD,MAAM,YADW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACrB,QAAQ,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC;AAE5D,KAAI,UAAU,UAAU,EACtB,QAAO,aAAa,UAAU,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC;AAEvD,QAAO;;;;;;;AAQT,SAAS,uBACP,IACA,aACA,kBAC8B;CAC9B,MAAM,MAAM,GAAG;AACf,KAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO,KAAA;CAE5C,MAAM,8BAAc,IAAI,KAAwB;AAChD,MAAK,MAAM,KAAK,YACd,aAAY,IAAI,EAAE,MAAM,EAAE;CAG5B,MAAM,SAA2B,EAAE;AAEnC,MAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,IAAI,EAAE;AACvD,MAAI,CAAC,YAAY,OAAO,aAAa,SACnC,OAAM,IAAI,MACR,mDAAmD,UAAU,MAAM,iBAAiB,sDACrF;AAGH,MAAI,OAAO,SAAS,aAAa,UAC/B,OAAM,IAAI,MACR,mDAAmD,UAAU,eAAe,iBAAiB,uBAC9F;AAGH,MAAI,CAAC,SAAS,YAAY,OAAO,SAAS,aAAa,SACrD,OAAM,IAAI,MACR,mDAAmD,UAAU,eAAe,iBAAiB,sEAC9F;AAGH,MAAI,OAAO,KAAK,SAAS,SAAS,CAAC,WAAW,EAC5C,OAAM,IAAI,MACR,mDAAmD,UAAU,MAAM,iBAAiB,4BACrF;EAGH,MAAM,WAAW,OAAO,QAAQ,SAAS,SAAS,CAAC,KAAK,CAAC,aAAa,gBAAgB;AACpF,OAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,WAAW,WAAW,EACtD,OAAM,IAAI,MACR,mDAAmD,UAAU,YAAY,YAAY,MAAM,iBAAiB,kDAC7G;AAWH,UAAO;IAAE,MAAM;IAAa,YATI,WAAW,KAAK,UAAU;KACxD,MAAM,UAAU,YAAY,IAAI,MAAM;AACtC,SAAI,CAAC,QACH,OAAM,IAAI,MACR,yCAAyC,UAAU,YAAY,YAAY,yBAAyB,MAAM,0DAA0D,iBAAiB,IACtL;AAEH,YAAO;MACP;IACsC;IACxC;AAEF,SAAO,KAAK;GACV,MAAM;GACN,UAAU,SAAS;GACnB;GACD,CAAC;;AAGJ,QAAO,OAAO,SAAS,IAAI,SAAS,KAAA;;;;;;;;;;AAWtC,SAAS,2BAA2B,IAAqB,kBAAwD;CAC/G,MAAM,MAAM,GAAG;AACf,KAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO,KAAA;CAK5C,MAAM,aAAa,GAAG,aAAa,UAAU,qBAAqB;CAClE,MAAM,sCAAsB,IAAI,KAA2B;AAE3D,KAAI,YAAY;AAEd,OAAK,MAAM,OAAO,WAAW,SAAS,EAAE,CACtC,MAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CACnC,KAAI,QAAQ;QACL,MAAM,CAAC,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,CAClE,KAAI,YAAa,qBAAoB,IAAI,MAAM,YAAY;;AAMnE,OAAK,MAAM,WAAW,WAAW,SAAS,EAAE,CAC1C,KAAI,QAAQ;QACL,MAAM,CAAC,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,CAClE,KAAI,YAAa,qBAAoB,IAAI,MAAM,YAAY;;;CAMnE,MAAM,SAA2B,EAAE;AAEnC,MAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,IAAI,EAAE;AACvD,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU;AAC/C,MAAI,OAAO,SAAS,aAAa,UAAW;AAC5C,MAAI,CAAC,SAAS,YAAY,OAAO,SAAS,aAAa,SAAU;AACjE,MAAI,OAAO,KAAK,SAAS,SAAS,CAAC,WAAW,EAAG;EAEjD,MAAM,WAAW,OAAO,QAAQ,SAAS,SAAS,CAAC,KAAK,CAAC,aAAa,gBAAgB;AACpF,OAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,WAAW,WAAW,EACtD,OAAM,IAAI,MACR,8CAA8C,UAAU,YAAY,YAAY,MAAM,iBAAiB,kDACxG;AAcH,UAAO;IAAE,MAAM;IAAa,YAZI,WAAW,KAAK,UAAU;KACxD,MAAM,cAAc,oBAAoB,IAAI,MAAM;AAIlD,YAAO;MACL,MAAM;MACN,MALyB,cACvB,gBAAgB,aAAa,aAAa,MAAM,CAAC,GACjD;OAAE,MAAM;OAAa,MAAM;OAAU;MAIvC,UAAU;MACV,aAAa,aAAa;MAC3B;MACD;IACsC;IACxC;AAEF,SAAO,KAAK;GACV,MAAM;GACN,UAAU,SAAS;GACnB;GACD,CAAC;;AAGJ,QAAO,OAAO,SAAS,IAAI,SAAS,KAAA;;AAGtC,SAAS,eACP,QACA,MACA,IACA,iBACA,sBACA,aACA,kBACiD;CACjD,MAAM,YAAY,CAAC,GAAG,iBAAiB,GAAI,GAAG,cAAc,EAAE,CAAE;CAEhE,MAAM,uBAAuB,UAAU,MAAM,MAAM,EAAE,OAAO,YAAY,EAAE,KAAK,aAAa,KAAK,kBAAkB;CAInH,MAAM,YAAY;CAClB,MAAM,aAAa,cAAc,WAAW,QAAQ,WAAW,iBAAiB;CAChF,MAAM,cAAc,cAAc,WAAW,SAAS,WAAW,iBAAiB;CAClF,MAAM,eAAe,cAAc,WAAW,UAAU,WAAW,iBAAiB,CAAC,QAClF,MAAM,EAAE,KAAK,aAAa,KAAK,kBACjC;CACD,MAAM,eAAe,cAAc,WAAW,UAAU,WAAW,iBAAiB;CAEpF,MAAM,gBAAyB,EAAE;CACjC,MAAM,EAAE,MAAM,aAAa,UAAU,wBAAwB,mBAAmB,GAAG,aAAa,IAAI,cAAc;CAClH,MAAM,EACJ,UACA,kBACA,QACA,cACA,aACA,UAAU,kBACV,UAAU,qBACR,iBAAiB,GAAG,WAAW,IAAI,MAAM,OAAO;AACpD,cAAa,KAAK,GAAG,cAAc;CAGnC,MAAM,uBAAuB,iBAAiB,UAAU,aAAa,iBAAiB;CACtF,IAAI;AACJ,KAAI,aAAa;EACf,MAAM,WAAW,qBAAqB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACnF,eAAa;GACX,UAAU,sBAAsB,YAAY;GAC5C,OAAO,sBAAsB,SAAS;GACtC,YAAY,sBAAsB;GAClC,UAAU,oBAAoB,sBAAsB;GACpD;GACD;YACQ,qBACT,cAAa;CAIf,MAAM,WAAW,yBAAyB,GAAG,SAAS;CAGtD,MAAM,cAAc;EAAC,GAAG;EAAY,GAAG;EAAa,GAAG;EAAc,GAAG;EAAa;CACrF,MAAM,UAAU,GAAG,eAAe,GAAG,OAAO,aAAa,CAAC,GAAG;CAC7D,MAAM,mBAAmB,uBAAuB,IAAI,aAAa,QAAQ;CAGzE,MAAM,kBAAkB,2BAA2B,IAAI,QAAQ;CAG/D,MAAM,kBACJ,oBAAoB,kBAAkB,CAAC,GAAI,oBAAoB,EAAE,EAAG,GAAI,mBAAmB,EAAE,CAAE,GAAG,KAAA;AAEpG,QAAO;EACL,WAAW;GACT,MAAM,mBAAmB,QAAQ,MAAM,GAAG,aAAa,qBAAqB;GAC5E,aAAa,iBAAiB,GAAG,SAAS,GAAG,YAAY;GACzD,YAAY;GACZ;GACA;GACA;GACA;GACA,cAAc,aAAa,SAAS,IAAI,eAAe,KAAA;GACvD;GACA;GACA;GACA;GACA;GACA;GACA,sBAAsB;GACtB,YAAY,GAAG,cAAc,KAAA;GAC7B,OAAO,GAAG;GACV;GACA;GACD;EACD;EACD;;;;;;;;AASH,SAAS,yBACP,UACmC;AACnC,KAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO,KAAA;CAE/C,MAAM,eAAsC,EAAE;AAC9C,MAAK,MAAM,SAAS,SAClB,MAAK,MAAM,CAAC,YAAY,WAAW,OAAO,QAAQ,MAAM,CACtD,cAAa,KAAK;EAAE;EAAY,QAAQ,UAAU,EAAE;EAAE,CAAC;AAG3D,QAAO,aAAa,SAAS,IAAI,eAAe,KAAA;;AAGlD,SAAS,iBAAiB,SAA6B,aAAqD;AAC1G,KAAI,WAAW,eAAe,YAAY,YACxC,QAAO,GAAG,QAAQ,MAAM;AAE1B,QAAO,eAAe;;AAGxB,SAAS,cACP,QACA,UACA,kBACA,kBACa;AACb,QAAO,OACJ,QAAQ,MAAM,EAAE,OAAO,SAAS,CAChC,KAAK,MAAM;EACV,MAAM,YAAY,sBAAsB,EAAE,QAAQ,iBAAiB;AACnE,SAAO;GACL,MAAM,EAAE;GACR,MAAM,EAAE,SACJ,gBAAgB,EAAE,QAAQ,EAAE,MAAM,mBAAmB,aAAa,iBAAiB,GAAG,KAAA,EAAU,GAC/F;IAAE,MAAM;IAAa,MAAM;IAAU;GAC1C,UAAU,EAAE,YAAY;GACxB,aAAa,EAAE;GACf,YAAY,EAAE,cAAc,EAAE,QAAQ,cAAc,WAAW,cAAc,KAAA;GAC7E,SAAS,EAAE,QAAQ,WAAW,WAAW;GACzC,SAAS,EAAE,WAAW,EAAE,QAAQ,WAAW,WAAW;GACtD,OAAO,EAAE;GACT,SAAS,EAAE;GACZ;GACD;;;;;;;;;;;;AAaN,SAAS,sBACP,QACA,kBAC0B;AAC1B,KAAI,CAAC,UAAU,CAAC,iBAAkB,QAAO,KAAA;CACzC,MAAM,MAAO,OAA6B;AAC1C,KAAI,CAAC,IAAK,QAAO,KAAA;CACjB,MAAM,QAAQ,iCAAiC,KAAK,IAAI;AACxD,KAAI,CAAC,MAAO,QAAO,KAAA;AACnB,QAAO,iBAAiB,MAAM;;AAGhC,SAAS,mBACP,MACA,IACA,cAC6F;AAC7F,KAAI,CAAC,MAAM,QAAS,QAAO,EAAE;CAG7B,IAAI,WAAyE;CAC7E,IAAI;AAEJ,KAAI,KAAK,QAAQ,qBAAqB,QAAQ;AAC5C,aAAW;AACX,WAAS,KAAK,QAAQ,oBAAqB;YAClC,KAAK,QAAQ,wBAAwB,QAAQ;AACtD,aAAW;AACX,WAAS,KAAK,QAAQ,uBAAwB;YACrC,KAAK,QAAQ,sCAAsC,QAAQ;AACpE,aAAW;AACX,WAAS,KAAK,QAAQ,qCAAsC;YACnD,KAAK,QAAQ,6BAA6B;AACnD,aAAW;AACX,WAAS,KAAK,QAAQ,4BAA6B;YAC1C,KAAK,QAAQ,eAAe;AACrC,aAAW;AACX,WAAS,KAAK,QAAQ,cAAe;;AAGvC,KAAI,CAAC,QAAQ;AAEX,MAAI,aAAa,SACf,QAAO;GAAE,MAAM;IAAE,MAAM;IAAa,MAAM;IAAU,QAAQ;IAAU;GAAE;GAAU;AAEpF,MAAI,aAAa,OACf,QAAO;GAAE,MAAM;IAAE,MAAM;IAAa,MAAM;IAAU;GAAE;GAAU;AAElE,SAAO,EAAE;;CAMX,MAAM,cAAc,gBAHJ,IAAI,cAChB,aAAa,8BAA8B,GAAG,YAAY,CAAC,GAAG,YAC9D,cACwC;AAG5C,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;EAClD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,WAAW,EAAE;AACxE,OAAI,CAAC,YAAa;AAClB,UAAO,KAAK,qBAAqB,WAAW,aAAa,aAAa,YAAY,CAAC;;AAErF,eAAa,KAAK;GAAE,MAAM;GAAa,aAAa,KAAA;GAAW;GAAQ,CAAC;AACxE,SAAO;GAAE,MAAM;IAAE,MAAM;IAAS,MAAM;IAAa;GAAE;GAAU;;AAKjE,KAAI,OAAO,OAAO;EAChB,MAAM,WAAsB,EAAE;AAE9B,OAAK,MAAM,WAAW,OAAO,MAC3B,KAAI,QAAQ,MAAM;GAChB,MAAM,MAAM,gBAAgB,SAAS,YAAY;AACjD,YAAS,KAAK,IAAI;aACT,QAAQ,SAAS,QAAQ,YAEzB,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;GAC7E,MAAM,cAAc,uBAAuB,SAAS,aAAa,aAAa;GAC9E,MAAM,cAAc,IAAI,IAAI,QAAQ,YAAY,EAAE,CAAC;GACnD,MAAM,SAAkB,EAAE;AAC1B,QAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,QAAI,CAAC,YAAa;AAClB,WAAO,KAAK,qBAAqB,WAAW,aAAa,aAAa,YAAY,CAAC;;AAErF,gBAAa,KAAK;IAAE,MAAM;IAAa,aAAa,QAAQ;IAAa;IAAQ,CAAC;AAClF,YAAS,KAAK;IAAE,MAAM;IAAS,MAAM;IAAa,CAAC;QAEnD,UAAS,KAAK,gBAAgB,SAAS,YAAY,CAAC;EAIxD,MAAM,UAAU,OAAO,MAAM,MAC1B,MAAoB,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,OAAO,CAC5F;EACD,MAAM,QAAiB;GACrB,MAAM;GACN;GACA,GAAI,OAAO,gBACP,EACE,eAAe;IAAE,UAAU,OAAO,cAAc;IAAc,SAAS,OAAO,cAAc,WAAW,EAAE;IAAE,EAC5G,GACD,EAAE;GACP;AAED,SAAO;GAAE,MADI,UAAW;IAAE,MAAM;IAAY,OAAO;IAAO,GAAe;GAC1D;GAAU;;AAG3B,QAAO;EAAE,MAAM,gBAAgB,QAAQ,YAAY;EAAE;EAAU;;;AAIjE,SAAS,uBAAuB,SAAuB,UAAkB,gBAAiC;AAExG,KAAI,QAAQ;OACL,MAAM,GAAG,eAAe,OAAO,QAAQ,QAAQ,WAAW,CAC7D,KAAI,YAAY,SAAS,OAAO,WAAW,UAAU,SACnD,QAAO,aAAa,WAAW,MAAM,GAAG,SAAS,QAAQ,YAAY,GAAG,GAAG;;CAKjF,MAAM,gBAAgB,IAAI,IAAI,eAAe,KAAK,MAAM,EAAE,KAAK,CAAC;CAChE,IAAI,OAAO;CACX,IAAI,SAAS;AACb,QAAO,cAAc,IAAI,KAAK,EAAE;AAC9B,SAAO,GAAG,WAAW;AACrB;;AAEF,QAAO;;AAGT,SAAS,mBAAmB,IAAiC,MAAc,QAA4B;AACrG,KAAI,IAAI,YACN,QAAO,gBAAgB,aAAa,8BAA8B,GAAG,YAAY,CAAC,GAAG,WAAW;AAIlG,QAAO,aAFU,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACtB,MAAM,UACH,GAAG,aAAa,OAAO,GAAG;;AAGzD,SAAS,iBACP,WACA,IACA,MACA,QASA;CACA,MAAM,SAA0B,EAAE;CAClC,IAAI,WAAoB;EAAE,MAAM;EAAa,MAAM;EAAU;CAC7D,IAAI,eAAwB,EAAE;CAC9B,IAAI,cAAc;CAClB,IAAI;CACJ,IAAI;AAEJ,KAAI,CAAC,UAAW,QAAO;EAAE;EAAU;EAAQ;EAAc;EAAa;CAEtE,MAAM,sBAAyC,EAAE;AAEjD,MAAK,MAAM,CAAC,YAAY,SAAS,OAAO,QAAQ,UAAU,EAAE;EAC1D,MAAM,OAAO,SAAS,YAAY,GAAG;AAErC,MAAI,QAAQ,OAAO,OAAO,KAAK;GAC7B,IAAI,gBAAyB;IAAE,MAAM;IAAa,MAAM;IAAW;GACnE,MAAM,cAAc,KAAK,UAAU;AACnC,OAAI,aAAa,QAAQ;IACvB,MAAM,cAAc,mBAAmB,IAAI,QAAQ,KAAK,UAAU,MAAM;IACxE,MAAM,SAAS,2BAA2B,YAAY,QAAQ,YAAY;AAC1E,oBAAgB,OAAO;AAEvB,mBAAe,OAAO;AACtB,kBAAc,OAAO;AACrB,eAAW,OAAO;AAClB,eAAW,OAAO;cACT,KAAK,QAEd,KAAI,KAAK,QAAQ,+BAA+B,KAAK,QAAQ,mBAC3D,iBAAgB;IAAE,MAAM;IAAa,MAAM;IAAU,QAAQ;IAAU;YAEvE,KAAK,QAAQ,iBACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,eACb,KAAK,QAAQ,mBAEb,iBAAgB;IAAE,MAAM;IAAa,MAAM;IAAU;QAChD;IAEL,MAAM,WAAW,OAAO,KAAK,KAAK,QAAQ,CAAC;AAC3C,QAAI,UAAU;KACZ,MAAM,eAAe,KAAK,QAAQ;AAClC,SAAI,cAAc,OAChB,iBAAgB,gBACd,aAAa,QACb,mBAAmB,IAAI,QAAQ,KAAK,UAAU,MAAM,CACrD;;;AAKT,uBAAoB,KAAK;IAAE,YAAY;IAAM,MAAM;IAAe,CAAC;aAC1D,QAAQ,OAAO,OAAO,IAE/B,qBAAoB,KAAK;GAAE,YAAY;GAAM,MAAM;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE,CAAC;WACnF,QAAQ,KAAK;GACtB,MAAM,cAAc,KAAK,UAAU;GACnC,MAAM,OAAO,aAAa,SAAS,gBAAgB,YAAY,QAAQ,QAAQ,OAAO,GAAG,KAAA;AACzF,UAAO,KAAK;IAAE,YAAY;IAAM;IAAM,CAAC;;;AAK3C,KAAI,oBAAoB,SAAS,GAAG;EAClC,MAAM,SAAS,CAAC,GAAG,oBAAoB,CAAC,MAAM,GAAG,MAAM,EAAE,aAAa,EAAE,WAAW;AAGnF,cADE,OAAO,MAAM,MAAM,EAAE,KAAK,SAAS,eAAgB,EAAE,KAA0B,SAAS,UAAU,IAAI,OAAO,IAC5F;;CAGrB,MAAM,mBAAmB,oBAAoB,SAAS,IAAI,sBAAsB,KAAA;AAEhF,QAAO;EAAE;EAAU;EAAkB;EAAQ;EAAc;EAAa;EAAU;EAAU;;;;ACv2B9F,SAAS,kBAAkB,QAA0B;CACnD,MAAM,yBAAS,IAAI,KAAoB;AACvC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,WAAW,OAAO,IAAI,MAAM,KAAK;AACvC,MAAI,CAAC,YAAY,MAAM,OAAO,SAAS,SAAS,OAAO,OACrD,QAAO,IAAI,MAAM,MAAM,MAAM;;AAGjC,QAAO,CAAC,GAAG,OAAO,QAAQ,CAAC;;AAG7B,SAAS,gBAAgB,KAAc,SAAiB,SAAuB;AAC7E,aAAY,KAAK,EACf,QAAQ,MAAM;AACZ,MAAI,EAAE,SAAS,QAAU,GAAuB,OAAO;IAE1D,CAAC;;AAGJ,SAAS,iBAAiB,QAAiB,UAAqB,SAAiB,SAAuB;AACtG,MAAK,MAAM,SAAS,OAClB,MAAK,MAAM,SAAS,MAAM,OACxB,iBAAgB,MAAM,MAAM,SAAS,QAAQ;AAGjD,MAAK,MAAM,WAAW,SACpB,MAAK,MAAM,MAAM,QAAQ,YAAY;AACnC,kBAAgB,GAAG,UAAU,SAAS,QAAQ;AAC9C,MAAI,GAAG,YACL,iBAAgB,GAAG,aAAa,SAAS,QAAQ;;;AAMzD,SAAgB,0BAA0B,cAAuB,cAAgC;CAC/F,MAAM,qBAAqB,CAAC,GAAG,aAAa;CAC5C,MAAM,mBAAmB,IAAI,IAAI,mBAAmB,KAAK,MAAM,EAAE,KAAK,CAAC;CACvE,MAAM,qBAAqB,IAAI,IAAI,mBAAmB,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAE9E,MAAM,2BAA2B,aAAa,QAAQ,UAAU;AAC9D,MAAI,CAAC,iBAAiB,IAAI,MAAM,KAAK,CAAE,QAAO;EAE9C,MAAM,WAAW,mBAAmB,IAAI,MAAM,KAAK;EACnD,MAAM,qBAAqB,IAAI,IAAI,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACtE,MAAM,mBAAmB,IAAI,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACjE,MAAM,gBACJ,MAAM,OAAO,MAAM,MAAM,CAAC,mBAAmB,IAAI,EAAE,KAAK,CAAC,IACzD,SAAS,OAAO,MAAM,MAAM,CAAC,iBAAiB,IAAI,EAAE,KAAK,CAAC;AAE5D,MAAI,iBAAiB,MAAM,OAAO,SAAS,SAAS,OAAO,QAAQ;GACjE,MAAM,MAAM,mBAAmB,QAAQ,SAAS;AAChD,OAAI,QAAQ,GAAI,oBAAmB,OAAO;AAC1C,sBAAmB,IAAI,MAAM,MAAM,MAAM;AACzC,WAAQ,KACN,kCAAkC,MAAM,KAAK,2CAA2C,MAAM,OAAO,OAAO,MAAM,SAAS,OAAO,OAAO,iCAC1I;aACQ,cACT,SAAQ,KACN,kCAAkC,MAAM,KAAK,uEAC9C;AAGH,SAAO;GACP;AAEF,QAAO,CAAC,GAAG,oBAAoB,GAAG,kBAAkB,yBAAyB,CAAC;;AAGhF,SAAgB,uBAAuB,gBAAyB,mBAAqC;CACnG,MAAM,aAAa,IAAI,IAAI,eAAe,KAAK,MAAM,EAAE,KAAK,CAAC;CAC7D,MAAM,eAAe,IAAI,IAAI,eAAe,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAEpE,MAAM,0BAA0B,kBAAkB,QAAQ,UAAU;AAClE,MAAI,CAAC,WAAW,IAAI,MAAM,KAAK,CAAE,QAAO;EAExC,MAAM,WAAW,aAAa,IAAI,MAAM,KAAK;EAC7C,MAAM,qBAAqB,IAAI,IAAI,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACtE,MAAM,mBAAmB,IAAI,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AAKjE,MAHE,MAAM,OAAO,MAAM,MAAM,CAAC,mBAAmB,IAAI,EAAE,KAAK,CAAC,IACzD,SAAS,OAAO,MAAM,MAAM,CAAC,iBAAiB,IAAI,EAAE,KAAK,CAAC,CAG1D,SAAQ,KACN,kCAAkC,MAAM,KAAK,uEAC9C;AAGH,SAAO;GACP;AAEF,QAAO,CAAC,GAAG,gBAAgB,GAAG,kBAAkB,wBAAwB,CAAC;;AAG3E,SAAS,0BAA0B,OAAuB;AACxD,QAAO,MAAM,OAAO,MACjB,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,WAAW,EAAE,KAAK,SAAS,aAAa,OAAO,EAAE,KAAK,UAAU,SAC3G;;AAGH,SAAS,0BAA0B,MAAc,QAAiB,cAAoC;AACpG,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,aAAa,IAAI,MAAM,KAAK,CAAE;AAClC,OAAK,MAAM,SAAS,MAAM,QAAQ;GAChC,IAAI,QAAQ;AACZ,eAAY,MAAM,MAAM,EACtB,QAAQ,MAAM;AACZ,QAAI,EAAE,SAAS,KAAM,SAAQ;MAEhC,CAAC;AACF,OAAI,MAAO,QAAO;;;AAGtB,QAAO;;AAGT,SAAgB,yBAAyB,QAAiB,UAA8B;CACtF,MAAM,mBAAmB,CAAC,GAAG,OAAO;CACpC,MAAM,SAAS,IAAI,IAAI,iBAAiB,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAGhE,MAAM,kBAAiE,EAAE;AACzE,MAAK,MAAM,SAAS,kBAAkB;AACpC,MAAI,CAAC,MAAM,KAAK,SAAS,OAAO,CAAE;EAElC,MAAM,WAAW,MAAM,KAAK,MAAM,GAAG,GAAG;EACxC,MAAM,YAAY,OAAO,IAAI,SAAS;AACtC,MAAI,CAAC,aAAa,MAAM,OAAO,UAAU,UAAU,OAAO,OAAQ;AAGlE,MAAI,CADe,UAAU,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,GAAG,SAAS,EAAE,KAAK,CAAC,CAC9E;AAGjB,MAAI,0BAA0B,MAAM,IAAI,0BAA0B,UAAU,CAAE;AAG9E,MAAI,0BAA0B,MAAM,MAAM,kBAAkB,IAAI,IAAI,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC,CAAE;AAE9F,kBAAgB,KAAK;GAAE,WAAW;GAAO;GAAW,CAAC;;CAIvD,MAAM,2BAAW,IAAI,KAAa;AAClC,MAAK,MAAM,EAAE,WAAW,eAAe,iBAAiB;AACtD,YAAU,SAAS,UAAU;AAC7B,WAAS,IAAI,UAAU,KAAK;AAC5B,mBAAiB,kBAAkB,UAAU,UAAU,MAAM,UAAU,KAAK;AAC5E,UAAQ,KACN,mBAAmB,UAAU,KAAK,UAAU,UAAU,KAAK,KAAK,UAAU,OAAO,OAAO,oBACzF;;AAMH,MAAK,MAAM,EAAE,WAAW,eAAe,iBAAiB;EACtD,MAAM,aAAa,UAAU;EAC7B,MAAM,aAAa,UAAU;AAE7B,OAAK,MAAM,SAAS,kBAAkB;AACpC,OAAI,SAAS,IAAI,MAAM,KAAK,CAAE;AAC9B,OAAI,MAAM,KAAK,UAAU,WAAW,OAAQ;AAC5C,OAAI,CAAC,MAAM,KAAK,WAAW,WAAW,CAAE;GAExC,MAAM,UAAU,aAAa,MAAM,KAAK,MAAM,WAAW,OAAO;GAChE,MAAM,WAAW,OAAO,IAAI,QAAQ;AAEpC,OAAI,YAAY,CAAC,SAAS,IAAI,SAAS,KAAK,EAAE;AAC5C,aAAS,IAAI,MAAM,KAAK;AACxB,qBAAiB,kBAAkB,UAAU,MAAM,MAAM,QAAQ;AACjE,YAAQ,KAAK,4BAA4B,MAAM,KAAK,mBAAmB,QAAQ,GAAG;UAC7E;AACL,qBAAiB,kBAAkB,UAAU,MAAM,MAAM,QAAQ;AACjE,UAAM,OAAO;AACb,WAAO,IAAI,SAAS,MAAM;AAC1B,YAAQ,KAAK,0BAA0B,WAAW,QAAQ,QAAQ,GAAG;;;;AAK3E,QAAO,iBAAiB,QAAQ,MAAM,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;;;;ACrL9D,SAAgB,6BAA6B,QAAiB,OAAqB;CACjF,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AACnD,MAAK,MAAM,SAAS,OAClB,MAAK,MAAM,SAAS,MAAM,OACxB,0BAAyB,MAAM,MAAM,OAAO,UAAU;;;;;;AAS5D,SAAgB,iCAAiC,UAAqB,OAAqB;CACzF,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AACnD,MAAK,MAAM,WAAW,SACpB,MAAK,MAAM,MAAM,QAAQ,WACvB,MAAK,MAAM,SAAS;EAAC,GAAG,GAAG;EAAY,GAAG,GAAG;EAAa,GAAG,GAAG;EAAc,GAAI,GAAG,gBAAgB,EAAE;EAAE,CACvG,0BAAyB,MAAM,MAAM,OAAO,UAAU;;;;AClB9D,SAAgB,kBAAkB,MAAqB;CACrD,MAAM,6BAAa,IAAI,KAAa;AACpC,MAAK,MAAM,KAAK,KAAK,OAAQ,YAAW,IAAI,EAAE,KAAK;AACnD,MAAK,MAAM,KAAK,KAAK,MAAO,YAAW,IAAI,EAAE,KAAK;CAElD,SAAS,QAAQ,KAAc,SAAuB;AACpD,cAAY,KAAK,EACf,QAAQ,MAAM;AACZ,OAAI,CAAC,WAAW,IAAI,EAAE,KAAK,CACzB,SAAQ,KAAK,gDAAgD,EAAE,KAAK,cAAc,QAAQ,GAAG;KAGlG,CAAC;;AAGJ,MAAK,MAAM,SAAS,KAAK,OACvB,MAAK,MAAM,SAAS,MAAM,OACxB,SAAQ,MAAM,MAAM,GAAG,MAAM,KAAK,GAAG,MAAM,OAAO;AAItD,MAAK,MAAM,WAAW,KAAK,SACzB,MAAK,MAAM,MAAM,QAAQ,YAAY;AACnC,OAAK,MAAM,KAAK;GAAC,GAAG,GAAG;GAAY,GAAG,GAAG;GAAa,GAAG,GAAG;GAAa,CACvE,SAAQ,EAAE,MAAM,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,GAAG,EAAE,OAAO;AAEzD,MAAI,GAAG,YAAa,SAAQ,GAAG,aAAa,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,cAAc;AACrF,UAAQ,GAAG,UAAU,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,WAAW;;;;;ACqBjE,eAAsB,UAAU,UAAkB,SAA0C;CAC1F,MAAM,EAAE,WAAW,MAAM,kBAAkB,SAAS;CAGpD,MAAM,OAFc,SAAS,gBAAgB,QAAQ,cAAc,OAAO,GAAG;CAiB7E,MAAM,UAAU,KAAK,WAAW;AAChC,KAAI,CAAC,QAAQ,WAAW,KAAK,CAC3B,OAAM,IAAI,eACR,gCAAgC,QAAQ,+BACxC,oHAAoH,SAAS,KAC9H;CAGH,MAAM,EAAE,QAAQ,UAAU,eACxB,KAAK,YAAY,SACjB,EAAE,qBAAqB,SAAS,qBAAqB,CACtD;CAED,MAAM,EAAE,UAAU,iBAAiB,kBACjC,KAAK,OACL,SAAS,sBACT,KAAK,YAAY,QAClB;CAED,MAAM,2BAA2B,0BAA0B,QAAQ,aAAa;CAMhF,MAAM,oBAAoB,+BACxB,KAAK,YAAY,QAClB;AACD,2BAA0B;CAE1B,MAAM,cAAc,yBADM,uBAAuB,0BAA0B,kBAAkB,EAC7B,SAAS;AACzE,iBAAgB,aAAa,SAAS,WAAW;AACjD,8BAA6B,aAAa,MAAM;AAChD,kCAAiC,UAAU,MAAM;CAEjD,MAAM,OAAO,mBAAmB,KAAK,YAAY,gBAAgB;CAEjE,MAAM,iBAAgC,KAAK,WAAW,EAAE,EACrD,KAAK,OAAO;EAAE,KAAK,EAAE,OAAO;EAAI,aAAa,EAAE;EAAa,EAAE,CAC9D,QAAQ,MAAM,EAAE,IAAI;CAEvB,MAAM,SAAkB;EACtB,MAAM,KAAK,MAAM,SAAS;EAC1B,SAAS,KAAK,MAAM,WAAW;EAC/B,aAAa,KAAK,MAAM;EACxB,SAAS,cAAc,IAAI,OAAO;EAClC,SAAS,cAAc,SAAS,IAAI,gBAAgB,KAAA;EACpD;EACA,QAAQ;EACR;EACA;EACA,KAAK,oBAAoB;EAC1B;AAED,mBAAkB,OAAO;AAEzB,QAAO;;;;;;;AAOT,SAAS,gBACP,QACA,YACM;AACN,KAAI,CAAC,WAAY;AACjB,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,QAAQ,WAAW,MAAM;AAC/B,MAAI,CAAC,MAAO;AACZ,OAAK,MAAM,SAAS,MAAM,QAAQ;GAChC,MAAM,aAAa,MAAM,MAAM;AAC/B,OAAI,WAAY,OAAM,aAAa;;;;;AAMzC,SAAS,mBACP,iBAI0B;AAC1B,KAAI,CAAC,gBAAiB,QAAO,KAAA;CAC7B,MAAM,UAAwB,EAAE;AAChC,MAAK,MAAM,GAAG,WAAW,OAAO,QAAQ,gBAAgB,CACtD,KAAI,OAAO,SAAS,UAAU,OAAO,WAAW,SAC9C,SAAQ,KAAK,EAAE,MAAM,UAAU,CAAC;UACvB,OAAO,SAAS,YAAY,OAAO,MAAM,OAAO,KACzD,SAAQ,KAAK;EAAE,MAAM;EAAU,IAAI,OAAO;EAAqC,MAAM,OAAO;EAAM,CAAC;UAC1F,OAAO,SAAS,YAAY,OAAO,MAC5C,SAAQ,KAAK;EAAE,MAAM;EAAU,OAAO,OAAO;EAAO,CAAC;AAGzD,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;;;;ACtFxC,IAAW,kCAAkB,IAAI,KAAa;;AAG9C,IAAW,gCAAgB,IAAI,KAAa;;;;;AAM5C,IAAI,mBAA2C,EAAE;;AAgBjD,SAAgB,gBAAgB,YAA2B;AACzD,KAAI,CAAC,WAAY;CACjB,MAAM,MAAM,aAAa,YAAY,QAAQ;CAC7C,MAAM,SAAsB,KAAK,MAAM,IAAI;AAE3C,KAAI,OAAO,eAAgB,mBAAkB,IAAI,IAAI,OAAO,eAAe;AAC3E,KAAI,OAAO,aAAc,iBAAgB,IAAI,IAAI,OAAO,aAAa;AACrE,KAAI,OAAO,gBAAiB,oBAAmB,OAAO;AACtD,KAAI,OAAO,mBAAoB,CAAuB,OAAO;;;;;;AAiB/D,SAAS,iBAAiB,IAAuB;CAC/C,MAAM,YAAY,GAAG,WAAW,SAAS;CACzC,MAAM,SAAS,GAAG;AAElB,KAAI,WAAW,UAAU,CAAC,UAAW,QAAO;AAC5C,KAAI,WAAW,SAAS,CAAC,aAAa,GAAG,WAAY,QAAO;AAC5D,KAAI,WAAW,SAAS,CAAC,UAAW,QAAO;AAC3C,KAAI,WAAW,UAAU,UAAW,QAAO;AAC3C,KAAI,WAAW,SAAS,aAAa,GAAG,WAAY,QAAO;AAC3D,KAAI,WAAW,SAAS,UAAW,QAAO;AAC1C,KAAI,WAAW,SAAS,WAAW,QAAS,QAAO;AACnD,KAAI,WAAW,SAAU,QAAO;AAChC,QAAO;;AAGT,SAAgB,eAAe,MAA+B;CAC5D,MAAM,SAAyB,EAAE;AAEjC,MAAK,MAAM,WAAW,KAAK,UAAU;AACnC,MAAI,cAAc,IAAI,QAAQ,KAAK,CAAE;EAErC,MAAM,MAA0B,EAAE;AAClC,OAAK,MAAM,MAAM,QAAQ,YAAY;AACnC,OAAI,gBAAgB,IAAI,GAAG,KAAK,CAAE;AAElC,OAAI,KAAK;IAAE,SAAS,QAAQ;IAAM,WAAW;IAAI,CAAC;;AAGpD,MAAI,IAAI,WAAW,EAAG;AAUtB,MAAI,MAAM,GAAG,MAAM;AACjB,UAAO,iBAAiB,EAAE,UAAU,GAAG,iBAAiB,EAAE,UAAU;IACpE;AAEF,SAAO,KAAK;GAAE,SAAS,QAAQ;GAAM,YAAY;GAAK,CAAC;;AAIzD,QAAO,MAAM,GAAG,MAAM;AAGpB,UAFa,iBAAiB,EAAE,YAAY,OAC/B,iBAAiB,EAAE,YAAY;GAE5C;AAEF,QAAO;;AA8GT,SAAgB,qBAAqB,SAAkB,WAAmB,MAAwB;AAChG,SAAQ,QAAQ,MAAhB;EACE,KAAK,YACH,QAAO,yBAAyB,QAAQ,MAAM,QAAQ,QAAQ,UAAU;EAC1E,KAAK,QACH,QAAO,CAAC,qBAAqB,QAAQ,OAAO,WAAW,KAAK,CAAC;EAC/D,KAAK,SAAS;GACZ,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM,EAAE,SAAS,QAAQ,KAAK;AAC9D,OAAI,OAAO;IACT,MAAM,MAA+B,EAAE;AACvC,SAAK,MAAM,SAAS,MAAM,OACxB,KAAI,MAAM,SACR,KAAI,YAAY,MAAM,KAAK,IAAI,qBAAqB,MAAM,MAAM,MAAM,MAAM,KAAK;AAGrF,WAAO;;AAET,UAAO,EAAE;;EAEX,KAAK,OAEH,QADU,KAAK,MAAM,MAAM,OAAO,GAAG,SAAS,QAAQ,KAAK,EACjD,OAAO,IAAI,SAAS;EAEhC,KAAK,WACH,QAAO,qBAAqB,QAAQ,OAAO,WAAW,KAAK;EAC7D,KAAK;AACH,OAAI,QAAQ,SAAS,SAAS,EAC5B,QAAO,qBAAqB,QAAQ,SAAS,IAAI,WAAW,KAAK;AAEnE,UAAO;;;AAIb,SAAS,yBAAyB,MAAc,QAA4B,WAA4B;AACtG,KAAI,SAAS,UAAU;AACrB,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,WAAW,YAAa,QAAO;AACnC,MAAI,WAAW,QAAS,QAAO;AAC/B,MAAI,WAAW,SAAS,WAAW,MAAO,QAAO;AACjD,SAAO,QAAQ,YAAY,UAAU;;AAEvC,KAAI,SAAS,UAAW,QAAO;AAC/B,KAAI,SAAS,SAAU,QAAO;AAC9B,KAAI,SAAS,UAAW,QAAO;AAC/B,QAAO;;;AAIT,SAAgB,gBAAgB,IAAe,MAA+C;AAC5F,KAAI,CAAC,GAAG,YAAa,QAAO;CAE5B,MAAM,WAAW,GAAG;AACpB,KAAI,SAAS,SAAS,SAAS;EAC7B,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM,EAAE,SAAS,SAAS,KAAK;AAC/D,MAAI,CAAC,MAAO,QAAO,EAAE;EAErB,MAAM,UAAmC,EAAE;AAC3C,OAAK,MAAM,SAAS,MAAM,QAAQ;AAChC,OAAI,CAAC,MAAM,SAAU;GACrB,MAAM,MAAM,YAAY,MAAM,KAAK;GACnC,IAAI,QAAQ,qBAAqB,MAAM,MAAM,MAAM,MAAM,KAAK;AAG9D,QAAK,QAAQ,UAAU,QAAQ,WAAW,OAAO,UAAU,SACzD,SAAQ,SAAS,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAEvE,WAAQ,OAAO;;AAEjB,SAAO;;AAIT,QAAO,EAAE;;;AAwCX,SAAgB,oBAAoB,IAAe,MAAuC;CACxF,MAAM,SAAiC,EAAE;AAEzC,KAAI,GAAG,WACL,QAAO,WAAW;AAGpB,MAAK,MAAM,KAAK,GAAG,aAAa;AAC9B,MAAI,CAAC,EAAE,SAAU;EACjB,MAAM,QAAQ,qBAAqB,EAAE,MAAM,EAAE,MAAM,KAAK;AACxD,SAAO,YAAY,EAAE,KAAK,IAAI,OAAO,MAAM;;CAI7C,MAAM,SAAiC,EAAE;AACzC,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,CAAC,MAAM,CAC1C,QAAO,OAAO,OAAO;AAEvB,QAAO;;AAoOT,SAAgB,YAAY,IAAe,YAA4C;CACrF,IAAI,OAAO,GAAG;AACd,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,WAAW,CACpD,QAAO,KAAK,QAAQ,IAAI,KAAK,IAAI,MAAM;AAEzC,QAAO;;AAWT,SAAgB,eAAyE;CACvF,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;CAClC,MAAM,UAAU,KAAK,QAAQ,SAAS;CACtC,MAAM,OAAO,YAAY,MAAM,KAAK,UAAU,KAAK,KAAK,UAAU,KAAK,QAAQ,IAAI;AACnF,KAAI,CAAC,MAAM;AACT,UAAQ,MAAM,sFAAsF;AACpG,UAAQ,KAAK,EAAE;;CAEjB,MAAM,aAAa,KAAK,QAAQ,aAAa;CAC7C,MAAM,UAAU,eAAe,MAAM,KAAK,aAAa,KAAK,KAAK,aAAa,KAAK,KAAA;CACnF,MAAM,YAAY,KAAK,QAAQ,iBAAiB;AAEhD,QAAO;EAAE;EAAM;EAAS,aADJ,cAAc,MAAM,KAAK,YAAY,KAAK,KAAK,YAAY,KAAK,QAAQ,IAAI;EAC3D;;;;;;;;;;;;;;AC/oBvC,eAAe,OAAO;CACpB,MAAM,EAAE,MAAM,UAAU,gBAAgB,cAAc;AACtD,iBAAgB,YAAY;AAE5B,SAAQ,IAAI,kBAAkB;CAC9B,MAAM,OAAO,MAAM,UAAU,SAAS;AACtC,SAAQ,IAAI,SAAS,KAAK,KAAK,IAAI,KAAK,UAAU;CAElD,MAAM,SAAS,eAAe,KAAK;CACnC,MAAM,YAAgC,EAAE;AAExC,MAAK,MAAM,SAAS,OAClB,MAAK,MAAM,WAAW,MAAM,YAAY;EACtC,MAAM,KAAK,QAAQ;EACnB,MAAM,cAAc,GAAG,MAAM,QAAQ,GAAG,GAAG;EAG3C,MAAM,oBAA4C,EAAE;AACpD,OAAK,MAAM,KAAK,GAAG,WACjB,mBAAkB,EAAE,QAAQ;EAE9B,MAAM,OAAO,YAAY,IAAI,kBAAkB;EAE/C,MAAM,cAAc,oBAAoB,IAAI,KAAK;EACjD,MAAM,OAAO,gBAAgB,IAAI,KAAK;EAUtC,MAAM,SAPyC;GAC7C,MAAM;GACN,KAAK;GACL,KAAK;GACL,OAAO;GACP,QAAQ;GACT,CAC6B,GAAG,eAAe;AAEhD,YAAU,KAAK;GACb;GACA,SAAS,MAAM;GACf,eAAe,GAAG;GAClB,SAAS;IACP,QAAQ,GAAG,WAAW,aAAa;IACnC;IACA;IACA;IACD;GACD,UAAU;IACR;IACA,MAAM;IACP;GACD,SAAS;GACT,YAAY;GACb,CAAC;;CAIN,MAAM,UAAwB;EAC5B,QAAQ;EACR,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC,aAAa,KAAK;EAClB;EACD;AAED,eAAc,oCAAoC,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AAEnF,SAAQ,IAAI,eAAe,UAAU,OAAO,uBAAuB;AACnE,SAAQ,IAAI,8CAA8C;;AAG5D,MAAM,CAAC,OAAO,QAAQ;AACpB,SAAQ,MAAM,+BAA+B,IAAI;AACjD,SAAQ,KAAK,EAAE;EACf"}