{"version":3,"sources":["../src/client.ts","../src/assets.ts","../../loading-tokens/src/index.ts","../src/provider.ts"],"sourcesContent":["/**\n * OneAuthClient — the primary entry point for the @rhinestone/1auth SDK.\n *\n * Manages all communication between an integrating app and the 1auth passkey\n * service (apps/passkey). Interactions happen in two ways:\n *\n *   1. HTTP — direct REST calls to the passkey service API for non-interactive\n *      operations such as intent preparation, status polling, and consent checks.\n *\n *   2. PostMessage — iframe/popup dialogs hosted at the passkey domain handle\n *      WebAuthn ceremonies and return results to the parent page.\n *\n * Supported flows:\n *   - Authentication (sign in / sign up) via modal, popup, or redirect\n *   - Passkey challenge signing for off-chain login\n *   - EIP-712 typed data signing\n *   - Cross-chain intents via the Rhinestone orchestrator\n *   - Batch intents (multiple chains, single passkey tap)\n *   - Data consent management\n */\nimport { hashTypedData, type TypedDataDefinition } from \"viem\";\nimport { fetchAssetsResponse } from \"./assets\";\nimport { tokenFetchError } from \"./sponsorship-fetch\";\nimport {\n  executeErrorCode,\n  executeErrorDetails,\n  normalizeOneAuthErrorDetails,\n  parseSigningResultError,\n} from \"./errors\";\nimport type {\n  AssetsResponse,\n  PasskeyProviderConfig,\n  SigningRequestOptions,\n  SigningResult,\n  CreateSigningRequestResponse,\n  SigningRequestStatus,\n  EmbedOptions,\n  PasskeyCredentials,\n  SigningPasskeyCredentials,\n  AuthResult,\n  AuthFlow,\n  AuthWithModalOptions,\n  LoginWithModalOptions,\n  CreateAccountWithModalOptions,\n  ConnectResult,\n  AuthenticateOptions,\n  AuthenticateResult,\n  IntentCall,\n  SendIntentOptions,\n  SendIntentResult,\n  PrepareIntentResponse,\n  SponsorshipMode,\n  ExecuteIntentResponse,\n  OneAuthErrorDetails,\n  WebAuthnSignature,\n  ThemeConfig,\n  SignMessageOptions,\n  SignMessageResult,\n  SignTypedDataOptions,\n  SignTypedDataResult,\n  IntentHistoryOptions,\n  IntentHistoryResult,\n  GetAssetsOptions,\n  SendBatchIntentOptions,\n  SendBatchIntentResult,\n  PrepareBatchIntentResponse,\n  PrepareBatchIntentDraftResponse,\n  BatchIntentItemResult,\n  CheckConsentOptions,\n  CheckConsentResult,\n  RequestConsentOptions,\n  RequestConsentResult,\n  GrantPermissionsOptions,\n  GrantPermissionsResult,\n  ListSessionGrantsOptions,\n  ListSessionGrantsResult,\n  SponsorshipConfig,\n  SponsorshipCallbackConfig,\n  OneAuthTelemetryAttributes,\n  OneAuthTelemetryEvent,\n  OneAuthTelemetryEventName,\n  OneAuthTelemetryFlow,\n  OneAuthTelemetryTraceContext,\n} from \"./types\";\n\n/** Require the server-owned slot before forwarding credentials to intent execution. */\nfunction requireSigningPasskeyCredentials(\n  value: PasskeyCredentials | undefined,\n): SigningPasskeyCredentials | undefined {\n  if (!value) return undefined;\n  return typeof value.keyId === \"number\" ? (value as SigningPasskeyCredentials) : undefined;\n}\nimport {\n  BRAND_PURPLE,\n  DARK_TOKENS,\n  LIGHT_TOKENS,\n  LOADING_BODY_GAP,\n  LOADING_FONT_FAMILY,\n  LOADING_ICON_PADDING,\n  LOADING_LINE_HEIGHT,\n  LOADING_MODAL_PADDING,\n  LOADING_MODAL_RADIUS,\n  LOADING_MODAL_WIDTH,\n  LOADING_SUBTITLE,\n  LOADING_SUBTITLE_FONT_SIZE,\n  LOADING_SUBTITLE_FONT_WEIGHT,\n  LOADING_TITLE,\n  LOADING_TITLE_BLOCK_GAP,\n  LOADING_TITLE_FONT_SIZE,\n  LOADING_TITLE_FONT_WEIGHT,\n  SPINNER_ARC,\n  SPINNER_CIRCUMFERENCE,\n  SPINNER_RADIUS,\n  SPINNER_SIZE,\n  SPINNER_SPIN_DURATION_MS,\n  SPINNER_STROKE,\n} from \"@1auth/loading-tokens\";\n\n// Modal width is derived from LOADING_MODAL_WIDTH (single source of truth,\n// owned by `@1auth/loading-tokens`). Changing the width here in isolation\n// would let popup/iframe drift from the Figma spec; keep them tied.\nconst POPUP_WIDTH = LOADING_MODAL_WIDTH;\nconst POPUP_HEIGHT = 600;\nconst DEFAULT_EMBED_WIDTH = `${LOADING_MODAL_WIDTH}px`;\nconst DEFAULT_EMBED_HEIGHT = \"500px\";\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.app\";\n\n/**\n * Return the embedding page origin when the SDK is running in a browser.\n * The dialog uses this only for first-paint attribution and postMessage\n * targeting; authenticated server-side origin decisions still use browser\n * provided referrer/event.origin values inside the passkey app.\n */\nfunction currentWindowOrigin(): string | null {\n  if (typeof window === \"undefined\") return null;\n  const origin = window.location?.origin;\n  return typeof origin === \"string\" && origin.length > 0 ? origin : null;\n}\n\n/**\n * Add the host origin to a dialog URL so the iframe can render the origin pill\n * on its first client render instead of waiting for PASSKEY_INIT or\n * document.referrer effects. Kept as a URL hint, not an authorization signal.\n */\nfunction appendParentOriginParam(params: URLSearchParams): void {\n  const origin = currentWindowOrigin();\n  if (origin) params.set(\"parentOrigin\", origin);\n}\n\n// Max characters for IntentCall.label / .sublabel before the SDK truncates\n// with an ellipsis. The sign dialog renders these in a ~200–260px column at\n// text-[16px] bold (see SignDialogBody.tsx TokenMovementCard). At that font\n// you fit ~17 typical chars; 20 is a forgiving cap that still avoids wrapping\n// for most strings while letting CSS `truncate` handle the worst-case fonts\n// as a safety net.\nconst MAX_LABEL_LEN = 20;\n\n// Default scrim appearance — preserved verbatim from the pre-`backdrop`-option\n// behavior so apps that never set `theme.backdrop` see no change. The dialog\n// (apps/passkey) uses the identical defaults for its in-iframe scrim.\nconst DEFAULT_BACKDROP_COLOR = \"#000000\";\nconst DEFAULT_BACKDROP_OPACITY = 0.4;\nconst DEFAULT_BACKDROP_BLUR = 8;\n// Only `#rrggbb` is allowed — same hard restriction the dialog applies to the\n// accent color (apps/passkey/src/lib/dialog-messages.ts ACCENT_RE). The value\n// is interpolated into a stylesheet string below, so anything looser (named\n// colors, `rgb()`, escapes) could become a CSS-injection vector.\nconst HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;\n\n/**\n * Resolve the scrim tint (as an `rgba(...)` string) and blur radius (px) for\n * the SDK loading overlay from the dialog URL's `backdrop*` query params.\n *\n * The overlay is painted by the SDK on the host page before the iframe renders\n * (see {@link OneAuthClient.createModalDialog}); it must match the in-iframe\n * scrim the passkey app paints afterward so the host→iframe handoff is\n * seamless. Both sides read the same params and clamp identically.\n *\n * Every field falls back to its default independently and invalid/out-of-range\n * values are coerced back to the default, so a malformed param can never\n * produce a broken `background`/`backdrop-filter` declaration.\n */\nexport function resolveBackdropStyle(params: URLSearchParams): {\n  background: string;\n  blur: number;\n} {\n  const rawColor = params.get(\"backdropColor\");\n  const hex = (rawColor && HEX_COLOR_RE.test(rawColor) ? rawColor : DEFAULT_BACKDROP_COLOR).slice(1);\n  const r = parseInt(hex.slice(0, 2), 16);\n  const g = parseInt(hex.slice(2, 4), 16);\n  const b = parseInt(hex.slice(4, 6), 16);\n\n  // Parse a numeric param back to its default when the field is absent.\n  // `URLSearchParams.get` returns null for omitted params and \"\" for empty\n  // ones, and `Number(null) === Number(\"\") === 0` — which passes\n  // `Number.isFinite`. Guarding on the raw value first keeps an omitted\n  // `backdropOpacity`/`backdropBlur` on its historical default (0.4 / 8px)\n  // instead of collapsing to a fully-transparent, unblurred overlay. An\n  // explicit \"0\" is still a real, finite value and is honored.\n  const clampNumber = (key: string, min: number, max: number, fallback: number): number => {\n    const raw = params.get(key);\n    if (!raw) return fallback;\n    const n = Number(raw);\n    return Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : fallback;\n  };\n\n  const opacity = clampNumber(\"backdropOpacity\", 0, 1, DEFAULT_BACKDROP_OPACITY);\n  const blur = clampNumber(\"backdropBlur\", 0, 40, DEFAULT_BACKDROP_BLUR);\n\n  return { background: `rgba(${r}, ${g}, ${b}, ${opacity})`, blur };\n}\n\n/**\n * Generate a unique nonce for a single modal session. Used by\n * `waitForModalAuthResponse` (and any other per-modal message listener)\n * to reject stale CLOSE / RESULT messages that a previous, already\n * cleaned-up iframe queued before its teardown — without the nonce the\n * new modal's listener would process the stale event and silently cancel\n * the fresh auth attempt. `crypto.randomUUID` is available in every\n * browser this SDK targets; fall back to a Math.random pair so non-\n * conformant environments don't throw at construction time.\n */\nfunction generateModalNonce(): string {\n  if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n    return crypto.randomUUID();\n  }\n  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n\ntype TelemetryOperation = {\n  operationId: string;\n  flow: OneAuthTelemetryFlow;\n  startedAt: number;\n  trace?: OneAuthTelemetryTraceContext;\n  attributes?: OneAuthTelemetryAttributes;\n};\n\ntype TelemetryEventPatch = Partial<\n  Omit<OneAuthTelemetryEvent, \"name\" | \"operationId\" | \"flow\" | \"timestamp\">\n>;\n\n/**\n * Generate a stable correlation id for one SDK operation. It is intentionally\n * opaque and random so it can be logged safely without leaking user data.\n */\nfunction generateTelemetryOperationId(): string {\n  return `1auth-${generateModalNonce()}`;\n}\n\n/**\n * Keep telemetry attributes JSON/log friendly. Undefined values are dropped so\n * callbacks and headers do not need to normalize SDK-produced objects.\n */\nfunction cleanTelemetryAttributes(\n  attributes: OneAuthTelemetryAttributes | undefined,\n): OneAuthTelemetryAttributes | undefined {\n  if (!attributes) return undefined;\n  const clean: OneAuthTelemetryAttributes = {};\n  for (const [key, value] of Object.entries(attributes)) {\n    if (value !== undefined) clean[key] = value;\n  }\n  return Object.keys(clean).length > 0 ? clean : undefined;\n}\n\n/**\n * Extract a consistent code/message pair from SDK result errors or thrown\n * exceptions without assuming a specific error class.\n */\nfunction describeTelemetryError(error: unknown): {\n  errorCode?: string;\n  errorMessage?: string;\n} {\n  if (!error) return {};\n  if (error instanceof Error) {\n    return { errorCode: error.name, errorMessage: error.message };\n  }\n  if (typeof error === \"object\") {\n    const err = error as { code?: unknown; message?: unknown };\n    return {\n      errorCode: typeof err.code === \"string\" ? err.code : undefined,\n      errorMessage: typeof err.message === \"string\" ? err.message : String(error),\n    };\n  }\n  return { errorMessage: String(error) };\n}\n\n/**\n * Truncate an IntentCall's `label` / `sublabel` to fit the sign dialog's\n * single-line label column. Returns the same call shape with capped strings;\n * leaves all other fields (to, data, value, icon) untouched. Returns the\n * input unchanged when `calls` is undefined or empty.\n *\n * The dialog also applies `truncate` CSS as a defense-in-depth measure — this\n * SDK cap exists so the request on the wire matches what the user sees, and\n * so apps can tell their label was too long (the truncated form ships).\n */\nfunction capCallLabels(calls: IntentCall[] | undefined): IntentCall[] | undefined {\n  if (!calls) return calls;\n  return calls.map((c) => {\n    const cappedLabel =\n      c.label && c.label.length > MAX_LABEL_LEN\n        ? c.label.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n        : c.label;\n    const cappedSublabel =\n      c.sublabel && c.sublabel.length > MAX_LABEL_LEN\n        ? c.sublabel.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n        : c.sublabel;\n    if (cappedLabel === c.label && cappedSublabel === c.sublabel) return c;\n    return { ...c, label: cappedLabel, sublabel: cappedSublabel };\n  });\n}\n\n/**\n * Reads the `signerType` from the stored session in localStorage. Absent or\n * malformed storage falls back to `\"passkey\"` so existing installs remain\n * backwards compatible.\n */\nfunction getStoredSignerType(): \"passkey\" | \"eoa\" {\n  if (typeof window === \"undefined\") return \"passkey\";\n  try {\n    const raw = window.localStorage.getItem(\"1auth-user\");\n    if (!raw) return \"passkey\";\n    const parsed = JSON.parse(raw) as { signerType?: \"passkey\" | \"eoa\" };\n    return parsed?.signerType === \"eoa\" ? \"eoa\" : \"passkey\";\n  } catch {\n    return \"passkey\";\n  }\n}\n\ntype NormalizedPasskeyProviderConfig = PasskeyProviderConfig & {\n  providerUrl: string;\n  dialogUrl: string;\n};\n\ntype BlindSigningOption = { blind_signing?: boolean };\n\n/**\n * Global default for blind signing, used when neither the per-call option nor\n * the client config expresses a preference.\n *\n * `true` means apps get blind signing out of the box and must *opt in* to\n * 1auth's visible review UI (clear signing) by passing `blind_signing: false`\n * on the client or per call. This is the single switch for the rollout: when\n * we're ready to change the platform-wide default, flip this one constant —\n * every app that hasn't set its own preference follows it.\n */\nconst DEFAULT_BLIND_SIGNING = true;\n\ntype SponsorshipTokens = { accessToken: string; extensionTokens: string[] };\n\ntype AccessTokenFetchResult =\n  | { ok: true; accessToken: string }\n  | { ok: false; code?: \"MISSING_APP_CREDENTIALS\"; message: string };\n\ntype ExtensionTokensFetchResult =\n  | { ok: true; extensionTokens: string[] }\n  | { ok: false; message: string };\n\nconst MISSING_APP_CREDENTIALS_MESSAGE =\n  \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — pass `sponsorship: { accessToken, getExtensionToken }` (or URL form) to the constructor.\";\n\n/**\n * Normalize any `SponsorshipConfig` shape to the internal callback form.\n *\n * The URL form is a thin convenience — it gets wrapped into callbacks that\n * hit the app's own endpoints. Using same-origin URLs is recommended so the\n * browser forwards session cookies and the app can authenticate the user\n * server-side before minting a sponsorship grant.\n *\n * The access-token endpoint is GET and returns `{ token }`. The extension-\n * token endpoint is POST `{ intentOp }` and returns `{ token }`.\n */\nfunction normalizeSponsorship(\n  config: SponsorshipConfig | undefined,\n): SponsorshipCallbackConfig | null {\n  if (!config) return null;\n  if (\"accessToken\" in config && \"getExtensionToken\" in config) {\n    return config;\n  }\n  const { accessTokenUrl, extensionTokenUrl } = config;\n  return {\n    accessToken: async () => {\n      const response = await fetch(accessTokenUrl, { credentials: \"include\" });\n      if (!response.ok) {\n        throw await tokenFetchError(\"access token\", response);\n      }\n      const data = (await response.json()) as { token?: string };\n      if (!data.token) {\n        throw new Error(\"Access token response missing `token` field\");\n      }\n      return data.token;\n    },\n    getExtensionToken: async (intentOp: string) => {\n      const response = await fetch(extensionTokenUrl, {\n        method: \"POST\",\n        credentials: \"include\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({ intentOp }),\n      });\n      if (!response.ok) {\n        throw await tokenFetchError(\"extension token\", response);\n      }\n      const data = (await response.json()) as { token?: string };\n      if (!data.token) {\n        throw new Error(\"Extension token response missing `token` field\");\n      }\n      return data.token;\n    },\n  };\n}\n\n/**\n * JSON.stringify replacer for grant-permission payloads. Session policy\n * helpers naturally use bigint values, but postMessage payloads must be\n * structured-clone friendly across browsers and JSON-safe for server calls.\n */\nfunction grantPermissionReplacer(_key: string, value: unknown): unknown {\n  return typeof value === \"bigint\" ? value.toString() : value;\n}\n\nfunction cloneGrantPayload<T>(value: T): T {\n  return JSON.parse(JSON.stringify(value, grantPermissionReplacer)) as T;\n}\n\nfunction normalizeGrantTargetChains(options: GrantPermissionsOptions): number[] {\n  const chainCandidates = options.targetChains ?? (\n    options.targetChain !== undefined ? [options.targetChain] : []\n  );\n  return Array.from(new Set(chainCandidates));\n}\n\nfunction normalizeGrantSourceChains(options: GrantPermissionsOptions): number[] {\n  return Array.from(new Set(options.sourceChains ?? []));\n}\n\nconst sessionForgetHandlers = new WeakMap<OneAuthClient, Set<() => void>>();\n\n/** Register provider-owned cleanup for a client-level forget-session message. */\nexport function registerSessionForgetHandler(\n  client: OneAuthClient,\n  handler: () => void,\n): () => void {\n  const handlers = sessionForgetHandlers.get(client) ?? new Set<() => void>();\n  handlers.add(handler);\n  sessionForgetHandlers.set(client, handlers);\n  return () => {\n    handlers.delete(handler);\n    if (handlers.size === 0) sessionForgetHandlers.delete(client);\n  };\n}\n\nexport class OneAuthClient {\n  private config: NormalizedPasskeyProviderConfig;\n  private theme: ThemeConfig;\n  private sponsorship: SponsorshipCallbackConfig | null;\n  // Persistent state for EOA forwarding via `/dialog/sign-eoa`. The iframe\n  // is created lazily on the first `requestWithWallet` call and reused for\n  // every subsequent call so its WalletConnect SignClient survives between\n  // transactions — otherwise each call would spin up a fresh SignClient\n  // that restores stale relay state from localStorage, producing\n  // \"Restore will override\" warnings and \"emitting session_request:N\n  // without any listeners\" errors on the second and later txs.\n  private eoaDialogState: {\n    dialog: HTMLDialogElement;\n    iframe: HTMLIFrameElement;\n  } | null = null;\n  // Hidden iframe that warms the dialog ahead of the first real open (see\n  // `prewarm()`). The passkey app runs on a long-lived server (not serverless),\n  // so there is no backend cold-start to hide — what stays expensive is the\n  // *browser-side* cost of a freshly created cross-origin iframe: downloading\n  // the dialog HTML + JS bundle, parsing it, hydrating React, and loading the\n  // font. Loading that bundle once into a parked hidden iframe lets the real\n  // open hit the HTTP cache (Next.js chunks/fonts are immutable-cached) over an\n  // already-warm connection, so the SDK preload overlay is shown only briefly.\n  private prewarmState: {\n    iframe: HTMLIFrameElement;\n    ready: Promise<boolean>;\n  } | null = null;\n  // Serialises concurrent `requestWithWallet` calls — they would otherwise\n  // both try to drive the same iframe and cross-resolve each other.\n  private eoaSerialQueue: Promise<unknown> = Promise.resolve();\n\n  /** Clear the default cache plus every provider bound to this client. */\n  private forgetApplicationSessions(): void {\n    if (typeof window !== \"undefined\") localStorage.removeItem(\"1auth-user\");\n    for (const handler of sessionForgetHandlers.get(this) ?? []) handler();\n    try {\n      this.config.onDisconnect?.();\n    } catch {\n      // Host callbacks are isolated from session cleanup so a rendering bug in\n      // the integrator cannot leave the SDK/provider caches authenticated.\n    }\n  }\n\n  /** Forget embedder-side sessions from any trusted dialog transport. */\n  private installDisconnectListener(): void {\n    if (\n      typeof window === \"undefined\" ||\n      typeof document === \"undefined\" ||\n      typeof window.addEventListener !== \"function\"\n    ) return;\n    const dialogOrigin = this.getDialogOrigin();\n    window.addEventListener(\"message\", (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.data?.type === \"PASSKEY_DISCONNECT\") {\n        this.forgetApplicationSessions();\n      }\n    });\n  }\n\n  /**\n   * Create a new OneAuthClient.\n   *\n   * Normalizes the config (filling in default URLs), then immediately injects\n   * `<link rel=\"preconnect\">` tags for the passkey domain so that DNS lookup\n   * and TLS handshake start before the first dialog is opened, shaving\n   * noticeable latency from the first user interaction.\n   *\n   * @param config - Client configuration including optional providerUrl, dialogUrl,\n   *   clientId, theme, and redirect settings.\n   */\n  constructor(config: PasskeyProviderConfig) {\n    const providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;\n    const dialogUrl = config.dialogUrl || providerUrl;\n    this.config = { ...config, providerUrl, dialogUrl };\n    this.theme = this.config.theme || {};\n    this.sponsorship = normalizeSponsorship(config.sponsorship);\n    this.installDisconnectListener();\n\n    // Pre-warm DNS + TLS connections to passkey domain\n    if (typeof document !== \"undefined\") {\n      this.injectPreconnect(providerUrl);\n      if (dialogUrl !== providerUrl) {\n        this.injectPreconnect(dialogUrl);\n      }\n      // Opt-in deeper warming: load the dialog bundle into a hidden iframe once\n      // the main thread is idle so it never competes with the host app's own\n      // first paint. Errors are swallowed — prewarm is best-effort.\n      if (this.config.prewarm) {\n        const warm = () => void this.prewarm();\n        const ric = (window as Window & {\n          requestIdleCallback?: (cb: () => void, opts?: { timeout: number }) => void;\n        }).requestIdleCallback;\n        if (typeof ric === \"function\") {\n          ric(warm, { timeout: 2000 });\n        } else {\n          setTimeout(warm, 200);\n        }\n      }\n    }\n\n    const initOperation = this.createTelemetryOperation(\"client\", {\n      hasClientId: !!this.config.clientId,\n      hasDialogUrlOverride: dialogUrl !== providerUrl,\n    });\n    this.emitTelemetry(\"client.init\", initOperation, { outcome: \"started\" });\n  }\n\n  /**\n   * Update the sponsorship configuration at runtime. Pass `undefined` to\n   * disable sponsorship.\n   */\n  setSponsorship(sponsorship: SponsorshipConfig | undefined): void {\n    this.sponsorship = normalizeSponsorship(sponsorship);\n  }\n\n  /**\n   * Whether the caller opted into SDK telemetry propagation or callbacks.\n   */\n  private shouldUseTelemetry(): boolean {\n    return !!this.config.telemetry && this.config.telemetry.enabled !== false;\n  }\n\n  /**\n   * Resolve the host app's current trace context. Callback failures are\n   * ignored because observability can never be allowed to break signing.\n   */\n  private getTelemetryTraceContext(): OneAuthTelemetryTraceContext | undefined {\n    const traceContext = this.config.telemetry?.traceContext;\n    if (!traceContext || !this.shouldUseTelemetry()) return undefined;\n    try {\n      return typeof traceContext === \"function\" ? traceContext() : traceContext;\n    } catch {\n      return undefined;\n    }\n  }\n\n  /**\n   * Resolve host-provided SDK event attributes and remove undefined fields.\n   */\n  private getTelemetryAttributes(): OneAuthTelemetryAttributes | undefined {\n    const attributes = this.config.telemetry?.attributes;\n    if (!attributes || !this.shouldUseTelemetry()) return undefined;\n    try {\n      const resolved = typeof attributes === \"function\" ? attributes() : attributes;\n      return cleanTelemetryAttributes(resolved);\n    } catch {\n      return undefined;\n    }\n  }\n\n  /**\n   * Create per-operation telemetry context shared by callbacks, HTTP headers,\n   * dialog URL params, and PASSKEY_INIT messages.\n   */\n  private createTelemetryOperation(\n    flow: OneAuthTelemetryFlow,\n    attributes?: OneAuthTelemetryAttributes,\n  ): TelemetryOperation {\n    return {\n      operationId: generateTelemetryOperationId(),\n      flow,\n      startedAt: Date.now(),\n      trace: this.getTelemetryTraceContext(),\n      attributes: cleanTelemetryAttributes({\n        ...this.getTelemetryAttributes(),\n        ...attributes,\n      }),\n    };\n  }\n\n  /**\n   * Emit a telemetry event to the host app. The callback is intentionally\n   * fire-and-forget and exception-safe so app telemetry cannot affect users.\n   */\n  private emitTelemetry(\n    name: OneAuthTelemetryEventName,\n    operation: TelemetryOperation,\n    patch: TelemetryEventPatch = {},\n  ): void {\n    const onEvent = this.config.telemetry?.onEvent;\n    if (!onEvent || !this.shouldUseTelemetry()) return;\n\n    const attributes = cleanTelemetryAttributes({\n      ...operation.attributes,\n      ...patch.attributes,\n    });\n    const event: OneAuthTelemetryEvent = {\n      name,\n      operationId: operation.operationId,\n      flow: operation.flow,\n      timestamp: new Date().toISOString(),\n      durationMs: patch.durationMs ?? Date.now() - operation.startedAt,\n      clientId: this.config.clientId,\n      providerUrl: this.config.providerUrl,\n      dialogUrl: this.getDialogUrl(),\n      trace: operation.trace,\n      ...patch,\n      attributes,\n    };\n\n    try {\n      onEvent(event);\n    } catch {\n      // Telemetry callbacks are intentionally isolated from SDK behavior.\n    }\n  }\n\n  /**\n   * Attach SDK correlation and optional W3C trace context to dialog URLs.\n   */\n  private appendTelemetryParams(\n    params: URLSearchParams,\n    operation: TelemetryOperation,\n  ): void {\n    if (!this.shouldUseTelemetry()) return;\n    params.set(\"sdkOperationId\", operation.operationId);\n    params.set(\"sdkTelemetryFlow\", operation.flow);\n    if (operation.trace?.traceparent) {\n      params.set(\"traceparent\", operation.trace.traceparent);\n    }\n    if (operation.trace?.tracestate) {\n      params.set(\"tracestate\", operation.trace.tracestate);\n    }\n    if (operation.trace?.traceId) {\n      params.set(\"sdkTraceId\", operation.trace.traceId);\n    }\n    if (operation.trace?.spanId) {\n      params.set(\"sdkSpanId\", operation.trace.spanId);\n    }\n  }\n\n  /**\n   * Add SDK correlation headers to passkey API calls. These headers are also\n   * valid W3C trace propagation inputs when the host app supplies traceparent.\n   */\n  private telemetryHeaders(operation?: TelemetryOperation): Record<string, string> {\n    if (!operation || !this.shouldUseTelemetry()) return {};\n    return {\n      \"x-1auth-sdk-operation-id\": operation.operationId,\n      \"x-1auth-sdk-flow\": operation.flow,\n      ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n      ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n    };\n  }\n\n  /**\n   * Embed telemetry context in PASSKEY_INIT payloads for dialog-side API calls.\n   */\n  private telemetryPayload(\n    operation: TelemetryOperation,\n  ): Record<string, string> | undefined {\n    if (!this.shouldUseTelemetry()) return undefined;\n    return {\n      operationId: operation.operationId,\n      flow: operation.flow,\n      ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n      ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n      ...(operation.trace?.traceId ? { traceId: operation.trace.traceId } : {}),\n      ...(operation.trace?.spanId ? { spanId: operation.trace.spanId } : {}),\n    };\n  }\n\n  /** Resolve the public funding policy while preserving the legacy user-paid alias. */\n  private resolveSponsorshipMode(options: {\n    sponsorshipMode?: SponsorshipMode;\n    sponsor?: boolean;\n  }): SponsorshipMode {\n    return options.sponsorshipMode ?? (options.sponsor === false ? \"disabled\" : \"required\");\n  }\n\n  /**\n   * Determine whether this signing call should request invisible dialog mode.\n   * Resolution order: per-call option wins over the constructor config, which\n   * wins over the platform-wide {@link DEFAULT_BLIND_SIGNING}. This lets an app\n   * flip the global default for itself while still overriding individual\n   * high-risk calls.\n   */\n  private shouldRequestBlindSigning(options?: BlindSigningOption): boolean {\n    return options?.blind_signing ?? this.config.blind_signing ?? DEFAULT_BLIND_SIGNING;\n  }\n\n  /**\n   * Fetch the app's access token (JWT). Called up front, before\n   * `/api/intent/prepare`, so the passkey server can authenticate the\n   * orchestrator quote call with the app's JWT instead of a service-level\n   * API key.\n   *\n   * Does not depend on `intentOp` — can run in parallel with anything that\n   * also doesn't depend on the quote.\n   */\n  private async fetchAccessToken(): Promise<AccessTokenFetchResult> {\n    if (!this.sponsorship) {\n      return {\n        ok: false,\n        code: \"MISSING_APP_CREDENTIALS\",\n        message: MISSING_APP_CREDENTIALS_MESSAGE,\n      };\n    }\n    try {\n      const accessToken = await this.sponsorship.accessToken();\n      return { ok: true, accessToken };\n    } catch (err) {\n      return {\n        ok: false,\n        message: err instanceof Error ? err.message : String(err),\n      };\n    }\n  }\n\n  /**\n   * Fetch one extension token per canonical sponsorship intent input, aligned\n   * with `sponsorFlags`. Sponsored prepare uses the same token for the final\n   * quote and later submission, so route construction and execution share one\n   * digest-bound authorization.\n   */\n  private async fetchExtensionTokens(\n    sponsorshipIntentInputs: string[],\n    sponsorFlags: boolean[],\n  ): Promise<ExtensionTokensFetchResult> {\n    if (!this.sponsorship) {\n      return { ok: false, message: MISSING_APP_CREDENTIALS_MESSAGE };\n    }\n    const anySponsored = sponsorFlags.some(Boolean);\n    if (!anySponsored) return { ok: true, extensionTokens: [] };\n    try {\n      const sponsorship = this.sponsorship;\n      const tokens = await Promise.all(\n        sponsorshipIntentInputs.map((input, i) =>\n          sponsorFlags[i] ? sponsorship.getExtensionToken(input) : Promise.resolve(\"\"),\n        ),\n      );\n      return { ok: true, extensionTokens: tokens };\n    } catch (err) {\n      return {\n        ok: false,\n        message: err instanceof Error ? err.message : String(err),\n      };\n    }\n  }\n\n  /**\n   * Update the theme configuration at runtime\n   */\n  setTheme(theme: ThemeConfig): void {\n    this.theme = theme;\n  }\n\n  /**\n   * Serialize the active theme into URL query parameters for the dialog.\n   *\n   * Merges the instance-level theme (set via constructor or `setTheme`) with any\n   * per-call override, so callers can temporarily change the appearance for a\n   * single dialog invocation without mutating shared state.\n   *\n   * @param overrideTheme - One-shot theme values that take precedence over the\n   *   instance theme for this call only.\n   * @returns A URL-encoded query string (e.g. `\"theme=dark&accent=%230090ff\"`),\n   *   or an empty string if no theme properties are set.\n   */\n  private getThemeParams(overrideTheme?: ThemeConfig): string {\n    const theme = { ...this.theme, ...overrideTheme };\n    const params = new URLSearchParams();\n\n    if (theme.mode) {\n      params.set('theme', theme.mode);\n    }\n    // `primaryColor` is the documented name; `accent` is the legacy alias.\n    // Resolve each layer independently before merging so that a per-call\n    // override (either field) wins over the instance value (either field) —\n    // a plain spread merge would let an instance `primaryColor` shadow a\n    // per-call `accent`, breaking the documented \"overrides take precedence\"\n    // contract while `accent` remains a back-compat alias.\n    const instancePrimary = this.theme.primaryColor ?? this.theme.accent;\n    const overridePrimary = overrideTheme?.primaryColor ?? overrideTheme?.accent;\n    const primary = overridePrimary ?? instancePrimary;\n    if (primary) {\n      params.set('accent', primary);\n    }\n\n    // Backdrop (scrim) tint/blur. Each field is emitted only when present so\n    // the dialog keeps its per-field defaults (black / 0.4 / 8px) for the\n    // common case where the app sets none. The dialog re-validates and clamps\n    // each value, so we pass them through verbatim here.\n    const backdrop = theme.backdrop;\n    if (backdrop) {\n      if (backdrop.color) {\n        params.set('backdropColor', backdrop.color);\n      }\n      if (backdrop.opacity !== undefined) {\n        params.set('backdropOpacity', String(backdrop.opacity));\n      }\n      if (backdrop.blur !== undefined) {\n        params.set('backdropBlur', String(backdrop.blur));\n      }\n    }\n\n    return params.toString();\n  }\n\n  /**\n   * Resolve the URL of the dialog app (the Vite/Next.js frontend that renders\n   * the WebAuthn UI inside the iframe).\n   *\n   * `dialogUrl` is a separate config option to support split deployments where\n   * the API server and the dialog frontend run at different origins. Falls back\n   * to `providerUrl` when not explicitly configured — the common case.\n   *\n   * @returns The base URL used when constructing all dialog endpoint paths.\n   */\n  private getDialogUrl(): string {\n    return this.config.dialogUrl || this.config.providerUrl;\n  }\n\n  /**\n   * Extract the trusted origin used to validate incoming postMessage events.\n   *\n   * All `window.addEventListener(\"message\", ...)` handlers in this class check\n   * `event.origin` against this value to prevent cross-origin spoofing. Wraps\n   * `getDialogUrl()` in a `new URL()` parse so that paths and query strings are\n   * stripped — only the scheme + host + port are compared.\n   *\n   * Falls back to the raw dialog URL string if URL parsing fails (e.g. during\n   * unit tests with non-standard URL formats).\n   *\n   * @returns The scheme + host + optional port of the dialog app (e.g. `\"https://passkey.1auth.app\"`).\n   */\n  private getDialogOrigin(): string {\n    const dialogUrl = this.getDialogUrl();\n    try {\n      return new URL(dialogUrl).origin;\n    } catch {\n      return dialogUrl;\n    }\n  }\n\n  /**\n   * Get the base provider URL\n   */\n  getProviderUrl(): string {\n    return this.config.providerUrl;\n  }\n\n  /**\n   * Get the configured client ID\n   */\n  getClientId(): string | undefined {\n    return this.config.clientId;\n  }\n\n  /**\n   * Whether this client operates on testnet chains only.\n   */\n  getTestnets(): boolean {\n    return this.config.testnets ?? false;\n  }\n\n  /**\n   * Get a unified token portfolio for a 1auth account across mainnets and\n   * testnets.\n   *\n   * @example\n   * ```typescript\n   * const assets = await client.getAssets({\n   *   accountAddress: \"0x1111111111111111111111111111111111111111\",\n   * });\n   * console.log(assets.mainnets.balances, assets.testnets.balances);\n   * ```\n   */\n  async getAssets(options: GetAssetsOptions): Promise<AssetsResponse> {\n    if (!options.accountAddress) {\n      throw new Error(\"getAssets requires accountAddress\");\n    }\n\n    const telemetry = this.createTelemetryOperation(\"assets\", {\n      hasAccountAddress: !!options.accountAddress,\n    });\n\n    try {\n      const accessTokenResult = await this.fetchAccessToken();\n      if (!accessTokenResult.ok) {\n        throw new Error(accessTokenResult.message);\n      }\n\n      const result = await fetchAssetsResponse({\n        providerUrl: this.config.providerUrl,\n        identifier: options.accountAddress,\n        clientId: this.config.clientId,\n        accessToken: accessTokenResult.accessToken,\n        headers: this.telemetryHeaders(telemetry),\n      });\n      this.emitTelemetry(\"assets.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: {\n          balanceCount: result.balances.length,\n          mainnetBalanceCount: result.mainnets.balances.length,\n          testnetBalanceCount: result.testnets.balances.length,\n        },\n      });\n      return result;\n    } catch (error) {\n      this.emitTelemetry(\"assets.failed\", telemetry, {\n        outcome: \"failure\",\n        ...describeTelemetryError(error),\n      });\n      throw error;\n    }\n  }\n\n  /**\n   * Poll the intent status endpoint until a transaction hash appears or the\n   * intent reaches a terminal failure state.\n   *\n   * This is used after `sendIntent` resolves (with `waitForHash: true`) to\n   * continue waiting for the on-chain hash even after the dialog has been\n   * dismissed. It is intentionally separate from the in-dialog polling loop so\n   * callers that don't need the hash can skip it entirely.\n   *\n   * Errors during individual poll attempts are swallowed so that transient\n   * network issues don't abort the wait prematurely.\n   *\n   * @param intentId - The Rhinestone intent ID returned by the execute endpoint.\n   * @param options.timeoutMs - Maximum wait time in milliseconds (default 120 000).\n   * @param options.intervalMs - Time between polls in milliseconds (default 2 000).\n   * @returns The transaction hash string, or `undefined` if the deadline was\n   *   reached or the intent failed/expired before a hash was produced.\n   */\n  private async waitForTransactionHash(\n    intentId: string,\n    options: { timeoutMs?: number; intervalMs?: number } = {},\n    telemetry?: TelemetryOperation,\n  ): Promise<string | undefined> {\n    const timeoutMs = options.timeoutMs ?? 120_000;\n    const intervalMs = options.intervalMs ?? 2_000;\n    const deadline = Date.now() + timeoutMs;\n\n    while (Date.now() < deadline) {\n      try {\n        const response = await fetch(\n          `${this.config.providerUrl}/api/intent/status/${intentId}`,\n          {\n            headers: {\n              ...this.telemetryHeaders(telemetry),\n              ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n            },\n          }\n        );\n        if (response.ok) {\n          const data = await response.json();\n          if (data.transactionHash) {\n            return data.transactionHash as string;\n          }\n          if (data.status === \"failed\" || data.status === \"expired\") {\n            return undefined;\n          }\n        }\n      } catch {\n        // Keep polling until timeout.\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, intervalMs));\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Open the authentication modal (sign in + sign up).\n   *\n   * Handles both new user registration and returning user login in a single\n   * call — the modal shows the appropriate flow based on whether the user\n   * has a passkey registered.\n   *\n   * @param options.theme - Override the theme for this modal invocation\n   * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n   * @param options.flow - Force the login or account-creation route instead\n   *   of the default auto-detect entry route\n   * @returns {@link AuthResult} with user details and typed address\n   *\n   * @example\n   * ```typescript\n   * const result = await client.authWithModal();\n   *\n   * if (result.success) {\n   *   console.log('Signed in as:', result.user?.address);\n   *   console.log('Address:', result.user?.address); // typed `0x${string}`\n   * } else if (result.error?.code === 'USER_CANCELLED') {\n   *   // User closed the modal\n   * }\n   * ```\n   */\n  async authWithModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n    return this.openAuthModal(options);\n  }\n\n  /**\n   * Open the sign-in modal directly.\n   *\n   * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n   * returning-user flow. Use it when the embedding app already knows the user\n   * is creating a login session, for example after an app-level \"Log in\"\n   * button. The result intentionally matches {@link authWithModal}.\n   *\n   * @param options.theme - Override the theme for this modal invocation\n   * @returns {@link AuthResult} with user details and typed address\n   */\n  async loginWithModal(options?: LoginWithModalOptions): Promise<AuthResult> {\n    return this.openAuthModal({ ...options, flow: \"login\" });\n  }\n\n  /**\n   * Open the account-creation modal directly.\n   *\n   * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n   * sign-up flow. Account creation still happens server-side in the passkey\n   * service; the SDK only opens the dialog and receives the postMessage result.\n   *\n   * @param options.theme - Override the theme for this modal invocation\n   * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n   * @returns {@link AuthResult} with the newly authenticated account details\n   */\n  async createAccountWithModal(options?: CreateAccountWithModalOptions): Promise<AuthResult> {\n    return this.openAuthModal({ ...options, flow: \"create-account\" });\n  }\n\n  /**\n   * Open one of the passkey authentication modal routes and wait for the\n   * login-result message.\n   *\n   * Keeping URL construction in one helper prevents the explicit login/signup\n   * methods from drifting away from the legacy `authWithModal` behavior.\n   */\n  private async openAuthModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n    const telemetry = this.createTelemetryOperation(\"auth\", {\n      flow: options?.flow ?? \"auto\",\n    });\n    const dialogUrl = this.getDialogUrl();\n    const requestId = this.createDialogRequestId();\n    const params = new URLSearchParams({\n      mode: 'iframe',\n      requestId,\n    });\n    if (this.config.clientId) {\n      params.set('clientId', this.config.clientId);\n    }\n    if (options?.oauthEnabled === false) {\n      params.set('oauth', '0');\n    }\n    if (options?.eoaConnect) {\n      // Signals the dialog's wallet path to terminate as a pure EOA signer\n      // session (plain tx, no intents) rather than wallet-assisted passkey\n      // signup. Read by useSignupFlow and the wallet sub-routes.\n      params.set('eoaConnect', '1');\n    }\n    if (options?.flow === \"create-account\") {\n      // Explicit account creation must not be short-circuited by a stored\n      // passkey-origin user; signup routes already treat switch=1 as that\n      // \"show signup anyway\" signal.\n      params.set('switch', '1');\n    }\n    // Seed first-paint attribution. The passkey app re-validates the actual\n    // caller from document.referrer / PASSKEY_INIT before trusting it.\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n\n    // Add theme params\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n\n    const authPath = this.getAuthDialogPath(options?.flow);\n    const url = `${dialogUrl}${authPath}?${params.toString()}`;\n\n    const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n    this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n    const result = await this.waitForModalAuthResponse(dialog, iframe, cleanup, requestId);\n    if (result.success) {\n      this.emitTelemetry(\"auth.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: { signerType: result.signerType ?? \"passkey\" },\n      });\n    } else {\n      this.emitTelemetry(\n        result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n        telemetry,\n        {\n          outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n          ...describeTelemetryError(result.error),\n        },\n      );\n    }\n    return result;\n  }\n\n  /**\n   * Generate a per-dialog nonce used to correlate iframe close messages with\n   * the SDK modal that opened them. Chromium can report a different\n   * `MessageEvent.source` WindowProxy after the `/dialog/auth` redirect, so\n   * auth close handling needs a stable in-band identifier without accepting\n   * stale close messages from earlier dialogs.\n   */\n  private createDialogRequestId(): string {\n    if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n      return crypto.randomUUID();\n    }\n    return `dialog-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n  }\n\n  /**\n   * Resolve the passkey app route for a requested auth flow.\n   */\n  private getAuthDialogPath(flow: AuthFlow = \"auto\"): string {\n    if (flow === \"login\") return \"/dialog/auth/signin\";\n    if (flow === \"create-account\") return \"/dialog/auth/signup\";\n    return \"/dialog/auth\";\n  }\n\n  /**\n   * Open the connect dialog (lightweight connection without passkey auth).\n   *\n   * This method shows a simple connection confirmation dialog that doesn't\n   * require a passkey signature. Users can optionally enable \"auto-connect\"\n   * to skip this dialog in the future.\n   *\n   * If the user has never connected before, this will return action: \"switch\"\n   * to indicate that the full auth modal should be opened instead.\n   *\n   * @example\n   * ```typescript\n   * const result = await client.connectWithModal();\n   *\n   * if (result.success) {\n   *   console.log('Connected as:', result.user?.address);\n   * } else if (result.action === 'switch') {\n   *   // User needs to sign in first\n   *   const authResult = await client.authWithModal();\n   * }\n   * ```\n   */\n  async connectWithModal(options?: {\n    theme?: ThemeConfig;\n  }): Promise<ConnectResult> {\n    const telemetry = this.createTelemetryOperation(\"connect\");\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({\n      mode: 'iframe',\n    });\n    if (this.config.clientId) {\n      params.set('clientId', this.config.clientId);\n    }\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n\n    // Add theme params\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n\n    const url = `${dialogUrl}/dialog/connect?${params.toString()}`;\n\n    const { dialog, iframe, cleanup } = this.createModalDialog(url);\n    this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n\n    const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n      mode: \"iframe\",\n      telemetry: this.telemetryPayload(telemetry),\n    });\n    if (!ready) {\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_CANCELLED\",\n        errorMessage: \"Connection was cancelled before the dialog became ready\",\n      });\n      return {\n        success: false,\n        action: \"cancel\",\n        error: { code: \"USER_CANCELLED\", message: \"Connection was cancelled\" },\n      };\n    }\n    this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n    const result = await this.waitForConnectResponse(dialog, iframe, cleanup);\n    if (result.success) {\n      this.emitTelemetry(\"connect.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: {\n          autoConnected: result.autoConnected === true,\n          signerType: result.signerType ?? \"passkey\",\n        },\n      });\n    } else {\n      this.emitTelemetry(\n        result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"connect.failed\",\n        telemetry,\n        {\n          outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n          ...describeTelemetryError(result.error),\n          attributes: { action: result.action },\n        },\n      );\n    }\n    return result;\n  }\n\n  /**\n   * High-level connect entry point — the method most integrators want.\n   *\n   * Tries the lightweight {@link connectWithModal} first (no passkey ceremony\n   * for returning users on the same browser), and transparently falls back to\n   * {@link authWithModal} when the connect dialog reports it has no stored\n   * credentials for this origin (`action: \"switch\"`). First-time visitors get\n   * one passkey ceremony to register; subsequent connects on the same browser\n   * resolve with no biometric prompt — and silently when the user has enabled\n   * \"Connect automatically\".\n   *\n   * The return shape is the same {@link ConnectResult} discriminated union as\n   * {@link connectWithModal}, so callers can treat both paths uniformly. When\n   * the auth-modal fallback runs, its successful result is normalized into a\n   * `ConnectResult` (no `id` field — the embedder origin must not see it).\n   *\n   * Cancellation: if the user cancels either dialog, the result is\n   * `{ success: false, action: \"cancel\", error: { code: \"USER_CANCELLED\", … } }`.\n   *\n   * @param options - Forwarded to whichever underlying modal is shown.\n   *   `oauthEnabled` only applies to the auth-modal fallback path.\n   * @returns A {@link ConnectResult} discriminated union.\n   *\n   * @example\n   * ```typescript\n   * const result = await client.connect();\n   * if (result.success) {\n   *   console.log(\"Connected as\", result.user?.address);\n   * }\n   * ```\n   */\n  async connect(options?: {\n    theme?: ThemeConfig;\n    oauthEnabled?: boolean;\n    /**\n     * Opt into \"wallet as signer\" mode for the auth-modal fallback — see\n     * {@link AuthWithModalOptions.eoaConnect}. Set by {@link createOneAuthConnection}.\n     */\n    eoaConnect?: boolean;\n  }): Promise<ConnectResult> {\n    const connectResult = await this.connectWithModal(\n      options?.theme ? { theme: options.theme } : undefined,\n    );\n\n    // Returning user / auto-connect / explicit confirm — done, no biometrics.\n    if (connectResult.success) return connectResult;\n\n    // First-time visitor or cleared storage: connect dialog can't prove the\n    // user, so it asks the SDK to switch to the full auth modal.\n    if (connectResult.action === \"switch\") {\n      const authResult = await this.authWithModal(options);\n      if (authResult.success && authResult.user) {\n        return {\n          success: true,\n          user: {\n            address: authResult.user.address,\n          },\n          // Preserve the signer type from the auth modal — a wallet-picked\n          // (EOA) signup must not be silently normalized to \"passkey\", or the\n          // provider would route its transactions through intents.\n          signerType: authResult.signerType ?? \"passkey\",\n          autoConnected: false,\n        };\n      }\n      // Auth modal cancelled or errored — surface as a ConnectResult so callers\n      // don't have to handle two error shapes.\n      return {\n        success: false,\n        action: \"cancel\",\n        error: authResult.error ?? {\n          code: \"USER_CANCELLED\",\n          message: \"Connection was cancelled\",\n        },\n      };\n    }\n\n    // User cancelled the connect dialog directly — pass through.\n    return connectResult;\n  }\n\n  /**\n   * Open the account management dialog.\n   *\n   * Shows the account overview with guardian status and recovery setup\n   * options. The dialog closes when the user clicks the X button or\n   * completes their action.\n   *\n   * @example\n   * ```typescript\n   * await client.openAccountDialog();\n   * ```\n   */\n  async openAccountDialog(options?: {\n    theme?: ThemeConfig;\n  }): Promise<void> {\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({\n      mode: 'iframe',\n    });\n\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n\n    const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n    // Guardian-setup and session-revoke inside the account dialog submit user\n    // intents, which must carry the app's JWT. Fetch it and forward it in the\n    // PASSKEY_INIT payload. Best-effort: if sponsorship isn't configured the\n    // dialog still opens for read-only / backup actions, and the intent flows\n    // surface a clear missing-authorization error rather than a cryptic\n    // orchestrator 400.\n    //\n    // Fetch the token BEFORE creating the iframe: createModalDialog starts\n    // loading the dialog, and the listener for its PASSKEY_READY is only\n    // installed inside waitForDialogReady. Awaiting a network call between\n    // those two would let a fast iframe post READY before the listener exists\n    // (→ 10s timeout, dialog never opens). Resolving the token first keeps the\n    // create→listen handoff synchronous, as it was originally.\n    const accessTokenResult = await this.fetchAccessToken();\n    const initMessage: Record<string, unknown> = { mode: \"iframe\" };\n    if (accessTokenResult.ok) {\n      initMessage.auth = { accessToken: accessTokenResult.accessToken };\n    }\n\n    const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n    const ready = await this.waitForDialogReady(dialog, iframe, cleanup, initMessage);\n    if (!ready) return;\n\n    // Wait for the dialog to close (no result needed)\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise<void>((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        if (event.data?.type === \"PASSKEY_CLOSE\" || event.data?.type === \"PASSKEY_DISCONNECT\") {\n          window.removeEventListener(\"message\", handleMessage);\n          dialog.removeEventListener(\"close\", handleClose);\n          cleanup();\n          resolve();\n        }\n      };\n      const handleClose = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        resolve();\n      };\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Open the account-recovery backup flow directly.\n   *\n   * Deep-links into the \"Backup your account\" flow inside the account dialog\n   * (rather than the account overview): the user verifies with their passkey,\n   * then saves a recovery passphrase and downloads an encrypted backup file.\n   * Use this to prompt users to secure their account after sign-up.\n   *\n   * Requires an authenticated user (call `authWithModal()` / `connect()`\n   * first) — the dialog reads the signed-in user from the passkey origin.\n   *\n   * Resolves `{ completed: true }` when the user finishes the backup, or\n   * `{ completed: false }` if they dismiss it — so callers can mark an\n   * onboarding step done or re-prompt later.\n   */\n  async setupRecovery(options?: {\n    theme?: ThemeConfig;\n  }): Promise<{ completed: boolean }> {\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({\n      mode: 'iframe',\n      // Deep-link the account dialog straight into the backup nudge instead\n      // of the account overview.\n      action: 'backup',\n    });\n\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n\n    const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n    const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n    const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n      mode: \"iframe\",\n    });\n    if (!ready) return { completed: false };\n\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise<{ completed: boolean }>((resolve) => {\n      let completed = false;\n      const finish = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n        cleanup();\n        resolve({ completed });\n      };\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        const type = event.data?.type;\n        if (type === \"PASSKEY_RECOVERY_RESULT\") {\n          // The dialog reports success right before closing; record it so the\n          // subsequent PASSKEY_CLOSE resolves with completed: true.\n          completed = Boolean(event.data?.data?.completed ?? event.data?.success);\n          return;\n        }\n        if (type === \"PASSKEY_CLOSE\" || type === \"PASSKEY_DISCONNECT\") {\n          finish();\n        }\n      };\n      const handleClose = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        resolve({ completed });\n      };\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Check if a user has already granted consent for the requested fields.\n   *\n   * @deprecated Data-sharing consent is disabled.\n   *\n   * Always returns `{ hasConsent: false }`.\n   */\n  async checkConsent(options: CheckConsentOptions): Promise<CheckConsentResult> {\n    void options;\n    return { hasConsent: false };\n  }\n\n  /**\n   * Request consent from the user to share their data.\n   *\n   * @deprecated Data-sharing consent is disabled.\n   *\n   * Always returns an `INVALID_REQUEST` result.\n   */\n  async requestConsent(options: RequestConsentOptions): Promise<RequestConsentResult> {\n    void options;\n    return {\n      success: false,\n      error: {\n        code: \"INVALID_REQUEST\",\n        message: \"Data-sharing consent is disabled\",\n      },\n    };\n  }\n\n  /**\n   * Open the dedicated SmartSession permission grant dialog.\n   *\n   * The app owns the session key material and sends only the public\n   * `sessionKeyAddress`. 1auth renders the permission review, collects the\n   * owner's passkey authorization, submits the install/enable intent, and\n   * returns a persistable session handle.\n   */\n  async grantPermissions(options: GrantPermissionsOptions): Promise<GrantPermissionsResult> {\n    const telemetry = this.createTelemetryOperation(\"grant_permission\", {\n      targetChains: normalizeGrantTargetChains(options).join(\",\"),\n      sponsor: options.sponsor !== false,\n    });\n    if (!options.accountAddress) {\n      this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"accountAddress is required\",\n      });\n      return {\n        success: false,\n        error: {\n          code: \"INVALID_OPTIONS\",\n          message: \"accountAddress is required\",\n        },\n      };\n    }\n    const targetChains = normalizeGrantTargetChains(options);\n    const sourceChains = normalizeGrantSourceChains(options);\n    if (targetChains.length === 0 || !options.sessionKeyAddress || !options.permissions?.length) {\n      this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"targetChains, sessionKeyAddress, and permissions are required\",\n      });\n      return {\n        success: false,\n        error: {\n          code: \"INVALID_OPTIONS\",\n          message: \"targetChains, sessionKeyAddress, and permissions are required\",\n        },\n      };\n    }\n    if (!this.sponsorship) {\n      this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"MISSING_APP_CREDENTIALS\",\n        errorMessage: MISSING_APP_CREDENTIALS_MESSAGE,\n      });\n      return {\n        success: false,\n        error: {\n          code: \"MISSING_APP_CREDENTIALS\",\n          message: MISSING_APP_CREDENTIALS_MESSAGE,\n        },\n      };\n    }\n\n    const accessTokenResult = await this.fetchAccessToken();\n    if (!accessTokenResult.ok) {\n      this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n        errorMessage: accessTokenResult.message,\n      });\n      return {\n        success: false,\n        error: {\n          code: \"SPONSORSHIP_FETCH_FAILED\",\n          message: accessTokenResult.message,\n        },\n      };\n    }\n\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams(options.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const grantUrl = `${dialogUrl}/dialog/grant-permission?${params.toString()}`;\n    const { dialog, iframe, cleanup } = this.createModalDialog(grantUrl);\n    const initPayload = {\n      mode: \"iframe\",\n      clientId: this.config.clientId,\n      grant: cloneGrantPayload({\n        accountAddress: options.accountAddress,\n        targetChain: targetChains[0],\n        targetChains,\n        sourceChains,\n        sessionKeyAddress: options.sessionKeyAddress,\n        permissions: options.permissions,\n        crossChainPermits: options.crossChainPermits,\n        validUntil: options.validUntil,\n        validAfter: options.validAfter,\n        maxUses: options.maxUses,\n        contracts: options.contracts,\n      }),\n      auth: { accessToken: accessTokenResult.accessToken },\n      sponsor: options.sponsor !== false,\n      telemetry: this.telemetryPayload(telemetry),\n    };\n\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      targetChains,\n    });\n    const result = await this.waitForGrantPermissionResponse(\n      dialog,\n      iframe,\n      cleanup,\n      options.sponsor !== false,\n      initPayload,\n    );\n    if (result.success) {\n      this.emitTelemetry(\"grant_permission.succeeded\", telemetry, {\n        outcome: \"success\",\n        targetChains,\n        status: result.status ? String(result.status) : undefined,\n      });\n      // The grant is already resolved; keep the dialog's \"Permission granted\"\n      // success screen (green Done button) on screen until the user dismisses\n      // it, then tear the iframe down. Without this the dialog would close the\n      // instant the result arrived and the confirmation would never be seen —\n      // unlike the sign flow, where sendIntent awaits the dialog close after a\n      // confirmed signature.\n      await this.waitForDialogClose(dialog, cleanup);\n    } else {\n      this.emitTelemetry(\n        result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"grant_permission.failed\",\n        telemetry,\n        {\n          outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n          targetChains,\n          ...describeTelemetryError(result.error),\n        },\n      );\n    }\n    return result;\n  }\n\n  /**\n   * List SmartSession grants previously granted to the current browser origin.\n   *\n   * 1auth derives the app identity from the request Origin header. The SDK does\n   * not send `clientId` for this lookup because grants are origin-scoped.\n   */\n  async listSessionGrants(\n    options: ListSessionGrantsOptions,\n  ): Promise<ListSessionGrantsResult> {\n    if (!options.accountAddress) {\n      return {\n        success: false,\n        error: {\n          code: \"INVALID_OPTIONS\",\n          message: \"accountAddress is required\",\n        },\n      };\n    }\n\n    const params = new URLSearchParams();\n    if (options.accountAddress) params.set(\"accountAddress\", options.accountAddress);\n    if (options.includeRevoked) params.set(\"includeRevoked\", \"true\");\n\n    try {\n      const response = await fetch(\n        `${this.config.providerUrl}/api/sessions/grants?${params.toString()}`,\n        { credentials: \"include\" },\n      );\n      const data = await response.json();\n      if (!response.ok) {\n        return {\n          success: false,\n          error: {\n            code: \"LIST_SESSION_GRANTS_FAILED\",\n            message: data?.error ?? `Request failed with status ${response.status}`,\n          },\n        };\n      }\n      return { success: true, grants: data.grants ?? [] };\n    } catch (err) {\n      return {\n        success: false,\n        error: {\n          code: \"LIST_SESSION_GRANTS_FAILED\",\n          message: err instanceof Error ? err.message : String(err),\n        },\n      };\n    }\n  }\n\n  /**\n   * Authenticate a user with an optional challenge to sign.\n   *\n   * This method combines authentication (sign in / sign up) with optional\n   * challenge signing, enabling off-chain login without on-chain transactions.\n   *\n   * When a challenge is provided:\n   * 1. User authenticates (sign in or sign up) through the normal auth dialog\n   * 2. User signs the challenge through the normal signing dialog\n   * 3. Returns user info + signature for server-side verification\n   *\n   * This composes the same supported provider routes as calling\n   * `authWithModal()` followed by `signMessage()`, so challenge auth cannot\n   * drift onto a provider route that the passkey service does not expose.\n   *\n   * @example\n   * ```typescript\n   * const result = await client.authenticate({\n   *   challenge: `Login to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`\n   * });\n   *\n   * if (result.success && result.challenge) {\n   *   // Verify signature server-side\n   *   const isValid = await verifyOnServer(\n   *     result.user?.address,\n   *     result.challenge.signature,\n   *     result.challenge.signedHash\n   *   );\n   * }\n   * ```\n   */\n  async authenticate(options?: AuthenticateOptions & { theme?: ThemeConfig }): Promise<AuthenticateResult> {\n    const telemetry = this.createTelemetryOperation(\"authenticate\", {\n      hasChallenge: !!options?.challenge,\n    });\n    const authResult = await this.authWithModal(options?.theme ? { theme: options.theme } : undefined);\n    if (!authResult.success) {\n      this.emitTelemetry(\n        authResult.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n        telemetry,\n        {\n          outcome: authResult.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n          ...describeTelemetryError(authResult.error),\n        },\n      );\n      return authResult;\n    }\n\n    if (!options?.challenge) {\n      this.emitTelemetry(\"auth.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: { challengeSigned: false },\n      });\n      return authResult;\n    }\n\n    const accountAddress = authResult.user?.address;\n    if (!accountAddress) {\n      const result: AuthenticateResult = {\n        success: false,\n        user: authResult.user,\n        signerType: authResult.signerType,\n        error: {\n          code: \"AUTHENTICATE_USER_MISSING\",\n          message: \"Authentication succeeded but no account address was returned for challenge signing\",\n        },\n      };\n      this.emitTelemetry(\"auth.failed\", telemetry, {\n        outcome: \"failure\",\n        ...describeTelemetryError(result.error),\n      });\n      return result;\n    }\n\n    const signResult = await this.signMessage({\n      accountAddress,\n      message: options.challenge,\n      description: \"Verify your identity\",\n      theme: options.theme,\n    });\n\n    if (signResult.success && signResult.signature && signResult.signedHash) {\n      const result: AuthenticateResult = {\n        ...authResult,\n        challenge: {\n          signature: signResult.signature,\n          signedHash: signResult.signedHash,\n        },\n      };\n      this.emitTelemetry(\"auth.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: { challengeSigned: true },\n      });\n      return result;\n    }\n\n    const error = signResult.error\n      ? { code: signResult.error.code, message: signResult.error.message }\n      : { code: \"SIGNING_FAILED\", message: \"Challenge signing failed\" };\n    const result: AuthenticateResult = {\n      success: false,\n      user: authResult.user,\n      signerType: authResult.signerType,\n      error,\n    };\n    const cancelled = error.code === \"USER_CANCELLED\" || error.code === \"USER_REJECTED\";\n    this.emitTelemetry(\n      cancelled ? \"dialog.cancelled\" : \"auth.failed\",\n      telemetry,\n      {\n        outcome: cancelled ? \"cancelled\" : \"failure\",\n        ...describeTelemetryError(error),\n      },\n    );\n    return result;\n  }\n\n  /**\n   * Show signing in a modal overlay (iframe dialog)\n   */\n  async signWithModal(options: SigningRequestOptions & { theme?: ThemeConfig }): Promise<SigningResult> {\n    const telemetry = this.createTelemetryOperation(\"sign\", {\n      signingMode: \"transaction\",\n      hasTransaction: !!options.transaction,\n      hasAccountAddress: !!options.accountAddress,\n    });\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n    const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n    const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n      hidden: requestedBlindSigning,\n    });\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      attributes: { blindSigning: requestedBlindSigning },\n    });\n\n    const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n      mode: \"iframe\",\n      challenge: options.challenge,\n      accountAddress: options.accountAddress,\n      description: options.description,\n      transaction: options.transaction,\n      metadata: options.metadata,\n      telemetry: this.telemetryPayload(telemetry),\n    }, {\n      blindSigning: requestedBlindSigning,\n      reveal,\n    });\n    if (!ready) {\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_REJECTED\",\n        errorMessage: \"User closed the dialog before signing\",\n      });\n      return {\n        success: false,\n        error: {\n          code: \"USER_REJECTED\",\n          message: \"User closed the dialog\",\n        },\n      };\n    }\n    this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n    const result = await this.waitForSigningResponse(dialog, iframe, cleanup);\n    if (result.success) {\n      this.emitTelemetry(\"sign.succeeded\", telemetry, { outcome: \"success\" });\n    } else {\n      this.emitTelemetry(\n        result.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n        telemetry,\n        {\n          outcome: result.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n          ...describeTelemetryError(result.error),\n        },\n      );\n    }\n    return result;\n  }\n\n  /**\n   * Send an intent to the Rhinestone orchestrator\n   *\n   * This is the high-level method for cross-chain transactions:\n   * 1. Prepares the intent (gets quote from orchestrator)\n   * 2. Shows the signing modal with real fees\n   * 3. Submits the signed intent for execution\n   * 4. Returns the transaction hash\n   *\n   * @example\n   * ```typescript\n   * const result = await client.sendIntent({\n   *   accountAddress: '0x...',\n   *   targetChain: 8453, // Base\n   *   calls: [\n   *     {\n   *       to: '0x...',\n   *       data: '0x...',\n   *       label: 'Swap ETH for USDC',\n   *       sublabel: '0.1 ETH → ~250 USDC',\n   *     },\n   *   ],\n   * });\n   *\n   * if (result.success) {\n   *   console.log('Transaction hash:', result.transactionHash);\n   * }\n   * ```\n   */\n  async sendIntent(options: SendIntentOptions): Promise<SendIntentResult> {\n    const { accountAddress, targetChain } = options;\n    // Cap label/sublabel up front so every downstream consumer (prepare\n    // request body AND the dialog's phase-1 init payload) sees the same\n    // truncated strings — keeps wire data and rendered UI in sync.\n    const calls = capCallLabels(options.calls);\n    const sponsorshipMode = this.resolveSponsorshipMode(options);\n    const sponsor = sponsorshipMode !== \"disabled\";\n    const telemetry = this.createTelemetryOperation(\"intent\", {\n      targetChain: targetChain ?? null,\n      callsCount: calls?.length ?? 0,\n      sponsor,\n      sponsorshipMode,\n      blindSigning: this.shouldRequestBlindSigning(options),\n    });\n\n    if (getStoredSignerType() === \"eoa\") {\n      this.emitTelemetry(\"intent.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"E_SIGNER_UNSUPPORTED\",\n        errorMessage: \"Cross-chain intents are not supported for EOA sessions\",\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\",\n        error: {\n          code: \"E_SIGNER_UNSUPPORTED\",\n          message:\n            \"Cross-chain intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n        },\n      };\n    }\n\n    if (!accountAddress) {\n      this.emitTelemetry(\"intent.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"accountAddress is required\",\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\",\n        error: {\n          code: \"INVALID_OPTIONS\",\n          message: \"accountAddress is required\",\n        },\n      };\n    }\n\n    const hasCalls = !!calls?.length;\n    const hasTokenRequests = !!options.tokenRequests?.length;\n    if (!targetChain || (!hasCalls && !hasTokenRequests)) {\n      this.emitTelemetry(\"intent.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"targetChain and calls or tokenRequests are required\",\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\",\n        error: {\n          code: \"INVALID_OPTIONS\",\n          message: \"targetChain and calls or tokenRequests are required\",\n        },\n      };\n    }\n\n    if (!this.sponsorship) {\n      this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"MISSING_APP_CREDENTIALS\",\n        errorMessage: \"No sponsorship configured on OneAuthClient\",\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\",\n        error: {\n          code: \"MISSING_APP_CREDENTIALS\",\n          message:\n            \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n        },\n      };\n    }\n\n    // Convert bigint amounts to strings for API serialization\n    const serializedTokenRequests = options.tokenRequests?.map((r) => ({\n      token: r.token,\n      amount: r.amount.toString(),\n    }));\n    let prepareResponse: PrepareIntentResponse;\n\n    // 1. Show dialog immediately + prepare in parallel.\n    //\n    // Two-phase approach — why:\n    //   - The dialog is shown right away so the user sees a UI immediately.\n    //   - Access-token minting also runs behind the dialog boot. The prepare\n    //     request still needs the token, but the iframe/chunk load does not;\n    //     overlapping them removes a cold app-token round trip from the\n    //     perceived loading path.\n    //   - Intent preparation (API call to the orchestrator for a quote) can\n    //     take 1–3 seconds. Hiding the dialog until the quote is ready would\n    //     make the interaction feel sluggish.\n    //   - Phase 1: send a stable transaction shell with raw calls but ask the\n    //     dialog to hold the movement card skeleton until the quote arrives.\n    //     Decoded previews are useful in isolation, but here they cause noisy\n    //     value churn when quote-normalized token decimals replace them.\n    //   - Phase 2: once the quote arrives, send a narrow quote-ready update\n    //     instead of replaying the whole PASSKEY_INIT path.\n    //\n    // Fast path: if preparation finishes before the iframe signals PASSKEY_READY\n    // (e.g. on a fast connection), we skip phase 1 entirely and send the full\n    // payload in a single PASSKEY_INIT message.\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams();\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n    const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n    const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n      hidden: requestedBlindSigning,\n    });\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      attributes: { blindSigning: requestedBlindSigning },\n    });\n\n    const dialogOrigin = this.getDialogOrigin();\n    const dialogOpenedAt = Date.now();\n    let iframeReadyObserved = false;\n    type EarlyDialogClose = { type: \"dialog_closed\"; ready: boolean };\n    let stopEarlyCloseWatch: () => void = () => undefined;\n    const earlyDialogClosePromise = new Promise<EarlyDialogClose>((resolve) => {\n      let settled = false;\n      const stop = () => {\n        if (settled) return;\n        settled = true;\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n      };\n      stopEarlyCloseWatch = stop;\n\n      const resolveClosed = (ready: boolean) => {\n        stop();\n        cleanup();\n        resolve({ type: \"dialog_closed\", ready });\n      };\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        // Scope the CLOSE to *this* sign dialog's iframe. authWithModal() and\n        // sendIntent() share the same dialogOrigin (passkey.1auth.app), so the\n        // auth dialog's PASSKEY_CLOSE — emitted async as it tears down on a\n        // successful sign-in — can still be in-flight when sendIntent attaches\n        // this listener for its brand-new dialog. Without the source check it\n        // gets misattributed to the sign dialog and cancels it before it's\n        // ready (USER_CANCELLED). Same guard the modal auth listener already\n        // applies via event.source === iframe.contentWindow.\n        if (\n          event.data?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          resolveClosed(iframeReadyObserved);\n        }\n      };\n\n      const handleClose = () => {\n        resolveClosed(iframeReadyObserved);\n      };\n\n      // Covers the gap after PASSKEY_READY but before the full signing listener\n      // is installed. Without this, closing the loading dialog during a cold\n      // access-token fetch drops PASSKEY_CLOSE and lets prepare continue.\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n    let dialogReadyDurationMs: number | undefined;\n    const dialogReadyPromise = this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n      blindSigning: requestedBlindSigning,\n      reveal,\n    }).then((result) => {\n      dialogReadyDurationMs = Date.now() - dialogOpenedAt;\n      iframeReadyObserved = result.ready;\n      return result;\n    });\n    const dialogClosedBeforeReadyPromise = dialogReadyPromise.then((result) =>\n      result.ready\n        ? new Promise<never>(() => undefined)\n        : ({ type: \"dialog_closed\" as const, ready: false }),\n    );\n\n    const accessTokenStartedAt = Date.now();\n    let accessTokenDurationMs: number | undefined;\n    const accessTokenPromise = this.fetchAccessToken().then((result) => {\n      accessTokenDurationMs = Date.now() - accessTokenStartedAt;\n      return result;\n    });\n\n    const accessOrClose = await Promise.race([\n      accessTokenPromise.then((result) => ({ type: \"access_token\" as const, result })),\n      dialogClosedBeforeReadyPromise,\n      earlyDialogClosePromise,\n    ]);\n    if (accessOrClose.type === \"dialog_closed\") {\n      stopEarlyCloseWatch();\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_CANCELLED\",\n        errorMessage: accessOrClose.ready\n          ? \"User closed the dialog while intent setup was still loading\"\n          : \"User closed the dialog before it became ready\",\n        attributes: {\n          accessTokenDurationMs,\n          dialogReadyDurationMs,\n        },\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\" as const,\n        error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n      };\n    }\n\n    const accessTokenResult = accessOrClose.result;\n    // Access-token failures are NOT returned early: they're converted into a\n    // synthetic failed PrepareResult below so the dialog's prepare-error\n    // retry (\"Try Again\" → PASSKEY_RETRY_PREPARE) covers them too — the\n    // retry path re-mints the token first, which is exactly the recovery a\n    // transient token-endpoint failure needs.\n    let accessTokenFailure: { code: string; message: string } | null = null;\n    if (!accessTokenResult.ok) {\n      const errorCode = accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\";\n      this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode,\n        errorMessage: accessTokenResult.message,\n        attributes: {\n          accessTokenDurationMs,\n          dialogReadyDurationMs,\n          loadingPhase: \"access_token\",\n        },\n      });\n      accessTokenFailure = { code: errorCode, message: accessTokenResult.message };\n    }\n    // Mutable: a dialog-initiated prepare retry re-mints the token (the most\n    // common prepare failure is an expired app JWT) and later auth bundles\n    // must carry the token the successful prepare actually used.\n    let accessToken = accessTokenResult.ok ? accessTokenResult.accessToken : \"\";\n\n    // Define requestBody outside try block so it's accessible for quote refresh.\n    const requestBody = {\n      accountAddress,\n      targetChain,\n      calls,\n      tokenRequests: serializedTokenRequests,\n      sourceAssets: options.sourceAssets,\n      sourceChainId: options.sourceChainId,\n      auth: { accessToken },\n      ...(this.config.clientId && { clientId: this.config.clientId }),\n    };\n\n    // Start prepare in background; track completion via mutable variable.\n    // When the iframe becomes ready, earlyPrepareResult will be non-null\n    // if prepare finished first (fast path), or null if still in flight.\n    type PrepareResult =\n      | { success: true; data: PrepareIntentResponse; tier: string | null }\n      | { success: false; error: { code: string; message: string; details?: OneAuthErrorDetails } };\n    let earlyPrepareResult: PrepareResult | null = null;\n    // Sponsored intents draft the canonical quote input, mint a single-use\n    // quote grant, prepare the authoritative quote, then mint a distinct\n    // single-use execution grant from the returned intentOp.\n    // The promise exposed below always contains the execution-time grant.\n    let extensionTokensPromise: Promise<ExtensionTokensFetchResult> =\n      Promise.resolve({ ok: true, extensionTokens: [] });\n    let extensionTokensDurationMs: number | undefined;\n    this.emitTelemetry(\"intent.prepare.started\", telemetry, {\n      outcome: \"started\",\n      targetChain,\n      attributes: {\n        accessTokenDurationMs,\n        dialogReadyDurationMs,\n      },\n    });\n    const prepareStartedAt = Date.now();\n    let prepareDurationMs: number | undefined;\n    // Wrapped so dialog-initiated retries re-run the complete draft → grant →\n    // final quote handshake with the latest access token.\n    const runPrepare = async (): Promise<PrepareResult> => {\n      let result: PrepareResult;\n\n      if (sponsorshipMode === \"disabled\") {\n        result = await this.prepareIntent(\n          { ...requestBody, quoteMode: \"final\", sponsorshipMode: \"self-funded\" },\n          telemetry,\n        );\n      } else {\n        const draft = await this.prepareSponsorshipDraft(\n          { ...requestBody, sponsorshipMode: \"required\" },\n          telemetry,\n        );\n        if (!draft.success) {\n          result = draft;\n        } else {\n          const extensionTokensStartedAt = Date.now();\n          const quoteGrantResult = await this.fetchExtensionTokens(\n            [JSON.stringify(draft.sponsorshipIntentInput)],\n            [true],\n          );\n          extensionTokensDurationMs = Date.now() - extensionTokensStartedAt;\n          if (!quoteGrantResult.ok) {\n            if (sponsorshipMode === \"preferred\") {\n              extensionTokensPromise = Promise.resolve({ ok: true, extensionTokens: [] });\n              result = await this.prepareIntent(\n                { ...requestBody, quoteMode: \"final\", sponsorshipMode: \"self-funded\" },\n                telemetry,\n              );\n            } else {\n              result = {\n                success: false,\n                error: {\n                  code: \"SPONSORSHIP_FETCH_FAILED\",\n                  message: quoteGrantResult.message,\n                },\n              };\n            }\n          } else {\n            const prepareFinalQuote = (quoteGrant: string) => this.prepareIntent(\n              {\n                ...requestBody,\n                quoteMode: \"final\",\n                sponsorshipMode: \"required\",\n                auth: {\n                  accessToken,\n                  extensionToken: quoteGrant,\n                },\n              },\n              telemetry,\n            );\n            let quoteIsSponsored = true;\n            result = await prepareFinalQuote(quoteGrantResult.extensionTokens[0]);\n            if (!result.success) {\n              // User-service grants are single-use. If an upstream retry or\n              // duplicate verification consumes the JTI, transparently mint\n              // one replacement for the identical canonical quote input.\n              const replacementQuoteGrant = await this.fetchExtensionTokens(\n                [JSON.stringify(draft.sponsorshipIntentInput)],\n                [true],\n              );\n              if (replacementQuoteGrant.ok) {\n                result = await prepareFinalQuote(replacementQuoteGrant.extensionTokens[0]);\n              }\n            }\n            if (!result.success && sponsorshipMode === \"preferred\") {\n              // A valid grant does not guarantee the sponsor will accept the\n              // authoritative quote. Preferred mode must preserve its public\n              // contract by obtaining a fresh, explicitly self-funded quote.\n              extensionTokensPromise = Promise.resolve({ ok: true, extensionTokens: [] });\n              quoteIsSponsored = false;\n              result = await this.prepareIntent(\n                { ...requestBody, quoteMode: \"final\", sponsorshipMode: \"self-funded\" },\n                telemetry,\n              );\n            }\n            if (result.success && quoteIsSponsored) {\n              const executionGrantResult = await this.fetchExtensionTokens(\n                [result.data.intentOp],\n                [true],\n              );\n              extensionTokensDurationMs = Date.now() - extensionTokensStartedAt;\n              if (!executionGrantResult.ok) {\n                if (sponsorshipMode === \"preferred\") {\n                  extensionTokensPromise = Promise.resolve({ ok: true, extensionTokens: [] });\n                  quoteIsSponsored = false;\n                  result = await this.prepareIntent(\n                    { ...requestBody, quoteMode: \"final\", sponsorshipMode: \"self-funded\" },\n                    telemetry,\n                  );\n                } else {\n                  result = {\n                    success: false,\n                    error: {\n                      code: \"SPONSORSHIP_FETCH_FAILED\",\n                      message: executionGrantResult.message,\n                    },\n                  };\n                }\n              } else {\n                extensionTokensPromise = Promise.resolve(executionGrantResult);\n              }\n            }\n          }\n        }\n      }\n\n      earlyPrepareResult = result;\n      prepareDurationMs = Date.now() - prepareStartedAt;\n      this.emitTelemetry(\n        result.success ? \"intent.prepare.succeeded\" : \"intent.prepare.failed\",\n        telemetry,\n        result.success\n          ? {\n              outcome: \"success\",\n              targetChain,\n              status: \"quoted\",\n              attributes: { accessTokenDurationMs, dialogReadyDurationMs, prepareDurationMs },\n            }\n          : {\n              outcome: \"failure\",\n              targetChain,\n              ...describeTelemetryError(result.error),\n              attributes: {\n                accessTokenDurationMs,\n                dialogReadyDurationMs,\n                prepareDurationMs,\n                loadingPhase: \"prepare\",\n              },\n            },\n      );\n      return result;\n    };\n    // When the access token never materialised, seed the flow with a failed\n    // result instead of calling /prepare with empty auth — the fast/\n    // progressive retry loops below surface it in the dialog and the user's\n    // retry re-mints the token before re-running prepare.\n    const preparePromise = accessTokenFailure\n      ? Promise.resolve<PrepareResult>({\n          success: false,\n          error: accessTokenFailure,\n        }).then((r) => {\n          earlyPrepareResult = r;\n          return r;\n        })\n      : runPrepare();\n\n    // Re-run prepare after the dialog requested a retry. Re-mints the app\n    // access token first: the dominant cause of prepare failures is the app\n    // JWT expiring (orchestrator 401), so retrying with the original token\n    // would fail forever. Returns the new PrepareResult — failures feed back\n    // into the caller's retry loop.\n    const retryPrepare = async (): Promise<PrepareResult> => {\n      const retryTokenResult = await this.fetchAccessToken();\n      if (!retryTokenResult.ok) {\n        return {\n          success: false,\n          error: {\n            code: retryTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n            message: retryTokenResult.message,\n          },\n        };\n      }\n      accessToken = retryTokenResult.accessToken;\n      requestBody.auth = { accessToken };\n      extensionTokensPromise = Promise.resolve({ ok: true, extensionTokens: [] });\n      return runPrepare();\n    };\n\n    // Wait for iframe to be ready\n    const readyOrClose = await Promise.race([\n      dialogReadyPromise.then((result) => ({ type: \"ready\" as const, result })),\n      earlyDialogClosePromise,\n    ]);\n    if (readyOrClose.type === \"dialog_closed\") {\n      stopEarlyCloseWatch();\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_CANCELLED\",\n        errorMessage: readyOrClose.ready\n          ? \"User closed the dialog while intent setup was still loading\"\n          : \"User closed the dialog before it became ready\",\n        attributes: {\n          accessTokenDurationMs,\n          dialogReadyDurationMs,\n          prepareDurationMs,\n        },\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\" as const,\n        error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n      };\n    }\n    const dialogResult = readyOrClose.result;\n\n    // Handle dialog closed before ready\n    if (!dialogResult.ready) {\n      stopEarlyCloseWatch();\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_CANCELLED\",\n        errorMessage: \"User closed the dialog before it became ready\",\n      });\n      return {\n        success: false,\n        intentId: \"\",\n        status: \"failed\" as const,\n        error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n      };\n    }\n    const blindSigning = dialogResult.blindSigning;\n    this.emitTelemetry(\"dialog.ready\", telemetry, {\n      outcome: \"started\",\n      attributes: {\n        accessTokenDurationMs,\n        dialogReadyDurationMs,\n      },\n    });\n\n    // Mutable init payload — starts as early preview, upgraded to full after quote\n    let currentInitPayload: Record<string, unknown>;\n    const refreshQuote = async () => {\n      try {\n        // Re-mint the app access token for the refreshed prepare. Quote\n        // refreshes happen when the user lingers on the review screen, so\n        // the token captured in `requestBody` may be close to (or past) its\n        // 1h expiry — the orchestrator would reject it with a 401 and the\n        // refresh would fail even though the quote itself is refreshable.\n        const refreshedTokenResult = await this.fetchAccessToken();\n        const refreshToken = refreshedTokenResult.ok\n          ? refreshedTokenResult.accessToken\n          : accessToken;\n        accessToken = refreshToken;\n        requestBody.auth = { accessToken: refreshToken };\n        extensionTokensPromise = Promise.resolve({ ok: true, extensionTokens: [] });\n        const refreshedResult = await runPrepare();\n        if (!refreshedResult.success) {\n          console.error(\"[SDK] Quote refresh failed:\", refreshedResult.error.message);\n          return null;\n        }\n        const refreshedData = refreshedResult.data;\n        const extensionResult = await extensionTokensPromise;\n        if (!extensionResult.ok) {\n          console.error(\"[SDK] Extension token refresh failed:\", extensionResult.message);\n          return null;\n        }\n        const refreshedAuth: SponsorshipTokens = {\n          accessToken: refreshToken,\n          extensionTokens: extensionResult.extensionTokens,\n        };\n\n        // Keep execute (legacy SDK-submit path) aligned with the latest quote\n        // the dialog is reviewing — token, grant, and quote move together.\n        prepareResponse = refreshedData;\n        extensionTokensPromise = Promise.resolve(extensionResult);\n        // Keep iframe-remount replays (PASSKEY_READY → PASSKEY_INIT) on the\n        // refreshed quote too.\n        currentInitPayload = {\n          ...currentInitPayload,\n          transaction: refreshedData.transaction,\n          challenge: refreshedData.challenge,\n          originMessages: refreshedData.originMessages,\n          expiresAt: refreshedData.expiresAt,\n          intentOp: refreshedData.intentOp,\n          digestResult: refreshedData.digestResult,\n          // A refreshed quote mints a fresh binding — it MUST replace the old\n          // one, or execute would verify the new intentOp against a stale\n          // binding and reject (once enforce mode is on).\n          binding: refreshedData.binding,\n          auth: refreshedAuth,\n        };\n        return {\n          intentOp: refreshedData.intentOp,\n          expiresAt: refreshedData.expiresAt,\n          challenge: refreshedData.challenge,\n          originMessages: refreshedData.originMessages?.map((message) => ({\n            chainId: message.chainId,\n            hash: message.messageHash,\n          })),\n          transaction: refreshedData.transaction,\n          digestResult: refreshedData.digestResult,\n          binding: refreshedData.binding,\n          // Dialog-executed intents read auth from dialog state — ship the\n          // rebound bundle with the refresh so PASSKEY_REFRESH_COMPLETE\n          // updates it alongside the quote.\n          auth: refreshedAuth,\n        };\n      } catch (error) {\n        console.error(\"[SDK] Quote refresh error:\", error);\n        return null;\n      }\n    };\n    // Install the close/result listener before the progressive preview init is\n    // sent. Otherwise a user can click Cancel while /prepare is still waiting\n    // on quote or portfolio work, and the parent page drops the message.\n    const signingResultPromise = this.waitForSigningWithRefresh(\n      dialog,\n      iframe,\n      cleanup,\n      dialogOrigin,\n      refreshQuote,\n    );\n    stopEarlyCloseWatch();\n\n    if (earlyPrepareResult) {\n      // Fast path: prepare already finished — send full PASSKEY_INIT (no regression)\n      // Type assertion needed: TS control flow doesn't track .then() mutations\n      let prepareResult = earlyPrepareResult as PrepareResult;\n      // Same retry contract as the progressive path below: any failure before\n      // the full payload reaches the dialog surfaces as PASSKEY_PREPARE_ERROR,\n      // and the dialog's \"Try Again\" re-enters via PASSKEY_RETRY_PREPARE.\n      for (;;) {\n        while (!prepareResult.success) {\n          this.sendPrepareError(iframe, prepareResult.error.message);\n          if (blindSigning) {\n            // No visible dialog to host the error/retry UI — fail immediately.\n            cleanup();\n            return {\n              success: false,\n              intentId: \"\",\n              status: \"failed\",\n              error: prepareResult.error,\n            };\n          }\n          const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n          if (next === \"closed\") {\n            return {\n              success: false,\n              intentId: \"\",\n              status: \"failed\",\n              error: prepareResult.error,\n            };\n          }\n          prepareResult = await retryPrepare();\n        }\n        prepareResponse = prepareResult.data;\n        const extensionResult = await extensionTokensPromise;\n        if (extensionResult.ok) {\n          const sponsorshipTokens: SponsorshipTokens = {\n            accessToken,\n            extensionTokens: extensionResult.extensionTokens,\n          };\n          currentInitPayload = {\n            mode: \"iframe\",\n            calls,\n            chainId: targetChain,\n            transaction: prepareResponse.transaction,\n            challenge: prepareResponse.challenge,\n            accountAddress: prepareResponse.accountAddress,\n            originMessages: prepareResponse.originMessages,\n            tokenRequests: serializedTokenRequests,\n            expiresAt: prepareResponse.expiresAt,\n            userId: prepareResponse.userId,\n            intentOp: prepareResponse.intentOp,\n            digestResult: prepareResponse.digestResult,\n            binding: prepareResponse.binding,\n            tier: prepareResult.tier,\n            auth: sponsorshipTokens,\n            telemetry: this.telemetryPayload(telemetry),\n          };\n          dialogResult.sendInit(currentInitPayload);\n          break;\n        }\n        this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n          outcome: \"failure\",\n          errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n          errorMessage: extensionResult.message,\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n            loadingPhase: \"extension_token\",\n          },\n        });\n        this.sendPrepareError(iframe, extensionResult.message);\n        if (blindSigning) {\n          cleanup();\n          return {\n            success: false,\n            intentId: \"\",\n            status: \"failed\",\n            error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n          };\n        }\n        const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n        if (next === \"closed\") {\n          return {\n            success: false,\n            intentId: \"\",\n            status: \"failed\",\n            error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n          };\n        }\n        // Retrying just the extension token would be unsafe — grants are\n        // digest-bound to the intentOp — so re-run the full prepare.\n        prepareResult = await retryPrepare();\n      }\n    } else {\n      // Progressive path: send the raw calls up front so the dialog can\n      // decode them locally (/api/decode) and reveal a fully-formed\n      // transaction card the moment decode settles — without waiting on the\n      // orchestrator quote. The quote follows via PASSKEY_QUOTE_READY below\n      // and upgrades the fee row + any routed amounts in place. The dialog\n      // gates the Sign button on that authoritative quote, so revealing the\n      // decoded preview early never lets the user sign un-quoted data.\n      currentInitPayload = {\n        mode: \"iframe\",\n        signingMode: \"transaction\",\n        calls,\n        chainId: targetChain,\n        accountAddress: options.accountAddress,\n        tokenRequests: serializedTokenRequests,\n        telemetry: this.telemetryPayload(telemetry),\n      };\n      dialogResult.sendInit(currentInitPayload);\n\n      // Wait for prepare to complete, then send quote data\n      const prepareOrCancel = await Promise.race([\n        preparePromise.then((prepareResult) => ({\n          type: \"prepare\" as const,\n          prepareResult,\n        })),\n        signingResultPromise.then((signingResult) => ({\n          type: \"signing\" as const,\n          signingResult,\n        })),\n      ]);\n      let prepareResult: PrepareResult;\n      if (prepareOrCancel.type === \"signing\") {\n        const earlySigningResult = prepareOrCancel.signingResult;\n        if (earlySigningResult.success) {\n          // Signing cannot complete before the prepared challenge arrives, but\n          // keep this branch total so TypeScript and future hidden flows have a\n          // deterministic path to the quote data needed for execute.\n          prepareResult = await preparePromise;\n        } else {\n          const signingError = earlySigningResult.error;\n          this.emitTelemetry(\n            signingError?.code === \"USER_REJECTED\"\n              ? \"dialog.cancelled\"\n              : \"intent.sign.failed\",\n            telemetry,\n            {\n              outcome: signingError?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n              ...describeTelemetryError(signingError),\n            },\n          );\n          if (blindSigning) cleanup();\n          return {\n            success: false,\n            intentId: \"\",\n            status: \"failed\",\n            error: signingError,\n          };\n        }\n      } else {\n        prepareResult = prepareOrCancel.prepareResult;\n      }\n      // Drive prepare → quote-ready → extension-token to completion, looping\n      // back through the dialog's \"Try Again\" (PASSKEY_RETRY_PREPARE) on any\n      // failure along the way. Each retry re-runs the FULL prepare so the\n      // quote and the per-intent sponsorship grant always match — a grant is\n      // digest-bound to its intentOp, so retrying just the extension token\n      // against a re-quoted intent would produce an unusable auth bundle.\n      for (;;) {\n        while (!prepareResult.success) {\n          this.sendPrepareError(iframe, prepareResult.error.message);\n          if (blindSigning) {\n            // No visible dialog to host the error/retry UI — fail immediately.\n            cleanup();\n            return {\n              success: false,\n              intentId: \"\",\n              status: \"failed\",\n              error: prepareResult.error,\n            };\n          }\n          const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n          if (next === \"closed\") {\n            return {\n              success: false,\n              intentId: \"\",\n              status: \"failed\",\n              error: prepareResult.error,\n            };\n          }\n          prepareResult = await retryPrepare();\n        }\n        prepareResponse = prepareResult.data;\n        const authReady =\n          !sponsor\n            ? ({\n                accessToken,\n                extensionTokens: [],\n              } satisfies SponsorshipTokens)\n            : undefined;\n\n        // Upgrade the init payload with full quote data. For sponsored intents,\n        // don't wait for the extension token here: review display needs the quote,\n        // while submit auth can arrive as a small follow-up before Sign unlocks.\n        currentInitPayload = {\n          mode: \"iframe\",\n          calls,\n          chainId: targetChain,\n          transaction: prepareResponse.transaction,\n          challenge: prepareResponse.challenge,\n          accountAddress: prepareResponse.accountAddress,\n          originMessages: prepareResponse.originMessages,\n          tokenRequests: serializedTokenRequests,\n          expiresAt: prepareResponse.expiresAt,\n          userId: prepareResponse.userId,\n          intentOp: prepareResponse.intentOp,\n          digestResult: prepareResponse.digestResult,\n          binding: prepareResponse.binding,\n          tier: prepareResult.tier,\n          ...(authReady && { auth: authReady }),\n          telemetry: this.telemetryPayload(telemetry),\n        };\n\n        // Narrow update: avoid replaying PASSKEY_INIT, which would rerun broad\n        // dialog initialization and briefly replace the skeleton/preview state\n        // before the authoritative quote-backed transaction lands.\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_QUOTE_READY\", ...currentInitPayload, fullViewport: true, blindSigning },\n          dialogOrigin,\n        );\n\n        if (!sponsor) break;\n\n        const extensionResult = await extensionTokensPromise;\n        if (extensionResult.ok) {\n          const sponsorshipTokens: SponsorshipTokens = {\n            accessToken,\n            extensionTokens: extensionResult.extensionTokens,\n          };\n          currentInitPayload = {\n            ...currentInitPayload,\n            auth: sponsorshipTokens,\n          };\n          iframe.contentWindow?.postMessage(\n            { type: \"PASSKEY_QUOTE_READY\", auth: sponsorshipTokens, fullViewport: true, blindSigning },\n            dialogOrigin,\n          );\n          break;\n        }\n\n        this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n          outcome: \"failure\",\n          errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n          errorMessage: extensionResult.message,\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n            loadingPhase: \"extension_token\",\n          },\n        });\n        this.sendPrepareError(iframe, extensionResult.message);\n        if (blindSigning) {\n          cleanup();\n          return {\n            success: false,\n            intentId: \"\",\n            status: \"failed\",\n            error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n          };\n        }\n        const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n        if (next === \"closed\") {\n          return {\n            success: false,\n            intentId: \"\",\n            status: \"failed\",\n            error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n          };\n        }\n        prepareResult = await retryPrepare();\n      }\n    }\n\n    // 2. Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n    // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n    // so the sign page recovers its state. Uses currentInitPayload which is the\n    // full payload after quote arrives.\n    const handleReReady = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...currentInitPayload, fullViewport: true, blindSigning },\n          dialogOrigin,\n        );\n      }\n    };\n    window.addEventListener(\"message\", handleReReady);\n\n    // 3. Wait for signing result with auto-refresh support\n    // This custom handler handles both signing results AND quote refresh requests.\n    const signingResult = await signingResultPromise;\n\n    window.removeEventListener(\"message\", handleReReady);\n\n    if (!signingResult.success) {\n      this.emitTelemetry(\n        signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"intent.sign.failed\",\n        telemetry,\n        {\n          outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n          ...describeTelemetryError(signingResult.error),\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n          },\n        },\n      );\n      if (blindSigning) cleanup();\n      return {\n        success: false,\n        intentId: \"\", // No intentId yet - signing was cancelled before execute\n        status: \"failed\",\n        error: signingResult.error,\n      };\n    }\n\n    // Check if dialog already executed the intent (new secure flow)\n    // In this case, signingResult contains intentId instead of signature\n    const dialogExecutedIntent = \"intentId\" in signingResult && signingResult.intentId;\n\n    // 5. Execute intent with signature (skip if dialog already executed)\n    let executeResponse: ExecuteIntentResponse;\n\n    if (dialogExecutedIntent) {\n      // Dialog already executed - use the returned intentId\n      executeResponse = {\n        success: true,\n        intentId: signingResult.intentId as string,\n        status: \"pending\",\n      };\n      this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: {\n          accessTokenDurationMs,\n          dialogReadyDurationMs,\n          prepareDurationMs,\n          extensionTokensDurationMs,\n          dialogExecuted: true,\n        },\n      });\n    } else {\n      // Legacy flow - execute with signature from dialog. The extension\n      // token was already fetched in parallel with signing above, so this\n      // just awaits the (usually already-resolved) promise. `accessToken` was\n      // fetched before /prepare, overlapped with the dialog iframe boot.\n      const extensionResult = await extensionTokensPromise;\n      if (!extensionResult.ok) {\n        this.emitTelemetry(\"intent.sign.failed\", telemetry, {\n          outcome: \"failure\",\n          errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n          errorMessage: extensionResult.message,\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n            loadingPhase: \"extension_token\",\n          },\n        });\n        this.sendTransactionStatus(iframe, \"failed\");\n        await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n        return {\n          success: false,\n          intentId: \"\",\n          status: \"failed\",\n          error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n        };\n      }\n      const extensionTokens = extensionResult.extensionTokens;\n      try {\n        this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n          outcome: \"success\",\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n            dialogExecuted: false,\n          },\n        });\n        this.emitTelemetry(\"intent.execute.started\", telemetry, {\n          outcome: \"started\",\n          targetChain: prepareResponse.targetChain,\n          attributes: {\n            accessTokenDurationMs,\n            dialogReadyDurationMs,\n            prepareDurationMs,\n            extensionTokensDurationMs,\n          },\n        });\n        const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {\n          method: \"POST\",\n          headers: {\n            \"Content-Type\": \"application/json\",\n            ...this.telemetryHeaders(telemetry),\n          },\n          body: JSON.stringify({\n            // Data from prepare response (no intentId yet - created on execute)\n            intentOp: prepareResponse.intentOp,\n            userId: prepareResponse.userId,\n            targetChain: prepareResponse.targetChain,\n            calls: prepareResponse.calls,\n            expiresAt: prepareResponse.expiresAt,\n            digestResult: prepareResponse.digestResult,\n            // Opaque prepare->execute binding, forwarded unchanged.\n            binding: prepareResponse.binding,\n            // Signature from dialog\n            signature: signingResult.signature,\n            passkey: requireSigningPasskeyCredentials(signingResult.passkey),\n            // App JWT — `accessToken` is always present. `extensionToken` is\n            // only included when sponsorship was requested (sponsor !== false).\n            auth: {\n              accessToken,\n              ...(extensionTokens.length > 0 && {\n                extensionToken: extensionTokens[0],\n              }),\n            },\n          }),\n        });\n\n        if (!response.ok) {\n          const errorData = await response.json().catch(() => ({}));\n          // Send failure status to dialog\n          this.sendTransactionStatus(iframe, \"failed\");\n          await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n          this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n            outcome: \"failure\",\n            targetChain: prepareResponse.targetChain,\n            errorCode: executeErrorCode(errorData),\n            errorMessage: errorData.error || \"Failed to execute intent\",\n          });\n          return {\n            success: false,\n            intentId: \"\", // No intentId - execute failed before creation\n            status: \"failed\",\n            error: {\n              code: executeErrorCode(errorData),\n              message: errorData.error || \"Failed to execute intent\",\n              details: executeErrorDetails(errorData.debug),\n            },\n          };\n        }\n\n        executeResponse = await response.json();\n        this.emitTelemetry(\"intent.execute.succeeded\", telemetry, {\n          outcome: \"success\",\n          targetChain: prepareResponse.targetChain,\n          status: executeResponse.status,\n        });\n      } catch (error) {\n        // Send failure status to dialog\n        this.sendTransactionStatus(iframe, \"failed\");\n        await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n        this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n          outcome: \"failure\",\n          targetChain: prepareResponse.targetChain,\n          ...describeTelemetryError(error),\n        });\n        return {\n          success: false,\n          intentId: \"\", // No intentId - network error before creation\n          status: \"failed\",\n          error: {\n            code: \"NETWORK_ERROR\",\n            message: error instanceof Error ? error.message : \"Network error\",\n          },\n        };\n      }\n    }\n\n    // 6. Poll for completion with status updates to dialog\n    let finalStatus = executeResponse.status;\n    let finalTxHash = executeResponse.transactionHash;\n\n    if (finalStatus === \"pending\") {\n      // Send initial pending status to dialog\n      this.sendTransactionStatus(iframe, \"pending\");\n      this.emitTelemetry(\"intent.status.started\", telemetry, {\n        outcome: \"started\",\n        status: finalStatus,\n      });\n\n      // Listen for early close (user clicking X) during polling.\n      // Close the dialog immediately so the user gets instant feedback.\n      let userClosedEarly = false;\n      const dialogOrigin = this.getDialogOrigin();\n      const earlyCloseHandler = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        // Scope to this dialog's iframe so a same-origin CLOSE from another\n        // 1auth dialog (e.g. a queued auth-modal teardown) can't be\n        // misattributed to this poll and cancel it. Mirrors the early-close\n        // watcher above and the modal auth listener's source guard.\n        if (\n          event.data?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          userClosedEarly = true;\n          cleanup();\n        }\n      };\n      window.addEventListener(\"message\", earlyCloseHandler);\n\n      // Poll status endpoint for updates\n      const maxAttempts = 120; // 3 minutes at 1.5s intervals\n      const pollIntervalMs = 1500;\n      let lastStatus = \"pending\";\n\n      for (let attempt = 0; attempt < maxAttempts; attempt++) {\n        if (userClosedEarly) break;\n\n        try {\n          const statusResponse = await fetch(\n            `${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,\n            {\n              method: \"GET\",\n              headers: {\n                ...this.telemetryHeaders(telemetry),\n                ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n              },\n            }\n          );\n\n          if (statusResponse.ok) {\n            const statusResult = await statusResponse.json();\n            finalStatus = statusResult.status;\n            finalTxHash = statusResult.transactionHash;\n\n            // Send status update to dialog if changed\n            if (finalStatus !== lastStatus) {\n              this.sendTransactionStatus(iframe, finalStatus, finalTxHash);\n              lastStatus = finalStatus;\n            }\n\n            // Exit if terminal status reached\n            // closeOn determines when to consider the intent successful (default: preconfirmed)\n            const closeOn = options.closeOn || \"preconfirmed\";\n            const successStatuses: Record<string, string[]> = {\n              claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n              preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n              filled: [\"filled\", \"completed\"],\n              completed: [\"completed\"],\n            };\n            const isTerminal = finalStatus === \"failed\" || finalStatus === \"expired\";\n            const isSuccess = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n            if (isTerminal || isSuccess) {\n              break;\n            }\n          }\n        } catch (pollError) {\n          console.error(\"Failed to poll intent status:\", pollError);\n        }\n\n        // Wait before next poll\n        await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n      }\n\n      window.removeEventListener(\"message\", earlyCloseHandler);\n\n      // If user closed during polling, clean up and return current status\n      if (userClosedEarly) {\n        cleanup();\n        this.emitTelemetry(\"intent.status.failed\", telemetry, {\n          outcome: \"cancelled\",\n          status: finalStatus,\n          errorCode: \"USER_CANCELLED\",\n          errorMessage: \"User closed the dialog while status polling\",\n        });\n        return {\n          success: false,\n          intentId: executeResponse.intentId,\n          status: finalStatus,\n          transactionHash: finalTxHash,\n          operationId: executeResponse.operationId,\n          error: {\n            code: \"USER_CANCELLED\",\n            message: \"User closed the dialog\",\n          },\n        };\n      }\n    }\n\n    // 7. Send final status to dialog\n    // Map successful statuses to \"confirmed\" based on closeOn setting\n    const closeOn = options.closeOn || \"preconfirmed\";\n    const successStatuses: Record<string, string[]> = {\n      claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n      preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n      filled: [\"filled\", \"completed\"],\n      completed: [\"completed\"],\n    };\n    const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n    const displayStatus = isSuccessStatus ? \"confirmed\" : finalStatus;\n\n    // Start listening for close BEFORE sending status to avoid race condition\n    // where user clicks Done before the listener is registered\n    const closePromise = this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n    this.sendTransactionStatus(iframe, displayStatus, finalTxHash);\n\n    // Wait for dialog to be closed by user\n    await closePromise;\n\n    if (options.waitForHash && !finalTxHash) {\n      const hash = await this.waitForTransactionHash(executeResponse.intentId, {\n        timeoutMs: options.hashTimeoutMs,\n        intervalMs: options.hashIntervalMs,\n      }, telemetry);\n      if (hash) {\n        finalTxHash = hash;\n        finalStatus = \"completed\";\n      } else {\n        finalStatus = \"failed\";\n        this.emitTelemetry(\"intent.status.failed\", telemetry, {\n          outcome: \"failure\",\n          status: finalStatus,\n          errorCode: \"HASH_TIMEOUT\",\n          errorMessage: \"Timed out waiting for transaction hash\",\n        });\n        return {\n          success: false,\n          intentId: executeResponse.intentId,\n          status: finalStatus,\n          transactionHash: finalTxHash,\n          operationId: executeResponse.operationId,\n          error: {\n            code: \"HASH_TIMEOUT\",\n            message: \"Timed out waiting for transaction hash\",\n          },\n        };\n      }\n    }\n\n    this.emitTelemetry(\"intent.status.succeeded\", telemetry, {\n      outcome: isSuccessStatus ? \"success\" : \"failure\",\n      status: finalStatus,\n    });\n    this.emitTelemetry(\"intent.completed\", telemetry, {\n      outcome: isSuccessStatus ? \"success\" : \"failure\",\n      status: finalStatus,\n      targetChain,\n    });\n\n    return {\n      success: isSuccessStatus,\n      intentId: executeResponse.intentId,\n      status: finalStatus,\n      transactionHash: finalTxHash,\n      operationId: executeResponse.operationId,\n      error: executeResponse.error,\n    };\n  }\n\n  /**\n   * Send a batch of intents for multi-chain execution with a single passkey tap.\n   *\n   * This method prepares multiple intents, shows a paginated review,\n   * and signs all intents with a single passkey tap via a shared merkle tree.\n   *\n   * @example\n   * ```typescript\n   * const result = await client.sendBatchIntent({\n   *   accountAddress: '0x...',\n   *   intents: [\n   *     {\n   *       targetChain: 8453, // Base\n   *       calls: [{ to: '0x...', data: '0x...', label: 'Swap on Base' }],\n   *     },\n   *     {\n   *       targetChain: 42161, // Arbitrum\n   *       calls: [{ to: '0x...', data: '0x...', label: 'Mint on Arbitrum' }],\n   *     },\n   *   ],\n   * });\n   *\n   * if (result.success) {\n   *   console.log(`${result.successCount} intents submitted`);\n   * }\n   * ```\n   */\n  async sendBatchIntent(options: SendBatchIntentOptions): Promise<SendBatchIntentResult> {\n    const telemetry = this.createTelemetryOperation(\"batch_intent\", {\n      intentCount: options.intents?.length ?? 0,\n      blindSigning: this.shouldRequestBlindSigning(options),\n    });\n    if (getStoredSignerType() === \"eoa\") {\n      this.emitTelemetry(\"batch.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"E_SIGNER_UNSUPPORTED\",\n        errorMessage: \"Batch intents are not supported for EOA sessions\",\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n        error:\n          \"Batch intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n      };\n    }\n\n    if (!options.accountAddress) {\n      this.emitTelemetry(\"batch.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"accountAddress is required\",\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n      };\n    }\n\n    if (!options.intents?.length) {\n      this.emitTelemetry(\"batch.completed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"INVALID_OPTIONS\",\n        errorMessage: \"At least one intent is required\",\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n      };\n    }\n\n    if (!this.sponsorship) {\n      this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"MISSING_APP_CREDENTIALS\",\n        errorMessage: \"No sponsorship configured on OneAuthClient\",\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n        error:\n          \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n      };\n    }\n\n    const sponsorshipModes = options.intents.map((intent) => this.resolveSponsorshipMode(intent));\n\n    // Fetch the app's access token up front — /api/intent/batch-prepare\n    // requires it so the passkey server can authenticate its orchestrator\n    // quote calls with the app's JWT instead of a service-level API key.\n    const accessTokenResult = await this.fetchAccessToken();\n    if (!accessTokenResult.ok) {\n      this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n        errorMessage: accessTokenResult.message,\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n      };\n    }\n    // Mutable: a quote refresh re-mints the token and must keep the execute\n    // path's auth aligned with the refreshed quotes.\n    let accessToken = accessTokenResult.accessToken;\n\n    // Serialize token request amounts to strings for API. Each intent's\n    // labels are capped via capCallLabels() so the dialog's phase-1 preview\n    // (which reads from serializedIntents below) and the prepare request\n    // both ship the same truncated strings.\n    const serializedIntents = options.intents.map((intent) => ({\n      targetChain: intent.targetChain,\n      calls: capCallLabels(intent.calls),\n      tokenRequests: intent.tokenRequests?.map((r) => ({\n        token: r.token,\n        amount: r.amount.toString(),\n      })),\n      sourceAssets: intent.sourceAssets,\n      sourceChainId: intent.sourceChainId,\n      moduleInstall: intent.moduleInstall,\n    }));\n\n    const requestBody = {\n      ...(options.accountAddress && { accountAddress: options.accountAddress }),\n      intents: serializedIntents,\n      auth: { accessToken },\n      ...(this.config.clientId && { clientId: this.config.clientId }),\n    };\n\n    // 1. Show dialog immediately + prepare batch in parallel.\n    //\n    // Same two-phase approach as sendIntent: open the dialog right away with\n    // raw call data so the user sees something immediately, then upgrade to the\n    // full quote payload once batch-prepare completes. See sendIntent for the\n    // full rationale.\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams();\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n    const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n    const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n      hidden: requestedBlindSigning,\n    });\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      intentCount: options.intents.length,\n      attributes: { blindSigning: requestedBlindSigning },\n    });\n\n    const dialogOrigin = this.getDialogOrigin();\n\n    type BatchPrepareResult =\n      | { success: true; data: PrepareBatchIntentResponse; tier: string | null; extensionTokens: string[] }\n      | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> };\n    let earlyBatchResult: BatchPrepareResult | null = null;\n    this.emitTelemetry(\"batch.prepare.started\", telemetry, {\n      outcome: \"started\",\n      intentCount: options.intents.length,\n      targetChains: serializedIntents.map((intent) => intent.targetChain),\n    });\n    const preparePromise = this.prepareBatchWithFunding(requestBody, sponsorshipModes, telemetry).then((r) => {\n      earlyBatchResult = r;\n      if (r.success) {\n        this.emitTelemetry(\"batch.prepare.succeeded\", telemetry, {\n          outcome: \"success\",\n          intentCount: r.data.intents.length,\n          targetChains: serializedIntents.map((intent) => intent.targetChain),\n        });\n      } else {\n        this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n          outcome: \"failure\",\n          errorMessage: r.error,\n          intentCount: options.intents.length,\n        });\n      }\n      return r;\n    });\n\n    // Wait for iframe to be ready\n    const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n      blindSigning: requestedBlindSigning,\n      reveal,\n    });\n\n    // Handle dialog closed before ready\n    if (!dialogResult.ready) {\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_CANCELLED\",\n        errorMessage: \"User closed the dialog before it became ready\",\n      });\n      return {\n        success: false,\n        results: [],\n        successCount: 0,\n        failureCount: 0,\n      };\n    }\n    const blindSigning = dialogResult.blindSigning;\n    this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n    // Mutable init payload — starts as early preview, upgraded to full after quote\n    let currentBatchPayload: Record<string, unknown>;\n\n    // Helper to handle batch prepare failure\n    const handleBatchPrepareFailure = async (\n      prepareResult: Extract<BatchPrepareResult, { success: false }>,\n    ) => {\n      const failedIntents = prepareResult.failedIntents;\n      const failureResults: import(\"./types\").BatchIntentItemResult[] = failedIntents?.map((f) => ({\n        index: f.index,\n        success: false,\n        intentId: \"\",\n        status: \"failed\" as import(\"./types\").IntentStatus,\n        error: { message: f.error, code: \"PREPARE_FAILED\" },\n      })) ?? [];\n\n      this.sendPrepareError(iframe, prepareResult.error);\n      await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n      return {\n        success: false as const,\n        results: failureResults,\n        successCount: 0,\n        failureCount: failureResults.length,\n        error: prepareResult.error,\n      };\n    };\n\n\n    let prepareResponse: PrepareBatchIntentResponse;\n\n    if (earlyBatchResult) {\n      // Fast path: batch-prepare already finished — send full PASSKEY_INIT\n      const prepareResult = earlyBatchResult as BatchPrepareResult;\n      if (!prepareResult.success) {\n        return handleBatchPrepareFailure(prepareResult);\n      }\n      prepareResponse = prepareResult.data;\n      const batchSponsorshipTokens: SponsorshipTokens = {\n        accessToken,\n        extensionTokens: prepareResult.extensionTokens,\n      };\n      currentBatchPayload = {\n        mode: \"iframe\",\n        batchMode: true,\n        batchIntents: prepareResponse.intents,\n        batchFailedIntents: prepareResponse.failedIntents,\n        challenge: prepareResponse.challenge,\n        binding: prepareResponse.binding,\n        accountAddress: prepareResponse.accountAddress,\n        userId: prepareResponse.userId,\n        expiresAt: prepareResponse.expiresAt,\n        tier: prepareResult.tier,\n        auth: batchSponsorshipTokens,\n        telemetry: this.telemetryPayload(telemetry),\n      };\n      dialogResult.sendInit(currentBatchPayload);\n    } else {\n      // Progressive path: send early preview with raw intent calls\n      currentBatchPayload = {\n        mode: \"iframe\",\n        batchMode: true,\n        batchIntents: serializedIntents.map((intent, idx) => ({\n          index: idx,\n          targetChain: intent.targetChain,\n          calls: JSON.stringify(intent.calls),\n          // No: transaction, intentOp, expiresAt, originMessages\n        })),\n        accountAddress: options.accountAddress,\n        telemetry: this.telemetryPayload(telemetry),\n      };\n      dialogResult.sendInit(currentBatchPayload);\n\n      // Wait for batch-prepare to complete, then send quote data\n      const prepareResult = await preparePromise;\n      if (!prepareResult.success) {\n        return handleBatchPrepareFailure(prepareResult);\n      }\n      prepareResponse = prepareResult.data;\n      const batchSponsorshipTokens: SponsorshipTokens = {\n        accessToken,\n        extensionTokens: prepareResult.extensionTokens,\n      };\n\n      // Upgrade the payload with full quote data\n      currentBatchPayload = {\n        mode: \"iframe\",\n        batchMode: true,\n        batchIntents: prepareResponse.intents,\n        batchFailedIntents: prepareResponse.failedIntents,\n        challenge: prepareResponse.challenge,\n        binding: prepareResponse.binding,\n        accountAddress: prepareResponse.accountAddress,\n        userId: prepareResponse.userId,\n        expiresAt: prepareResponse.expiresAt,\n        tier: prepareResult.tier,\n        auth: batchSponsorshipTokens,\n        telemetry: this.telemetryPayload(telemetry),\n      };\n\n      // Re-send as PASSKEY_INIT so all dialog versions handle it\n      iframe.contentWindow?.postMessage(\n        { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n        dialogOrigin,\n      );\n    }\n\n    // 2. Handle iframe remount: resend PASSKEY_INIT on subsequent PASSKEY_READY\n    const handleBatchReReady = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n          dialogOrigin,\n        );\n      }\n    };\n    window.addEventListener(\"message\", handleBatchReReady);\n\n    // 3. Wait for batch signing result with auto-refresh support\n    const batchResult = await new Promise<SendBatchIntentResult>((resolve) => {\n      const handleMessage = async (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const message = event.data;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tcleanup();\n\t\t\tthis.emitTelemetry(\"dialog.cancelled\", telemetry, {\n\t\t\t\toutcome: \"cancelled\",\n\t\t\t\terrorCode: \"USER_REJECTED\",\n\t\t\t\terrorMessage: \"Session disconnected\",\n\t\t\t});\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\tresults: [],\n\t\t\t\tsuccessCount: 0,\n\t\t\t\tfailureCount: 0,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        // Handle quote refresh request\n        if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n          try {\n            // Re-mint the app access token — refreshes fire after the user\n            // lingered on review, so the token in `requestBody` may have\n            // crossed its 1h expiry (orchestrator would 401 the re-quote).\n            const refreshedTokenResult = await this.fetchAccessToken();\n            const refreshToken = refreshedTokenResult.ok\n              ? refreshedTokenResult.accessToken\n              : accessToken;\n            const refreshResult = await this.prepareBatchWithFunding(\n              { ...requestBody, auth: { accessToken: refreshToken } },\n              sponsorshipModes,\n              telemetry,\n            );\n\n            if (refreshResult.success) {\n              const refreshed = refreshResult.data;\n              const refreshedAuth: SponsorshipTokens = {\n                accessToken: refreshToken,\n                extensionTokens: refreshResult.extensionTokens,\n              };\n\n              prepareResponse = refreshed;\n              accessToken = refreshToken;\n              requestBody.auth = { accessToken: refreshToken };\n              // Keep iframe-remount replays on the refreshed quotes + auth.\n              currentBatchPayload = {\n                ...currentBatchPayload,\n                batchIntents: refreshed.intents,\n                batchFailedIntents: refreshed.failedIntents,\n                challenge: refreshed.challenge,\n                binding: refreshed.binding,\n                expiresAt: refreshed.expiresAt,\n                auth: refreshedAuth,\n              };\n              iframe.contentWindow?.postMessage({\n                type: \"PASSKEY_REFRESH_COMPLETE\",\n                batchIntents: refreshed.intents,\n                challenge: refreshed.challenge,\n                binding: refreshed.binding,\n                expiresAt: refreshed.expiresAt,\n                auth: refreshedAuth,\n              }, dialogOrigin);\n            } else {\n              iframe.contentWindow?.postMessage({\n                type: \"PASSKEY_REFRESH_ERROR\",\n                error: \"Failed to refresh batch quotes\",\n              }, dialogOrigin);\n            }\n          } catch {\n            iframe.contentWindow?.postMessage({\n              type: \"PASSKEY_REFRESH_ERROR\",\n              error: \"Failed to refresh batch quotes\",\n            }, dialogOrigin);\n          }\n          return;\n        }\n\n        // Handle signing result with batch results\n        if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n          window.removeEventListener(\"message\", handleMessage);\n\n          if (message.success && message.data?.batchResults) {\n            const rawResults: Array<{\n              index: number;\n              operationId?: string;\n              intentId?: string;\n              status: string;\n              error?: string;\n              success?: boolean;\n            }> = message.data.batchResults;\n\n            const results: BatchIntentItemResult[] = rawResults.map((r) => ({\n              index: r.index,\n              success: r.success ?? r.status !== \"FAILED\",\n              intentId: r.intentId || r.operationId || \"\",\n              status: r.status === \"FAILED\" ? \"failed\" : \"pending\",\n              error: r.error ? { code: \"EXECUTE_FAILED\", message: r.error } : undefined,\n            }));\n\n            // Merge in prepare-phase failures (e.g. account not deployed on chain).\n            // These intents never reached the dialog (they were filtered out before\n            // the signing screen), so we re-attach them here to give callers a\n            // complete, index-sorted result set covering every input intent.\n            const prepareFailures: BatchIntentItemResult[] = (prepareResponse.failedIntents ?? []).map((f) => ({\n              index: f.index,\n              success: false,\n              intentId: \"\",\n              status: \"failed\" as const,\n              error: { code: \"PREPARE_FAILED\", message: f.error },\n            }));\n            const allResults = [...results, ...prepareFailures].sort((a, b) => a.index - b.index);\n\n            const successCount = allResults.filter((r) => r.success).length;\n\n            await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n            this.emitTelemetry(\"batch.sign.succeeded\", telemetry, {\n              outcome: \"success\",\n              intentCount: allResults.length,\n            });\n\n            resolve({\n              success: successCount === allResults.length,\n              results: allResults,\n              successCount,\n              failureCount: allResults.length - successCount,\n            });\n          } else {\n            // Signing failed or was cancelled\n            cleanup();\n            this.emitTelemetry(\"batch.sign.failed\", telemetry, {\n              outcome: \"failure\",\n              errorCode: \"SIGNING_FAILED\",\n              errorMessage: \"Batch signing failed or was cancelled\",\n            });\n            resolve({\n              success: false,\n              results: [],\n              successCount: 0,\n              failureCount: 0,\n            });\n          }\n        }\n\n        // Handle dialog close\n        if (message?.type === \"PASSKEY_CLOSE\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n            outcome: \"cancelled\",\n            errorCode: \"USER_CANCELLED\",\n            errorMessage: \"User closed the batch dialog\",\n          });\n          resolve({\n            success: false,\n            results: [],\n            successCount: 0,\n            failureCount: 0,\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n\n    window.removeEventListener(\"message\", handleBatchReReady);\n\n    this.emitTelemetry(\"batch.completed\", telemetry, {\n      outcome: batchResult.success ? \"success\" : \"failure\",\n      intentCount: batchResult.results.length,\n      attributes: {\n        successCount: batchResult.successCount,\n        failureCount: batchResult.failureCount,\n      },\n      ...(batchResult.error ? { errorMessage: batchResult.error } : {}),\n    });\n\n    return batchResult;\n  }\n\n  /**\n   * Send transaction status to the dialog iframe\n   */\n  private sendTransactionStatus(\n    iframe: HTMLIFrameElement,\n    status: string,\n    transactionHash?: string\n  ): void {\n    const dialogOrigin = this.getDialogOrigin();\n    iframe.contentWindow?.postMessage(\n      {\n        type: \"TRANSACTION_STATUS\",\n        status,\n        transactionHash,\n      },\n      dialogOrigin\n    );\n  }\n\n  /**\n   * Listen for a signing result that belongs to a specific `requestId`.\n   *\n   * Used by legacy server-side signing request flows (popup/embed/modal) where\n   * the dialog was pre-loaded with a signing request created via the API. The\n   * `requestId` filter is needed because multiple dialogs may be open or there\n   * may be stale messages from a previous dialog in the queue.\n   *\n   * Resolves on `PASSKEY_SIGNING_RESULT` matching `requestId`, or on\n   * `PASSKEY_CLOSE` (user dismissed the dialog).\n   *\n   * @param requestId - The signing request ID to match against incoming messages.\n   * @param dialog - The `<dialog>` element (opened before this call) used to\n   *   `showModal()` so the dialog becomes interactive.\n   * @param _iframe - Unused; kept for signature consistency with other wait helpers.\n   * @param cleanup - Idempotent teardown function that closes and removes the dialog.\n   * @returns A `SigningResult` discriminated union.\n   */\n  private waitForIntentSigningResponse(\n    requestId: string,\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void\n  ): Promise<SigningResult> {\n    const dialogOrigin = this.getDialogOrigin();\n\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const message = event.data;\n        const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature; passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string; keyId: number } } | undefined;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tcleanup();\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"USER_REJECTED\", message: \"Session disconnected\" },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n          window.removeEventListener(\"message\", handleMessage);\n\n          if (message.success && payload.signature) {\n            resolve({\n              success: true,\n              requestId,\n              signature: payload.signature,\n              passkey: payload.passkey, // Include passkey info for signature encoding\n            });\n          } else {\n            resolve({\n              success: false,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        } else if (\n          message?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // User clicked X button to close/reject. Cross-frame guard: ignore a\n          // stray PASSKEY_CLOSE from a sibling same-origin dialog so it can't\n          // forge a rejection of this signing request.\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            error: {\n              code: \"USER_REJECTED\",\n              message: \"User closed the dialog\",\n            },\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.showModal();\n    });\n  }\n\n  /**\n   * Listen for a signing result from the currently open modal dialog.\n   *\n   * Unlike `waitForIntentSigningResponse`, this variant does not filter by\n   * `requestId` because the inline intent flow (sendIntent / signMessage /\n   * signTypedData) owns the dialog exclusively — there is no risk of collisions\n   * from other dialogs.\n   *\n   * Handles two result shapes:\n   *   - New \"secure flow\": dialog executed the intent server-side and returns\n   *     only an `intentId` (no signature exposed to the SDK).\n   *   - Legacy flow: dialog returns a raw `WebAuthnSignature` for the SDK to\n   *     forward to the execute endpoint.\n   *\n   * @param dialog - The `<dialog>` element wrapping the signing iframe.\n   * @param iframe - The signing iframe; used to authenticate the source of\n   *   `PASSKEY_CLOSE` so a sibling same-origin dialog can't forge a rejection.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   * @returns A `SigningResult` extended with an optional `signedHash` field\n   *   populated when the dialog performs message signing.\n   */\n  private waitForSigningResponse(\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void\n  ): Promise<SigningResult & { signedHash?: string }> {\n    const dialogOrigin = this.getDialogOrigin();\n\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const message = event.data;\n        const payload = message?.data as { signature?: WebAuthnSignature; passkey?: PasskeyCredentials; signedHash?: string; intentId?: string } | undefined;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tcleanup();\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"USER_REJECTED\", message: \"Session disconnected\" },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n          window.removeEventListener(\"message\", handleMessage);\n\n          // Check if dialog already executed the intent (new secure flow)\n          if (message.success && payload?.intentId) {\n            resolve({\n              success: true,\n              intentId: payload.intentId,\n            } as SigningResult & { signedHash?: string; intentId?: string });\n          } else if (message.success && payload?.signature) {\n            // Legacy flow - dialog returns signature for SDK to execute\n            resolve({\n              success: true,\n              signature: payload.signature,\n              passkey: payload.passkey,\n              signedHash: payload.signedHash,\n            });\n          } else {\n            // Failure path: tear the iframe down here. The passkey app\n            // sends `PASSKEY_SIGNING_RESULT(false)` then `PASSKEY_CLOSE`\n            // back-to-back on cancel, but we've just removed the\n            // listener so the follow-up CLOSE would be dropped, leaving\n            // the dialog stuck open.\n            cleanup();\n            resolve({\n              success: false,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        } else if (\n          message?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n          // same-origin dialog (e.g. an auth modal tearing down) so it can't\n          // forge a rejection of this signing request.\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            error: {\n              code: \"USER_REJECTED\",\n              message: \"User closed the dialog\",\n            },\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Listen for a signing result while also handling quote-refresh requests.\n   *\n   * Quotes from the Rhinestone orchestrator have a short TTL (typically ~60 s).\n   * When the user takes too long to review and the quote expires, the dialog\n   * sends `PASSKEY_REFRESH_QUOTE`. This method intercepts that message, calls\n   * the provided `onRefresh` callback to fetch a new quote, and replies with\n   * either `PASSKEY_REFRESH_COMPLETE` (success) or `PASSKEY_REFRESH_ERROR`\n   * (failure) — allowing the dialog to stay open and show the updated fees\n   * without requiring a full restart.\n   *\n   * Once the user confirms or rejects, the promise resolves with the signing\n   * result exactly as `waitForSigningResponse` would.\n   *\n   * @param dialog - The `<dialog>` element wrapping the signing iframe.\n   * @param iframe - The iframe element; used to post refresh messages back.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   * @param dialogOrigin - Trusted origin for message validation (passed in to\n   *   avoid redundant `getDialogOrigin()` calls from the hot path).\n   * @param onRefresh - Async callback that fetches a fresh quote and returns the\n   *   updated intent fields, or `null` if the refresh failed.\n   * @returns A `SigningResult` extended with an optional `signedHash`.\n   */\n  private waitForSigningWithRefresh(\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    dialogOrigin: string,\n    onRefresh: () => Promise<{\n      intentOp: string;\n      expiresAt: string;\n      challenge: string;\n      originMessages?: Array<{ chainId: number; hash: string }>;\n      transaction?: unknown;\n      digestResult?: unknown;\n      /** Fresh prepare->execute binding for the refreshed quote (opaque). */\n      binding?: string;\n      /** Auth bundle re-bound to the refreshed intentOp — extension grants\n          are digest-bound, so the dialog must swap auth with the quote. */\n      auth?: SponsorshipTokens;\n    } | null>\n  ): Promise<SigningResult & { signedHash?: string }> {\n    return new Promise((resolve) => {\n      const handleMessage = async (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const message = event.data;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tcleanup();\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\terror: { code: \"USER_REJECTED\", message: \"Session disconnected\" },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        // Handle quote refresh request from dialog\n        if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n          const refreshedData = await onRefresh();\n\n          if (refreshedData) {\n            // Send refreshed quote data to dialog\n            iframe.contentWindow?.postMessage({\n              type: \"PASSKEY_REFRESH_COMPLETE\",\n              ...refreshedData,\n            }, dialogOrigin);\n          } else {\n            // Send error if refresh failed\n            iframe.contentWindow?.postMessage({\n              type: \"PASSKEY_REFRESH_ERROR\",\n              error: \"Failed to refresh quote\",\n            }, dialogOrigin);\n          }\n          return;\n        }\n\n        const payload = message?.data as {\n          signature?: WebAuthnSignature;\n          passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string; keyId: number };\n          signedHash?: string;\n          intentId?: string;\n        } | undefined;\n\n        if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n          window.removeEventListener(\"message\", handleMessage);\n\n          // Check if dialog already executed the intent (new secure flow)\n          if (message.success && payload?.intentId) {\n            resolve({\n              success: true,\n              intentId: payload.intentId,\n            } as SigningResult & { signedHash?: string; intentId?: string });\n          } else if (message.success && payload?.signature) {\n            // Legacy flow - dialog returns signature for SDK to execute\n            resolve({\n              success: true,\n              signature: payload.signature,\n              passkey: payload.passkey,\n              signedHash: payload.signedHash,\n            });\n          } else {\n            // Failure path: close the iframe. The passkey app sends the\n            // follow-up `PASSKEY_CLOSE` after this `RESULT`, but we've just\n            // removed the listener so it would be dropped on the floor —\n            // tear down here so the user isn't stuck staring at a dialog\n            // that's already done.\n            cleanup();\n            resolve({\n              success: false,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        } else if (\n          message?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n          // same-origin dialog so it can't forge a rejection of this signing\n          // request mid-refresh.\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            error: {\n              code: \"USER_REJECTED\",\n              message: \"User closed the dialog\",\n            },\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Wait for the dialog to be explicitly closed by the user or the iframe.\n   *\n   * Resolves on either:\n   *   - `PASSKEY_CLOSE` postMessage from the iframe (user clicked the X button\n   *     or the dialog programmatically closed itself after showing a result).\n   *   - The native `<dialog> close` event (escape key or `dialog.close()` call).\n   *\n   * Calling `cleanup()` before awaiting this is safe — both resolution paths\n   * call `cleanup()` internally but it is idempotent. The primary use case is\n   * keeping the dialog open while the SDK polls for a transaction hash, then\n   * showing the final success/error state before letting the user dismiss.\n   *\n   * @param dialog - The `<dialog>` element to watch.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   */\n  private waitForDialogClose(\n    dialog: HTMLDialogElement,\n    cleanup: () => void\n  ): Promise<void> {\n    const dialogOrigin = this.getDialogOrigin();\n\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        if (event.data?.type === \"PASSKEY_CLOSE\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve();\n        }\n      };\n\n      // Also handle dialog close via escape key or clicking outside\n      const handleClose = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n        cleanup();\n        resolve();\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Hidden blind-signing iframes have no user-visible Done or Close button.\n   * Once the SDK has the result it needs, tear them down immediately instead\n   * of waiting for an iframe close event that can never be clicked.\n   */\n  private async waitForDialogCloseUnlessBlind(\n    blindSigning: boolean,\n    dialog: HTMLDialogElement,\n    cleanup: () => void,\n  ): Promise<void> {\n    if (blindSigning) {\n      cleanup();\n      return;\n    }\n    await this.waitForDialogClose(dialog, cleanup);\n  }\n\n  /**\n   * After a prepare error has been surfaced in the dialog, wait for the user\n   * to either close the dialog (give up) or click \"Try Again\", which the\n   * dialog forwards as `PASSKEY_RETRY_PREPARE`.\n   *\n   * On `\"closed\"` the dialog has been cleaned up; on `\"retry\"` it stays open\n   * (showing its loading skeleton) while the caller re-runs prepare. Without\n   * this, \"Try Again\" after a prepare failure was a dead end: the dialog\n   * reset its local state but the SDK had already given up, so the quote\n   * never arrived and the Sign button stayed disabled forever.\n   */\n  private waitForPrepareRetryOrClose(\n    dialog: HTMLDialogElement,\n    cleanup: () => void,\n  ): Promise<\"retry\" | \"closed\"> {\n    const dialogOrigin = this.getDialogOrigin();\n\n    return new Promise((resolve) => {\n      const stop = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n      };\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        if (event.data?.type === \"PASSKEY_RETRY_PREPARE\") {\n          stop();\n          resolve(\"retry\");\n        } else if (event.data?.type === \"PASSKEY_CLOSE\") {\n          stop();\n          cleanup();\n          resolve(\"closed\");\n        }\n      };\n\n      // Also handle dialog close via escape key or clicking outside\n      const handleClose = () => {\n        stop();\n        cleanup();\n        resolve(\"closed\");\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Inject a `<link rel=\"preconnect\">` tag for the given URL's origin.\n   *\n   * Browsers use preconnect hints to resolve DNS, perform the TCP handshake,\n   * and negotiate TLS before a resource is actually requested, reducing\n   * time-to-first-byte when the dialog iframe loads. The tag is deduplicated —\n   * if one already exists for the same origin it will not be added again.\n   *\n   * Only called in browser environments (guarded by `typeof document` in the\n   * constructor). Invalid URLs are silently ignored.\n   *\n   * @param url - Any URL whose origin should be preconnected to.\n   */\n  private injectPreconnect(url: string): void {\n    try {\n      const origin = new URL(url).origin;\n      if (document.querySelector(`link[rel=\"preconnect\"][href=\"${origin}\"]`)) return;\n      const link = document.createElement(\"link\");\n      link.rel = \"preconnect\";\n      link.href = origin;\n      link.crossOrigin = \"anonymous\";\n      document.head.appendChild(link);\n    } catch {\n      // Invalid URL, skip\n    }\n  }\n\n  /**\n   * Warm the dialog ahead of the first user interaction.\n   *\n   * `preconnect` (run in the constructor) only warms DNS/TLS. This goes\n   * further: it loads the dialog into a hidden, off-screen iframe so the\n   * browser downloads and parses the dialog HTML + JS bundle and the font, and\n   * keeps the cross-origin connection alive. When the user later opens a real\n   * auth/sign dialog, the fresh iframe serves those bytes from cache over the\n   * warm connection and paints far sooner — so the SDK preload overlay is shown\n   * only briefly (or imperceptibly) instead of covering a full cold load.\n   *\n   * It loads a dedicated `/dialog/warm` route, NOT a real flow route. That\n   * matters for two reasons:\n   *   - **No side effects.** The real `/dialog/auth` route runs the signup\n   *     flow on mount (identity probe → `POST /api/auth/register?step=start`),\n   *     which writes an `AuthChallenge` row and counts against the register\n   *     rate limiter. Warming must never create backend auth state for a user\n   *     who hasn't acted, so the warm route renders nothing and runs no flow.\n   *   - **No message cross-talk.** The warm route posts no `PASSKEY_READY` /\n   *     `PASSKEY_RENDERED`, so a slow warm can never satisfy a visible modal's\n   *     readiness listener and drive it to `PASSKEY_INIT` at the wrong moment.\n   * The warm route still pulls the shared Next.js framework + main + dialog\n   * layout chunks (the bulk of every flow's bundle), so the real open is fast.\n   *\n   * Best called on a *likely-intent* signal — `pointerenter`/`focus` of your\n   * \"Sign in\" / \"Pay\" button — rather than on page load, so visitors who never\n   * authenticate don't pay for a cross-origin iframe. Pass `prewarm: true` in\n   * the client config to have the SDK schedule this once on an idle callback.\n   *\n   * Idempotent: repeated calls return the same in-flight/settled promise.\n   * Resolves `true` once the hidden iframe's document has loaded, `false` on\n   * timeout or failure. Never throws and never blocks a real dialog open — a\n   * failed prewarm just means the next open does a normal (cold) load.\n   *\n   * @returns Whether the dialog became warm.\n   */\n  async prewarm(): Promise<boolean> {\n    if (typeof document === \"undefined\") return false;\n    // Idempotent: a second call (e.g. hover after an idle-scheduled warm)\n    // rides the first one's load instead of opening another iframe.\n    if (this.prewarmState) return this.prewarmState.ready;\n\n    // Dedicated warm route — silent for modal readiness, but it can emit a\n    // deployment-forced disconnect. Pin the host origin in the URL because\n    // privacy policies may strip document.referrer and prewarm never sends\n    // PASSKEY_INIT to authenticate a postMessage origin later.\n    const warmParams = new URLSearchParams({ parentOrigin: window.location.origin });\n    const warmUrl = `${this.getDialogUrl()}/dialog/warm?${warmParams.toString()}`;\n\n    // A bare hidden iframe — deliberately NOT the full createModalDialog\n    // chrome (no <dialog>, overlay, Escape handler or showModal). We only need\n    // the browser to fetch + run the bundle; none of the modal lifecycle\n    // applies to a frame the user never sees.\n    const iframe = document.createElement(\"iframe\");\n    iframe.setAttribute(\"aria-hidden\", \"true\");\n    iframe.setAttribute(\"tabindex\", \"-1\");\n    iframe.title = \"1auth dialog prewarm\";\n    // Off-screen + inert so it can never intercept clicks or take focus, while\n    // still being \"rendered\" (display:none would let some browsers defer the\n    // load we are trying to trigger).\n    iframe.style.cssText =\n      \"position:fixed;left:-9999px;top:0;width:1px;height:1px;opacity:0;border:0;pointer-events:none;\";\n\n    // Resolve on the iframe `load` event rather than a postMessage. The warm\n    // route is intentionally message-silent, and `load` fires for cross-origin\n    // frames too (we never touch contentDocument), so it is the right\n    // signal — and one a stray frame's messages can never spoof.\n    const ready = new Promise<boolean>((resolve) => {\n      let settled = false;\n      const finish = (value: boolean) => {\n        if (settled) return;\n        settled = true;\n        clearTimeout(timer);\n        resolve(value);\n      };\n      iframe.onload = () => finish(true);\n      iframe.onerror = () => finish(false);\n      // Failsafe so the promise always settles even if `load` is missed.\n      const timer = setTimeout(() => finish(false), 10000);\n    });\n    iframe.src = warmUrl;\n    document.body.appendChild(iframe);\n\n    this.prewarmState = { iframe, ready };\n    return ready;\n  }\n\n  /**\n   * Tear down the hidden prewarm iframe created by {@link prewarm}.\n   *\n   * The HTTP cache that prewarm populated survives teardown, so a subsequent\n   * open is still bundle-warm; this only releases the parked frame (and its\n   * keep-alive connection). Call it when auth is no longer likely on the\n   * current view. Safe to call when nothing is warmed.\n   */\n  destroyPrewarm(): void {\n    const state = this.prewarmState;\n    if (!state) return;\n    this.prewarmState = null;\n    state.iframe.remove();\n  }\n\n  /**\n   * Wait for the dialog iframe to signal ready, but defer sending `PASSKEY_INIT`\n   * until the caller decides the time is right.\n   *\n   * This is the deferred variant of `waitForDialogReady`, used by flows that run\n   * the dialog and a background API call in parallel (the \"two-phase\" approach).\n   * Rather than blocking until both the iframe is ready AND the API call is done,\n   * this method resolves as soon as `PASSKEY_READY` arrives and returns a\n   * `sendInit` callback. The caller invokes `sendInit` once prepare data is\n   * available, which may happen before or after the iframe is ready.\n   *\n   * Timeout: if the iframe never signals ready within 10 seconds (e.g. network\n   * error, origin mismatch), resolves with `{ ready: false }` and calls cleanup.\n   *\n   * @param dialog - The `<dialog>` element wrapping the iframe.\n   * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   * @returns `{ ready: true, sendInit }` when the iframe is ready, or\n   *   `{ ready: false }` if the dialog was closed or timed out first.\n   */\n  private waitForDialogReadyDeferred(\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    options: { blindSigning?: boolean; reveal?: () => void } = {},\n  ): Promise<\n    | { ready: true; blindSigning: boolean; sendInit: (initMessage: Record<string, unknown>) => void }\n    | { ready: false }\n  > {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      let settled = false;\n\n      const teardown = () => {\n        if (settled) return;\n        settled = true;\n        clearTimeout(readyTimeout);\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n      };\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        if (event.data?.type === \"PASSKEY_READY\") {\n          const blindSigning = options.blindSigning === true;\n          teardown();\n          resolve({\n            ready: true,\n            blindSigning,\n            sendInit: (initMessage: Record<string, unknown>) => {\n              if (blindSigning) iframe.focus({ preventScroll: true });\n              iframe.contentWindow?.postMessage(\n                { type: \"PASSKEY_INIT\", ...initMessage, fullViewport: true, blindSigning },\n                dialogOrigin,\n              );\n            },\n          });\n        } else if (\n          event.data?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // Match by source, not just origin: the auth dialog (authWithModal)\n          // emits a stray PASSKEY_CLOSE from the SAME origin as it tears down.\n          // Without the source check, that close resolves the sign dialog's\n          // ready-promise as { ready: false } → dialogClosedBeforeReadyPromise\n          // → a spurious USER_CANCELLED (\"closed before it became ready\").\n          // Identical guard to the earlyDialogClosePromise fix.\n          teardown();\n          cleanup();\n          resolve({ ready: false });\n        }\n      };\n\n      const handleClose = () => {\n        teardown();\n        resolve({ ready: false });\n      };\n\n      const readyTimeout = setTimeout(() => {\n        teardown();\n        cleanup();\n        resolve({ ready: false });\n      }, 10000);\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Call the passkey service to obtain a Rhinestone orchestrator quote for an\n   * intent (a single target-chain transaction or swap).\n   *\n   * The service contacts the Rhinestone orchestrator, which returns a signed\n   * `intentOp` structure containing the quote, fees, and a WebAuthn challenge\n   * the user must sign to authorize execution.\n   *\n   * The `X-Origin-Tier` response header is forwarded to the dialog so it can\n   * display tier-specific UI (e.g. \"Free\" vs \"Premium\" badge).\n   *\n   * Side effect: if the server returns \"User not found\", the cached user entry\n   * is removed from `localStorage` to force re-authentication.\n   *\n   * @param requestBody - Serialized intent options (bigint amounts converted to\n   *   strings before this call).\n   * @returns On success: `{ success: true, data: PrepareIntentResponse, tier }`.\n   *   On failure: `{ success: false, error: { code, message, details? } }`.\n   */\n  /**\n   * Request a non-sponsored draft solely to obtain the SDK-canonical intent\n   * input that the embedding app must authorize. The passkey service returns\n   * no signable quote or user data in this phase.\n   */\n  private async prepareSponsorshipDraft(\n    requestBody: Record<string, unknown>,\n    telemetry?: TelemetryOperation,\n  ): Promise<\n    | { success: true; sponsorshipIntentInput: unknown }\n    | { success: false; error: { code: string; message: string; details?: OneAuthErrorDetails } }\n  > {\n    try {\n      const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n        body: JSON.stringify({ ...requestBody, quoteMode: \"draft\" }),\n      });\n      if (!response.ok) {\n        const errorData = await response.json().catch(() => ({}));\n        return {\n          success: false,\n          error: {\n            code: \"PREPARE_FAILED\",\n            message: errorData.error || \"Failed to prepare sponsorship draft\",\n            details: (errorData.details ?? errorData.candidateErrors ?? errorData) as OneAuthErrorDetails,\n          },\n        };\n      }\n      const data = (await response.json()) as { sponsorshipIntentInput?: unknown };\n      if (data.sponsorshipIntentInput === undefined) {\n        return {\n          success: false,\n          error: { code: \"PREPARE_FAILED\", message: \"Prepare response missing sponsorship intent input\" },\n        };\n      }\n      return { success: true, sponsorshipIntentInput: data.sponsorshipIntentInput };\n    } catch (error) {\n      return {\n        success: false,\n        error: {\n          code: \"NETWORK_ERROR\",\n          message: error instanceof Error ? error.message : \"Network error\",\n        },\n      };\n    }\n  }\n\n  private async prepareIntent(\n    requestBody: Record<string, unknown>,\n    telemetry?: TelemetryOperation,\n  ): Promise<\n    | { success: true; data: PrepareIntentResponse; tier: string | null }\n    | { success: false; error: { code: string; message: string; details?: OneAuthErrorDetails } }\n  > {\n    try {\n      const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n        body: JSON.stringify(requestBody),\n      });\n\n      if (!response.ok) {\n        const errorData = await response.json().catch(() => ({}));\n        const errorMessage = errorData.error || \"Failed to prepare intent\";\n\n        if (errorMessage.includes(\"User not found\")) {\n          localStorage.removeItem(\"1auth-user\");\n        }\n\n        return {\n          success: false,\n          error: {\n            code: errorMessage.includes(\"User not found\") ? \"USER_NOT_FOUND\" : \"PREPARE_FAILED\",\n            message: errorMessage,\n            details: normalizeOneAuthErrorDetails(\n              errorData.details ??\n                (errorData.candidateErrors === undefined\n                  ? errorData\n                  : { candidateErrors: errorData.candidateErrors }),\n            ),\n          },\n        };\n      }\n\n      const tier = response.headers.get(\"X-Origin-Tier\");\n      return { success: true, data: await response.json(), tier };\n    } catch (error) {\n      return {\n        success: false,\n        error: {\n          code: \"NETWORK_ERROR\",\n          message: error instanceof Error ? error.message : \"Network error\",\n        },\n      };\n    }\n  }\n\n  /**\n   * Call the passkey service to obtain orchestrator quotes for all intents in a\n   * batch, returning a single shared WebAuthn challenge.\n   *\n   * The service prepares each intent independently and assembles a merkle tree\n   * whose root becomes the challenge. Signing that root once authorizes every\n   * intent in the batch. Partially-failed batches are supported: the response\n   * includes both `intents` (succeeded) and `failedIntents` (per-intent errors),\n   * so the dialog can still show the successful subset for signing.\n   *\n   * Side effect: same \"User not found\" localStorage cleanup as `prepareIntent`.\n   *\n   * @param requestBody - Serialized batch options (bigint amounts converted to\n   *   strings before this call).\n   * @returns On success: `{ success: true, data: PrepareBatchIntentResponse, tier }`.\n   *   On failure: `{ success: false, error, failedIntents? }`.\n   */\n  /**\n   * Draft, authorize, and authoritatively quote a batch without losing caller indices.\n   * Preferred sponsorship failures are retried only by an explicit full-batch\n   * self-funded re-quote so every returned intent shares one fresh merkle root.\n   */\n  private async prepareBatchWithFunding(\n    requestBody: Record<string, unknown>,\n    sponsorshipModes: SponsorshipMode[],\n    telemetry?: TelemetryOperation,\n  ): Promise<\n    | { success: true; data: PrepareBatchIntentResponse; tier: string | null; extensionTokens: string[] }\n    | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> }\n  > {\n    const draftFundingModes = sponsorshipModes.map((mode) =>\n      mode === \"disabled\" ? \"self-funded\" as const : \"required\" as const,\n    );\n    const draftResult = await this.prepareBatchDraft(\n      { ...requestBody, quoteMode: \"draft\", fundingModes: draftFundingModes },\n      telemetry,\n    );\n    if (!draftResult.success) return draftResult;\n\n    const draftFailedIntents = draftResult.data.failedIntents ?? [];\n    const draftSuccessfulIndices = new Set(\n      Object.keys(draftResult.data.sponsorshipIntentInputs).map(Number),\n    );\n    if (draftSuccessfulIndices.size === 0) {\n      return {\n        success: false,\n        error: \"All intents failed to get sponsorship drafts\",\n        failedIntents: draftFailedIntents,\n      };\n    }\n    // The final request must contain only draft successes. Keeping a failed\n    // original index in the request would make the server require a grant that\n    // cannot exist and discard the valid, signable subset.\n    const finalIntents = (requestBody.intents as Array<Record<string, unknown>>)\n      .flatMap((intent, index) => draftSuccessfulIndices.has(index)\n        ? [{ ...intent, originalIndex: index }]\n        : []);\n\n    const grantsByIndex: Record<string, string> = {};\n    const finalFundingModes = [...draftFundingModes];\n    const sponsoredIndices = Object.keys(draftResult.data.sponsorshipIntentInputs)\n      .map(Number)\n      .filter((index) => sponsorshipModes[index] !== \"disabled\");\n    const grantResults = await Promise.allSettled(\n      sponsoredIndices.map(async (index) => ({\n        index,\n        token: await this.sponsorship!.getExtensionToken(\n          JSON.stringify(draftResult.data.sponsorshipIntentInputs[String(index)]),\n        ),\n      })),\n    );\n    for (let i = 0; i < grantResults.length; i++) {\n      const result = grantResults[i];\n      const index = sponsoredIndices[i];\n      if (result.status === \"fulfilled\") {\n        grantsByIndex[String(index)] = result.value.token;\n      } else if (sponsorshipModes[index] === \"preferred\") {\n        finalFundingModes[index] = \"self-funded\";\n      } else {\n        return { success: false, error: `Sponsorship token fetch failed for required intent ${index}` };\n      }\n    }\n\n    const runFinal = (fundingModes: Array<\"required\" | \"self-funded\">) =>\n      this.prepareBatchIntent({\n        ...requestBody,\n        intents: finalIntents,\n        quoteMode: \"final\",\n        fundingModes,\n        quoteExtensionTokens: grantsByIndex,\n      }, telemetry);\n    let finalResult = await runFinal(finalFundingModes);\n    const preferredSponsoredFailures = finalResult.success\n      ? (finalResult.data.failedIntents ?? []).map((failure) => failure.index)\n      : (finalResult.failedIntents ?? []).map((failure) => failure.index);\n    const preferredFallbackIndices = preferredSponsoredFailures.filter(\n      (index) => sponsorshipModes[index] === \"preferred\" && finalFundingModes[index] === \"required\",\n    );\n    if (preferredFallbackIndices.length > 0) {\n      for (const index of preferredFallbackIndices) {\n        finalFundingModes[index] = \"self-funded\";\n        delete grantsByIndex[String(index)];\n      }\n      finalResult = await runFinal(finalFundingModes);\n    }\n    if (!finalResult.success) return finalResult;\n    if (draftFailedIntents.length > 0) {\n      const draftFailedIndices = new Set(\n        draftFailedIntents.map((failure) => failure.index),\n      );\n      finalResult = {\n        ...finalResult,\n        data: {\n          ...finalResult.data,\n          failedIntents: [\n            ...draftFailedIntents,\n            ...(finalResult.data.failedIntents ?? []).filter(\n              (failure) => !draftFailedIndices.has(failure.index),\n            ),\n          ],\n        },\n      };\n    }\n\n    const sponsoredPreparedIntents = finalResult.data.intents.filter(\n      (intent) => finalFundingModes[intent.index] === \"required\",\n    );\n    const executionGrantResults = await Promise.allSettled(\n      sponsoredPreparedIntents.map(async (intent) => ({\n        index: intent.index,\n        token: await this.sponsorship!.getExtensionToken(intent.intentOp),\n      })),\n    );\n    const executionGrantsByIndex: Record<string, string> = {};\n    for (let i = 0; i < executionGrantResults.length; i++) {\n      const result = executionGrantResults[i];\n      const index = sponsoredPreparedIntents[i].index;\n      if (result.status === \"fulfilled\") {\n        executionGrantsByIndex[String(index)] = result.value.token;\n      } else {\n        return { success: false, error: `Execution sponsorship token fetch failed for intent ${index}` };\n      }\n    }\n\n    return {\n      ...finalResult,\n      extensionTokens: finalResult.data.intents.map((intent) =>\n        finalFundingModes[intent.index] === \"required\" ? executionGrantsByIndex[String(intent.index)] ?? \"\" : \"\",\n      ),\n    };\n  }\n\n  /** Request canonical batch sponsorship inputs without returning signable data. */\n  private async prepareBatchDraft(\n    requestBody: Record<string, unknown>,\n    telemetry?: TelemetryOperation,\n  ): Promise<\n    | { success: true; data: PrepareBatchIntentDraftResponse; tier: string | null }\n    | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> }\n  > {\n    try {\n      const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n        body: JSON.stringify(requestBody),\n      });\n      if (!response.ok) {\n        const errorData = await response.json().catch(() => ({}));\n        return { success: false, error: errorData.error || \"Failed to prepare batch sponsorship draft\", failedIntents: errorData.failedIntents };\n      }\n      return { success: true, data: await response.json(), tier: response.headers.get(\"X-Origin-Tier\") };\n    } catch {\n      return { success: false, error: \"Network error\" };\n    }\n  }\n\n  private async prepareBatchIntent(\n    requestBody: Record<string, unknown>,\n    telemetry?: TelemetryOperation,\n  ): Promise<\n    | { success: true; data: PrepareBatchIntentResponse; tier: string | null }\n    | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> }\n  > {\n    try {\n      const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n        body: JSON.stringify(requestBody),\n      });\n\n      if (!response.ok) {\n        const errorData = await response.json().catch(() => ({}));\n        const errorMessage = errorData.error || \"Failed to prepare batch intent\";\n\n        if (errorMessage.includes(\"User not found\")) {\n          localStorage.removeItem(\"1auth-user\");\n        }\n\n        return {\n          success: false,\n          error: errorMessage,\n          failedIntents: errorData.failedIntents,\n        };\n      }\n\n      const tier = response.headers.get(\"X-Origin-Tier\");\n      return { success: true, data: await response.json(), tier };\n    } catch {\n      return { success: false, error: \"Network error\" };\n    }\n  }\n\n  /**\n   * Forward a prepare-phase error to the dialog iframe so it can display a\n   * human-readable failure message instead of hanging on the loading state.\n   *\n   * The dialog listens for `PASSKEY_PREPARE_ERROR` and transitions to an error\n   * view. The user can then dismiss the dialog, at which point\n   * `waitForDialogClose` resolves and the SDK returns the error to the caller.\n   *\n   * @param iframe - The iframe element to post the error to.\n   * @param error - Human-readable error message from the prepare response.\n   */\n  private sendPrepareError(iframe: HTMLIFrameElement, error: string): void {\n    const dialogOrigin = this.getDialogOrigin();\n    iframe.contentWindow?.postMessage(\n      { type: \"PASSKEY_PREPARE_ERROR\", error },\n      dialogOrigin,\n    );\n  }\n\n  /**\n   * Poll for intent status\n   *\n   * Use this to check on the status of a submitted intent\n   * that hasn't completed yet.\n   */\n  async getIntentStatus(intentId: string): Promise<SendIntentResult> {\n    const telemetry = this.createTelemetryOperation(\"status\");\n    this.emitTelemetry(\"intent.status.started\", telemetry, {\n      outcome: \"started\",\n      attributes: { directStatusCheck: true },\n    });\n    try {\n      const response = await fetch(\n        `${this.config.providerUrl}/api/intent/status/${intentId}`,\n        {\n          headers: {\n            ...this.telemetryHeaders(telemetry),\n            ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n          },\n        }\n      );\n\n      if (!response.ok) {\n        const errorData = await response.json().catch(() => ({}));\n        this.emitTelemetry(\"status.failed\", telemetry, {\n          outcome: \"failure\",\n          errorCode: \"STATUS_FAILED\",\n          errorMessage: errorData.error || \"Failed to get intent status\",\n        });\n        return {\n          success: false,\n          intentId,\n          status: \"failed\",\n          error: {\n            code: \"STATUS_FAILED\",\n            message: errorData.error || \"Failed to get intent status\",\n          },\n        };\n      }\n\n      const data = await response.json();\n      this.emitTelemetry(\"status.succeeded\", telemetry, {\n        outcome: data.status === \"completed\" ? \"success\" : \"started\",\n        status: data.status,\n      });\n      return {\n        success: data.status === \"completed\",\n        intentId,\n        status: data.status,\n        transactionHash: data.transactionHash,\n        operationId: data.operationId,\n      };\n    } catch (error) {\n      this.emitTelemetry(\"status.failed\", telemetry, {\n        outcome: \"failure\",\n        ...describeTelemetryError(error),\n      });\n      return {\n        success: false,\n        intentId,\n        status: \"failed\",\n        error: {\n          code: \"NETWORK_ERROR\",\n          message: error instanceof Error ? error.message : \"Network error\",\n        },\n      };\n    }\n  }\n\n  /**\n   * Get the history of intents for the authenticated user.\n   *\n   * Requires an active session (user must be logged in).\n   *\n   * @example\n   * ```typescript\n   * // Get recent intents\n   * const history = await client.getIntentHistory({ limit: 10 });\n   *\n   * // Filter by status\n   * const pending = await client.getIntentHistory({ status: 'pending' });\n   *\n   * // Filter by date range\n   * const lastWeek = await client.getIntentHistory({\n   *   from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),\n   * });\n   * ```\n   */\n  async getIntentHistory(\n    options?: IntentHistoryOptions\n  ): Promise<IntentHistoryResult> {\n    const telemetry = this.createTelemetryOperation(\"history\", {\n      hasStatusFilter: !!options?.status,\n    });\n    const queryParams = new URLSearchParams();\n    if (options?.limit) queryParams.set(\"limit\", String(options.limit));\n    if (options?.offset) queryParams.set(\"offset\", String(options.offset));\n    if (options?.status) queryParams.set(\"status\", options.status);\n    if (options?.from) queryParams.set(\"from\", options.from);\n    if (options?.to) queryParams.set(\"to\", options.to);\n\n    const url = `${this.config.providerUrl}/api/intent/history${\n      queryParams.toString() ? `?${queryParams}` : \"\"\n    }`;\n\n    const response = await fetch(url, {\n      headers: {\n        ...this.telemetryHeaders(telemetry),\n        ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n      },\n      credentials: \"include\",\n    });\n\n    if (!response.ok) {\n      const errorData = await response.json().catch(() => ({}));\n      this.emitTelemetry(\"history.failed\", telemetry, {\n        outcome: \"failure\",\n        errorCode: \"HISTORY_FAILED\",\n        errorMessage: errorData.error || \"Failed to get intent history\",\n      });\n      throw new Error(errorData.error || \"Failed to get intent history\");\n    }\n\n    const result = await response.json();\n    this.emitTelemetry(\"history.succeeded\", telemetry, {\n      outcome: \"success\",\n      attributes: {\n        total: result.total,\n        returned: result.intents?.length ?? 0,\n      },\n    });\n    return result;\n  }\n\n  /**\n   * Forward a raw EIP-1193 request to the iframe so the active EOA connector\n   * can handle it (wallet-connect session or injected wallet). Opens\n   * `/dialog/sign-eoa`, which looks up the wagmi connector and delegates to\n   * `connector.getProvider().request({ method, params })`. The wallet's own\n   * UI is the review screen; the dialog just transports the request.\n   */\n  async requestWithWallet(options: {\n    method: string;\n    params?: unknown[] | Record<string, unknown>;\n    expectedAddress?: `0x${string}`;\n    theme?: ThemeConfig;\n  }): Promise<\n    | { success: true; result: unknown }\n    | { success: false; error: { code: string; message: string } }\n  > {\n    // Serialise concurrent calls: the EOA iframe is a single shared resource\n    // and the iframe's view + classifyInit state assume one in-flight\n    // request at a time.\n    const job = this.eoaSerialQueue.then(\n      () => this.doRequestWithWallet(options),\n      () => this.doRequestWithWallet(options),\n    );\n    this.eoaSerialQueue = job.then(\n      () => undefined,\n      () => undefined,\n    );\n    return job;\n  }\n\n  private async doRequestWithWallet(options: {\n    method: string;\n    params?: unknown[] | Record<string, unknown>;\n    expectedAddress?: `0x${string}`;\n    theme?: ThemeConfig;\n  }): Promise<\n    | { success: true; result: unknown }\n    | { success: false; error: { code: string; message: string } }\n  > {\n    const dialogOrigin = this.getDialogOrigin();\n    const ensureResult = await this.ensureEoaDialog(options?.theme);\n    if (!ensureResult.ok) {\n      return {\n        success: false,\n        error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n      };\n    }\n    const { dialog, iframe } = ensureResult;\n\n    // requestId binds the SDK call to its dialog instance. Required for\n    // every subsequent message: the dialog echoes it on PASSKEY_EOA_RESULT\n    // and PASSKEY_EOA_CLOSE so stale messages from a previous flow cannot\n    // cross-resolve this promise.\n    const requestId =\n      typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n        ? crypto.randomUUID()\n        : `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n    const hideDialog = () => {\n      if (dialog.open) dialog.close();\n    };\n\n    // Install the result listener BEFORE PASSKEY_INIT is sent. Fast methods\n    // like wallet_getCallsStatus can resolve in the same task as the init\n    // and emit PASSKEY_EOA_RESULT before a listener attached afterward\n    // would see it.\n    const responsePromise = this.waitForEoaResponse(\n      iframe,\n      hideDialog,\n      requestId,\n      dialogOrigin,\n    );\n\n    const initPayload = {\n      mode: \"iframe\",\n      method: options.method,\n      params: options.params,\n      expectedAddress: options.expectedAddress,\n      requestId,\n    };\n    iframe.contentWindow?.postMessage(\n      { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n      dialogOrigin,\n    );\n\n    // The iframe may re-emit PASSKEY_READY if its React tree remounts\n    // (HMR, Suspense). Re-send PASSKEY_INIT so it picks the current\n    // request up — keyed on the same requestId, which the iframe dedupes.\n    const handleReReady = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.source !== iframe.contentWindow) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n          dialogOrigin,\n        );\n      }\n    };\n    window.addEventListener(\"message\", handleReReady);\n\n    const result = await responsePromise;\n    window.removeEventListener(\"message\", handleReReady);\n    hideDialog();\n    return result;\n  }\n\n  /**\n   * Lazily create the persistent `/dialog/sign-eoa` iframe and reveal it.\n   * Subsequent calls just re-open the existing `<dialog>` so the iframe's\n   * in-page state (notably the WalletConnect SignClient) is preserved\n   * between transactions.\n   */\n  private async ensureEoaDialog(theme: ThemeConfig | undefined): Promise<\n    | { ok: true; dialog: HTMLDialogElement; iframe: HTMLIFrameElement }\n    | { ok: false }\n  > {\n    if (this.eoaDialogState) {\n      const { dialog, iframe } = this.eoaDialogState;\n      if (!dialog.open) {\n        // dialog.showModal() throws if already open — guarded above.\n        dialog.showModal();\n      }\n      return { ok: true, dialog, iframe };\n    }\n\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    // Keep the persistent EOA iframe on the same parent-origin hint path as\n    // the other dialog routes; the passkey app still authenticates the caller\n    // from browser-provided referrer/event.origin before trusting it.\n    appendParentOriginParam(params);\n    const themeParams = this.getThemeParams(theme);\n    if (themeParams) {\n      new URLSearchParams(themeParams).forEach((value, key) => {\n        params.set(key, value);\n      });\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign-eoa?${params.toString()}`;\n\n    const { dialog, iframe, destroy } = this.createModalDialog(signingUrl, {\n      persistent: true,\n    });\n\n    const ready = await this.waitForEoaIframeReady(iframe);\n    if (!ready) {\n      // Iframe never came up — fully tear down and surface as a rejection.\n      // Next call will retry from scratch.\n      destroy();\n      return { ok: false };\n    }\n\n    this.eoaDialogState = { dialog, iframe };\n    return { ok: true, dialog, iframe };\n  }\n\n  private waitForEoaIframeReady(iframe: HTMLIFrameElement): Promise<boolean> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      let timeoutId: ReturnType<typeof setTimeout> | null = null;\n      const cleanup = () => {\n        if (timeoutId !== null) clearTimeout(timeoutId);\n        window.removeEventListener(\"message\", handler);\n      };\n      const handler = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        if (event.source !== iframe.contentWindow) return;\n        if (event.data?.type === \"PASSKEY_READY\") {\n          cleanup();\n          resolve(true);\n        }\n      };\n      window.addEventListener(\"message\", handler);\n      timeoutId = setTimeout(() => {\n        cleanup();\n        resolve(false);\n      }, 10000);\n    });\n  }\n\n  private waitForEoaResponse(\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    requestId: string,\n    dialogOrigin: string,\n  ): Promise<\n    | { success: true; result: unknown }\n    | { success: false; error: { code: string; message: string } }\n  > {\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        // Three trust checks before reading any payload:\n        //   1. event.origin pinned to the dialog origin\n        //   2. event.source pinned to this iframe's contentWindow (rejects\n        //      messages from sibling frames or popups that grabbed a window\n        //      reference)\n        //   3. requestId echoed by the dialog matches ours (rejects stale\n        //      messages from a prior remount or a concurrent dialog)\n        if (event.origin !== dialogOrigin) return;\n        if (event.source !== iframe.contentWindow) return;\n        const message = event.data;\n        if (\n          message?.type === \"PASSKEY_EOA_RESULT\" ||\n          message?.type === \"PASSKEY_EOA_CLOSE\"\n        ) {\n          if (message.requestId !== requestId) return;\n        } else {\n          return;\n        }\n        window.removeEventListener(\"message\", handleMessage);\n        if (message.type === \"PASSKEY_EOA_CLOSE\") {\n          cleanup();\n          resolve({\n            success: false,\n            error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n          });\n          return;\n        }\n        if (message.success) {\n          resolve({ success: true, result: message.data?.result });\n        } else {\n          resolve({\n            success: false,\n            error: message.error || {\n              code: \"EOA_REQUEST_FAILED\",\n              message: \"Wallet request failed\",\n            },\n          });\n        }\n      };\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Sign an arbitrary message with the user's passkey\n   *\n   * This is for off-chain message signing (e.g., authentication challenges,\n   * terms acceptance, login signatures), NOT for transaction signing.\n   * The message is displayed to the user and signed with their passkey.\n   *\n   * @example\n   * ```typescript\n   * // Sign a login challenge\n   * const result = await client.signMessage({\n   *   accountAddress: '0x...',\n   *   message: `Sign in to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`,\n   *   description: 'Verify your identity to continue',\n   * });\n   *\n   * if (result.success) {\n   *   // Send signature to your backend for verification\n   *   await fetch('/api/verify', {\n   *     method: 'POST',\n   *     body: JSON.stringify({\n   *       signature: result.signature,\n   *       message: result.signedMessage,\n   *     }),\n   *   });\n   * }\n   * ```\n   */\n  async signMessage(options: SignMessageOptions): Promise<SignMessageResult> {\n    const telemetry = this.createTelemetryOperation(\"sign\", {\n      signingMode: \"message\",\n      hasAccountAddress: !!options.accountAddress,\n    });\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n    const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n    const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n      hidden: requestedBlindSigning,\n    });\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      attributes: { blindSigning: requestedBlindSigning },\n    });\n\n    const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n      blindSigning: requestedBlindSigning,\n      reveal,\n    });\n    if (!dialogResult.ready) {\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_REJECTED\",\n        errorMessage: \"User closed the dialog before signing\",\n      });\n      return {\n        success: false,\n        error: {\n          code: \"USER_REJECTED\",\n          message: \"User closed the dialog\",\n        },\n      };\n    }\n\n    const initPayload = {\n      mode: \"iframe\",\n      message: options.message,\n      challenge: options.challenge || options.message,\n      accountAddress: options.accountAddress,\n      description: options.description,\n      metadata: options.metadata,\n      telemetry: this.telemetryPayload(telemetry),\n    };\n    dialogResult.sendInit(initPayload);\n    const blindSigning = dialogResult.blindSigning;\n    this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n    // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n    // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n    // so the sign page recovers its state.\n    const dialogOrigin = this.getDialogOrigin();\n    const handleReReady = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n          dialogOrigin,\n        );\n      }\n    };\n    window.addEventListener(\"message\", handleReReady);\n\n    const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n    window.removeEventListener(\"message\", handleReReady);\n    cleanup();\n\n    if (signingResult.success) {\n      this.emitTelemetry(\"sign.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: { signingMode: \"message\" },\n      });\n      return {\n        success: true,\n        signature: signingResult.signature,\n        signedMessage: options.message,\n        signedHash: signingResult.signedHash as `0x${string}` | undefined,\n        passkey: signingResult.passkey,\n      };\n    }\n\n    this.emitTelemetry(\n      signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n      telemetry,\n      {\n        outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n        ...describeTelemetryError(signingResult.error),\n        attributes: { signingMode: \"message\" },\n      },\n    );\n    return {\n      success: false,\n      error: signingResult.error,\n    };\n  }\n\n  /**\n   * Sign EIP-712 typed data with the user's passkey\n   *\n   * This method allows signing structured data following the EIP-712 standard.\n   * The typed data is displayed to the user in a human-readable format before signing.\n   *\n   * @example\n   * ```typescript\n   * // Sign an ERC-2612 Permit\n   * const result = await client.signTypedData({\n   *   accountAddress: '0x...',\n   *   domain: {\n   *     name: 'Dai Stablecoin',\n   *     version: '1',\n   *     chainId: 1,\n   *     verifyingContract: '0x6B175474E89094C44Da98b954EecdeCB5BE3830F',\n   *   },\n   *   types: {\n   *     Permit: [\n   *       { name: 'owner', type: 'address' },\n   *       { name: 'spender', type: 'address' },\n   *       { name: 'value', type: 'uint256' },\n   *       { name: 'nonce', type: 'uint256' },\n   *       { name: 'deadline', type: 'uint256' },\n   *     ],\n   *   },\n   *   primaryType: 'Permit',\n   *   message: {\n   *     owner: '0xabc...',\n   *     spender: '0xdef...',\n   *     value: 1000000000000000000n,\n   *     nonce: 0n,\n   *     deadline: 1735689600n,\n   *   },\n   * });\n   *\n   * if (result.success) {\n   *   console.log('Signed hash:', result.signedHash);\n   * }\n   * ```\n   */\n  async signTypedData(options: SignTypedDataOptions): Promise<SignTypedDataResult> {\n    const telemetry = this.createTelemetryOperation(\"sign\", {\n      signingMode: \"typedData\",\n      primaryType: options.primaryType,\n      hasAccountAddress: !!options.accountAddress,\n    });\n    // Compute the EIP-712 hash using viem\n    // Use unknown cast to work around viem's strict template literal type requirements\n    const signedHash = hashTypedData({\n      domain: options.domain,\n      types: options.types,\n      primaryType: options.primaryType,\n      message: options.message,\n    } as unknown as TypedDataDefinition);\n\n    const dialogUrl = this.getDialogUrl();\n    const params = new URLSearchParams({ mode: \"iframe\" });\n    appendParentOriginParam(params);\n    this.appendTelemetryParams(params, telemetry);\n    const themeParams = this.getThemeParams(options?.theme);\n    if (themeParams) {\n      const themeParsed = new URLSearchParams(themeParams);\n      themeParsed.forEach((value, key) => params.set(key, value));\n    }\n    const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n    const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n    const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n      hidden: requestedBlindSigning,\n    });\n    this.emitTelemetry(\"dialog.opened\", telemetry, {\n      outcome: \"started\",\n      attributes: { blindSigning: requestedBlindSigning },\n    });\n\n    const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n      blindSigning: requestedBlindSigning,\n      reveal,\n    });\n    if (!dialogResult.ready) {\n      this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n        outcome: \"cancelled\",\n        errorCode: \"USER_REJECTED\",\n        errorMessage: \"User closed the dialog before signing\",\n      });\n      return {\n        success: false,\n        error: {\n          code: \"USER_REJECTED\",\n          message: \"User closed the dialog\",\n        },\n      };\n    }\n\n    const initPayload = {\n      mode: \"iframe\",\n      signingMode: \"typedData\",\n      typedData: {\n        domain: options.domain,\n        types: options.types,\n        primaryType: options.primaryType,\n        message: options.message,\n      },\n      challenge: signedHash,\n      accountAddress: options.accountAddress,\n      description: options.description,\n      telemetry: this.telemetryPayload(telemetry),\n    };\n    dialogResult.sendInit(initPayload);\n    const blindSigning = dialogResult.blindSigning;\n    this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n    // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n    // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n    // so the sign page recovers its state.\n    const dialogOrigin = this.getDialogOrigin();\n    const handleReReady = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n          dialogOrigin,\n        );\n      }\n    };\n    window.addEventListener(\"message\", handleReReady);\n\n    const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n    window.removeEventListener(\"message\", handleReReady);\n    cleanup();\n\n    if (signingResult.success) {\n      this.emitTelemetry(\"sign.succeeded\", telemetry, {\n        outcome: \"success\",\n        attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n      });\n      return {\n        success: true,\n        signature: signingResult.signature,\n        signedHash,\n        passkey: signingResult.passkey,\n      };\n    }\n\n    this.emitTelemetry(\n      signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n      telemetry,\n      {\n        outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n        ...describeTelemetryError(signingResult.error),\n        attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n      },\n    );\n    return {\n      success: false,\n      error: signingResult.error,\n    };\n  }\n\n  async signWithPopup(options: SigningRequestOptions): Promise<SigningResult> {\n    const request = await this.createSigningRequest(options, \"popup\");\n\n    // Use dialogUrl to construct the signing URL (override server's URL)\n    const dialogUrl = this.getDialogUrl();\n    const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=popup`;\n\n    const popup = this.openPopup(signingUrl);\n    if (!popup) {\n      return {\n        success: false,\n        error: {\n          code: \"POPUP_BLOCKED\",\n          message:\n            \"Popup was blocked by the browser. Please allow popups for this site.\",\n        },\n      };\n    }\n\n    return this.waitForPopupResponse(request.requestId, popup);\n  }\n\n  async signWithRedirect(\n    options: SigningRequestOptions,\n    redirectUrl?: string\n  ): Promise<void> {\n    const finalRedirectUrl = redirectUrl || this.config.redirectUrl;\n    if (!finalRedirectUrl) {\n      throw new Error(\n        \"redirectUrl is required for redirect flow. Pass it to signWithRedirect() or set it in the constructor.\"\n      );\n    }\n\n    const request = await this.createSigningRequest(\n      options,\n      \"redirect\",\n      finalRedirectUrl\n    );\n\n    // Use dialogUrl to construct the signing URL (override server's URL)\n    const dialogUrl = this.getDialogUrl();\n    const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=redirect&redirectUrl=${encodeURIComponent(finalRedirectUrl)}`;\n\n    window.location.href = signingUrl;\n  }\n\n  async signWithEmbed(\n    options: SigningRequestOptions,\n    embedOptions: EmbedOptions\n  ): Promise<SigningResult> {\n    const request = await this.createSigningRequest(options, \"embed\");\n\n    const iframe = this.createEmbed(request.requestId, embedOptions);\n\n    return this.waitForEmbedResponse(request.requestId, iframe, embedOptions);\n  }\n\n  /**\n   * Create and append a signing iframe to a caller-supplied container element.\n   *\n   * Used by the `signWithEmbed` flow where the integrator wants the signing UI\n   * to appear inline on their page rather than in a modal overlay. The iframe\n   * loads a pre-created signing request URL and fires `options.onReady` once\n   * the page has loaded.\n   *\n   * @param requestId - The signing request ID; used to construct the iframe src\n   *   and give it a stable DOM id for later removal via `removeEmbed`.\n   * @param options - Embed configuration including the container element,\n   *   optional dimensions, and lifecycle callbacks.\n   * @returns The created `<iframe>` element (already appended to the container).\n   */\n  private createEmbed(\n    requestId: string,\n    options: EmbedOptions\n  ): HTMLIFrameElement {\n    const dialogUrl = this.getDialogUrl();\n    const iframe = document.createElement(\"iframe\");\n    iframe.src = `${dialogUrl}/dialog/sign/${requestId}?mode=iframe`;\n    iframe.style.width = options.width || DEFAULT_EMBED_WIDTH;\n    iframe.style.height = options.height || DEFAULT_EMBED_HEIGHT;\n    iframe.style.border = \"none\";\n    iframe.style.borderRadius = \"12px\";\n    iframe.style.boxShadow = \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\";\n    iframe.id = `passkey-embed-${requestId}`;\n    iframe.allow = \"publickey-credentials-get *; publickey-credentials-create *; identity-credentials-get\";\n\n    iframe.onload = () => {\n      options.onReady?.();\n    };\n\n    options.container.appendChild(iframe);\n\n    // Tell the dialog about the parent's viewport so DialogCard can\n    // cap itself at 75% of the user's screen instead of auto-growing\n    // for long sign flows (e.g. a 20-action transaction). Without\n    // this, the dialog falls back to its old infinite-growth\n    // behaviour and the scroll-gated Sign button never fires.\n    this.wireViewportInfo(iframe);\n\n    // Auto-resize the iframe to the dialog's natural content height.\n    // Without this, taller screens (e.g. signup with the email field\n    // ~552px) get clipped against the fixed `DEFAULT_EMBED_HEIGHT`, and\n    // shorter screens leave dead space below. The dialog measures its\n    // card via ResizeObserver and posts `PASSKEY_RESIZE` on every change.\n    const host = new URL(dialogUrl);\n    const onResize = (event: MessageEvent) => {\n      if (event.source !== iframe.contentWindow) return;\n      if (event.origin !== host.origin) return;\n      if (event.data?.type !== \"PASSKEY_RESIZE\") return;\n      const h = Number(event.data.height);\n      if (Number.isFinite(h) && h > 0) {\n        iframe.style.height = `${h}px`;\n      }\n    };\n    window.addEventListener(\"message\", onResize);\n    // ResizeObserver in the iframe keeps firing for the dialog's\n    // lifetime; we leave the listener attached until the iframe is\n    // removed via `removeEmbed`. No cleanup hook is exposed by\n    // `createEmbed`; document a follow-up here if leak becomes an issue.\n\n    return iframe;\n  }\n\n  /**\n   * Post `PASSKEY_VIEWPORT_INFO` with the parent's\n   * `window.innerHeight` to the iframe whenever it signals\n   * `PASSKEY_READY`, and re-post on `window.resize` (rAF-debounced)\n   * so the dialog's internal max-height cap follows the user's\n   * actual screen.\n   *\n   * Inside the iframe, `vh`/`dvh` units refer to the iframe's own\n   * height (recursive when the iframe auto-sizes), so the parent is\n   * the only reliable source of \"what 75% of the user's screen is\".\n   * The dialog stores the value in `dialog-context` and falls back\n   * to auto-grow when the value is absent — so it's safe to call\n   * this even for embedders that don't actually cap (modal mode\n   * uses `fullViewport` which has its own outer cap).\n   */\n  private wireViewportInfo(iframe: HTMLIFrameElement): () => void {\n    const dialogOrigin = this.getDialogOrigin();\n\n    const post = () => {\n      iframe.contentWindow?.postMessage(\n        { type: \"PASSKEY_VIEWPORT_INFO\", height: window.innerHeight },\n        dialogOrigin,\n      );\n    };\n\n    const handleMessage = (event: MessageEvent) => {\n      if (event.origin !== dialogOrigin) return;\n      if (event.source !== iframe.contentWindow) return;\n      if (event.data?.type === \"PASSKEY_READY\") {\n        post();\n      }\n    };\n    window.addEventListener(\"message\", handleMessage);\n\n    // rAF-debounced resize. Coalesces drag-resize bursts to one post\n    // per animation frame so we don't spam the iframe with messages.\n    let raf: number | null = null;\n    const onResize = () => {\n      if (raf !== null) return;\n      raf = requestAnimationFrame(() => {\n        raf = null;\n        post();\n      });\n    };\n    window.addEventListener(\"resize\", onResize);\n\n    return () => {\n      window.removeEventListener(\"message\", handleMessage);\n      window.removeEventListener(\"resize\", onResize);\n      if (raf !== null) cancelAnimationFrame(raf);\n    };\n  }\n\n  /**\n   * Listen for a signing result from an embedded (inline) signing iframe.\n   *\n   * Matches incoming `PASSKEY_SIGNING_RESULT` messages against `requestId`\n   * to avoid reacting to messages from other iframes on the page. On resolution\n   * (success or failure), the iframe is removed from the DOM and\n   * `embedOptions.onClose` is invoked.\n   *\n   * @param requestId - The signing request ID to match against incoming messages.\n   * @param iframe - The embedded signing iframe.\n   * @param embedOptions - Embed configuration; `onClose` is called after cleanup.\n   * @returns A `SigningResult` discriminated union.\n   */\n  private waitForEmbedResponse(\n    requestId: string,\n    iframe: HTMLIFrameElement,\n    embedOptions: EmbedOptions\n  ): Promise<SigningResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      const cleanup = () => {\n        window.removeEventListener(\"message\", handleMessage);\n        iframe.remove();\n        embedOptions.onClose?.();\n      };\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) {\n          return;\n        }\n\n        const message = event.data;\n        // The Messenger sends: { type, success, data: { requestId, signature }, error }\n        const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n        if (\n          message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n          payload?.requestId === requestId\n        ) {\n          cleanup();\n\n          if (message.success && payload.signature) {\n            resolve({\n              success: true,\n              requestId,\n              signature: payload.signature,\n            });\n          } else {\n            resolve({\n              success: false,\n              requestId,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  removeEmbed(requestId: string): void {\n    const iframe = document.getElementById(`passkey-embed-${requestId}`);\n    if (iframe) {\n      iframe.remove();\n    }\n  }\n\n  async handleRedirectCallback(): Promise<SigningResult> {\n    const params = new URLSearchParams(window.location.search);\n    const requestId = params.get(\"request_id\");\n    const status = params.get(\"status\");\n    const error = params.get(\"error\");\n    const errorMessage = params.get(\"error_message\");\n\n    if (error) {\n      return {\n        success: false,\n        requestId: requestId || undefined,\n        error: {\n          code: parseSigningResultError({ code: error }).code,\n          message: errorMessage || \"Unknown error\",\n        },\n      };\n    }\n\n    if (!requestId) {\n      return {\n        success: false,\n        error: {\n          code: \"INVALID_REQUEST\",\n          message: \"No request_id found in callback URL\",\n        },\n      };\n    }\n\n    if (status !== \"completed\") {\n      return {\n        success: false,\n        requestId,\n        error: {\n          code: \"UNKNOWN\",\n          message: `Unexpected status: ${status}`,\n        },\n      };\n    }\n\n    return this.fetchSigningResult(requestId);\n  }\n\n\n  /**\n   * Register a signing request with the passkey service and receive a\n   * short-lived `requestId`.\n   *\n   * Used by the legacy popup, redirect, and embed flows. The passkey service\n   * stores the challenge and metadata server-side so the dialog page can fetch\n   * them by `requestId` without relying on URL parameters alone. This avoids\n   * exposing potentially large challenge payloads in query strings.\n   *\n   * @param options - The signing options (challenge, accountAddress, description, etc.).\n   * @param mode - How the dialog will be opened (`\"popup\"`, `\"redirect\"`, or `\"embed\"`).\n   * @param redirectUrl - Only required for `\"redirect\"` mode; the URL the dialog\n   *   will navigate back to after signing.\n   * @returns The created signing request with its unique `requestId`.\n   * @throws If the API call fails.\n   */\n  private async createSigningRequest(\n    options: SigningRequestOptions,\n    mode: \"popup\" | \"redirect\" | \"embed\",\n    redirectUrl?: string\n  ): Promise<CreateSigningRequestResponse> {\n    const response = await fetch(\n      `${this.config.providerUrl}/api/sign/request`,\n      {\n        method: \"POST\",\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n        body: JSON.stringify({\n          ...(this.config.clientId && { clientId: this.config.clientId }),\n          accountAddress: options.accountAddress,\n          challenge: options.challenge,\n          description: options.description,\n          metadata: options.metadata,\n          transaction: options.transaction,\n          mode,\n          redirectUrl,\n        }),\n      }\n    );\n\n    if (!response.ok) {\n      const errorData = await response.json().catch(() => ({}));\n      throw new Error(errorData.error || errorData.message || \"Failed to create signing request\");\n    }\n\n    return response.json();\n  }\n\n  /**\n   * Open a centered popup window for the signing or auth dialog.\n   *\n   * Positions the popup near the top of the current window (50px from the top)\n   * and horizontally centered relative to the browser window. Uses `popup=true`\n   * to request a minimal chrome popup (no address bar) on browsers that support\n   * the Window Management API.\n   *\n   * @param url - The full URL to open in the popup.\n   * @returns The popup `Window` reference, or `null` if the browser blocked it.\n   */\n  private openPopup(url: string): Window | null {\n    const left = window.screenX + (window.outerWidth - POPUP_WIDTH) / 2;\n    const top = window.screenY + 50; // Near top of window\n\n    return window.open(\n      url,\n      \"passkey-signing\",\n      `width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top},popup=true`\n    );\n  }\n\n  /**\n   * Wait for the dialog iframe to signal ready, then immediately send init data.\n   *\n   * This is the synchronous-init variant: `initMessage` is available at call\n   * time, so it can be posted as soon as `PASSKEY_READY` arrives. Use\n   * `waitForDialogReadyDeferred` when init data depends on an in-flight API call.\n   *\n   * Also handles early close (X button, escape key, backdrop click) during the\n   * ready phase so those paths resolve cleanly without leaking event listeners.\n   *\n   * Timeout: resolves `false` after 10 seconds if the iframe never signals ready\n   * (e.g. origin mismatch or network error loading the dialog app).\n   *\n   * @param dialog - The `<dialog>` element wrapping the iframe.\n   * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   * @param initMessage - The `PASSKEY_INIT` payload to send when ready.\n   * @returns `true` if the dialog is ready and init was sent; `false` if the\n   *   dialog was closed or timed out before becoming ready.\n   */\n  private waitForDialogReady(\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    initMessage: Record<string, unknown>,\n    options: { blindSigning?: boolean; reveal?: () => void } = {},\n  ): Promise<boolean> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      let settled = false;\n\n      const teardown = () => {\n        if (settled) return;\n        settled = true;\n        clearTimeout(readyTimeout);\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n      };\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        if (event.data?.type === \"PASSKEY_READY\") {\n          const blindSigning = options.blindSigning === true;\n          teardown();\n          if (blindSigning) iframe.focus({ preventScroll: true });\n          iframe.contentWindow?.postMessage({\n            type: \"PASSKEY_INIT\",\n            ...initMessage,\n            fullViewport: true,\n            blindSigning,\n          }, dialogOrigin);\n          resolve(true);\n        } else if (\n          event.data?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // Cross-frame guard (same as waitForDialogReadyDeferred): a stray\n          // PASSKEY_CLOSE from a sibling same-origin dialog must not resolve\n          // this dialog's ready phase as closed-before-ready.\n          teardown();\n          cleanup();\n          resolve(false);\n        }\n      };\n\n      // Handle escape key / backdrop click which call cleanup() -> dialog.close()\n      const handleClose = () => {\n        teardown();\n        resolve(false);\n      };\n\n      // Timeout: if dialog never signals ready (e.g. origin mismatch), clean up\n      const readyTimeout = setTimeout(() => {\n        teardown();\n        cleanup();\n        resolve(false);\n      }, 10000);\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Create and open a full-viewport `<dialog>` containing a passkey iframe.\n   *\n   * The SDK owns the browser `<dialog>` plus a minimal generic preload shell\n   * that appears immediately on click. The passkey iframe owns all branded and\n   * origin-specific UI (TitleBar, trust icon, action cards); the shell is\n   * removed as soon as the iframe reports that its centered card has painted.\n   *\n   * Lifecycle:\n   *   1. A themed generic preload shell is injected and shown immediately\n   *      while the iframe loads. It intentionally contains no TitleBar or\n   *      origin chrome so that UI has a single implementation in apps/passkey.\n   *   2. When the iframe sends `PASSKEY_RENDERED`, the overlay is removed and\n   *      the iframe becomes fully visible in the same frame.\n   *   3. The returned `cleanup` function tears down all event listeners,\n   *      disconnects the MutationObserver, closes the `<dialog>`, and removes\n   *      it from the DOM. It is idempotent — safe to call multiple times.\n   *\n   * Browser quirks handled:\n   *   - The 1Password extension sets `inert` on the `<dialog>`, making it\n   *     non-interactive. A MutationObserver removes the attribute immediately.\n   *   - Password managers may also set `inert` on dialog siblings; cleanup\n   *     restores those as well.\n   *   - The iframe sandbox includes `allow-popups-to-escape-sandbox` so that\n   *     1Password's popup UI can render outside the sandboxed context.\n   *   - `allow-downloads` lets the passkey iframe trigger the recovery-key\n   *     JSON fallback download without sending sensitive data to the parent.\n   *\n   * @param url - The full URL (including query params) to load in the iframe.\n   * @returns References to the dialog, iframe, and a cleanup function.\n   */\n  private createModalDialog(url: string, options?: { persistent?: boolean; hidden?: boolean }): {\n    dialog: HTMLDialogElement;\n    iframe: HTMLIFrameElement;\n    cleanup: () => void;\n    destroy: () => void;\n    reveal: () => void;\n  } {\n    const dialogUrl = this.getDialogUrl();\n    const hostUrl = new URL(dialogUrl);\n\n    const urlParams = new URL(url, window.location.href).searchParams;\n    const { background: backdropBackground, blur: backdropBlur } =\n      resolveBackdropStyle(urlParams);\n    const themeMode = urlParams.get(\"theme\") || \"light\";\n    const isDark =\n      themeMode === \"dark\" ||\n      (themeMode !== \"light\" &&\n        window.matchMedia(\"(prefers-color-scheme: dark)\").matches);\n    const theme = isDark ? DARK_TOKENS : LIGHT_TOKENS;\n\n    const dialog = document.createElement(\"dialog\");\n    dialog.dataset.passkey = \"\";\n    if (options?.hidden) {\n      dialog.dataset.passkeyHidden = \"\";\n    }\n    dialog.style.opacity = \"1\";\n    dialog.style.background = \"transparent\";\n    document.body.appendChild(dialog);\n\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      dialog[data-passkey] {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100vw;\n        height: 100vh;\n        height: 100dvh;\n        max-width: none;\n        max-height: none;\n        margin: 0;\n        padding: 0;\n        border: none;\n        background: transparent;\n        color-scheme: normal;\n        outline: none;\n        overflow: hidden;\n        pointer-events: auto;\n      }\n      dialog[data-passkey]::backdrop {\n        background: transparent !important;\n      }\n      dialog[data-passkey][data-passkey-hidden] {\n        width: 1px;\n        height: 1px;\n        max-width: 1px;\n        max-height: 1px;\n        opacity: 0;\n        pointer-events: none;\n      }\n      dialog[data-passkey][data-passkey-hidden] iframe {\n        width: 1px;\n        height: 1px;\n        opacity: 0 !important;\n        pointer-events: none;\n        backdrop-filter: none;\n        -webkit-backdrop-filter: none;\n      }\n      dialog[data-passkey] [data-passkey-overlay] {\n        position: fixed;\n        inset: 0;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        background: ${backdropBackground};\n        backdrop-filter: blur(${backdropBlur}px);\n        -webkit-backdrop-filter: blur(${backdropBlur}px);\n        z-index: 1;\n        pointer-events: none;\n      }\n      dialog[data-passkey][data-passkey-hidden] [data-passkey-overlay] {\n        display: none;\n      }\n      dialog[data-passkey] [data-passkey-preload-card] {\n        width: ${LOADING_MODAL_WIDTH}px;\n        max-width: 100%;\n        overflow: hidden;\n        border-radius: ${LOADING_MODAL_RADIUS}px;\n        background: ${theme.bgPrimary};\n        box-shadow: 0 24px 80px rgba(0, 0, 0, 0.24), 0 2px 12px rgba(0, 0, 0, 0.12);\n        font-family: ${LOADING_FONT_FAMILY};\n        line-height: ${LOADING_LINE_HEIGHT};\n        -webkit-font-smoothing: antialiased;\n        -moz-osx-font-smoothing: grayscale;\n      }\n      dialog[data-passkey] [data-passkey-preload-body] {\n        box-sizing: border-box;\n        display: flex;\n        width: 100%;\n        flex-direction: column;\n        align-items: center;\n        gap: ${LOADING_BODY_GAP}px;\n        padding: ${LOADING_MODAL_PADDING}px;\n        border-radius: ${LOADING_MODAL_RADIUS}px;\n        background: ${theme.bgPrimary};\n      }\n      dialog[data-passkey] [data-passkey-preload-spinner-wrap] {\n        display: flex;\n        align-items: center;\n        padding: ${LOADING_ICON_PADDING}px;\n      }\n      dialog[data-passkey] [data-passkey-preload-spinner] {\n        position: relative;\n        width: ${SPINNER_SIZE}px;\n        height: ${SPINNER_SIZE}px;\n      }\n      dialog[data-passkey] [data-passkey-preload-spinner] svg {\n        position: absolute;\n        inset: 0;\n        width: 100%;\n        height: 100%;\n        color: ${BRAND_PURPLE};\n        animation: _1auth-spin ${SPINNER_SPIN_DURATION_MS}ms linear infinite;\n      }\n      dialog[data-passkey] [data-passkey-preload-copy] {\n        display: flex;\n        width: 100%;\n        flex-direction: column;\n        align-items: center;\n        gap: ${LOADING_TITLE_BLOCK_GAP}px;\n        text-align: center;\n      }\n      dialog[data-passkey] [data-passkey-preload-title] {\n        margin: 0;\n        color: ${theme.textPrimary};\n        font-size: ${LOADING_TITLE_FONT_SIZE}px;\n        font-weight: ${LOADING_TITLE_FONT_WEIGHT};\n        line-height: ${LOADING_LINE_HEIGHT};\n      }\n      dialog[data-passkey] [data-passkey-preload-subtitle] {\n        margin: 0;\n        color: ${theme.textSecondary};\n        font-size: ${LOADING_SUBTITLE_FONT_SIZE}px;\n        font-weight: ${LOADING_SUBTITLE_FONT_WEIGHT};\n        line-height: ${LOADING_LINE_HEIGHT};\n      }\n      @media (max-width: 639px) {\n        dialog[data-passkey] [data-passkey-overlay] {\n          align-items: flex-end;\n        }\n        dialog[data-passkey] [data-passkey-preload-card] {\n          width: 100%;\n          border-bottom-right-radius: 0;\n          border-bottom-left-radius: 0;\n        }\n        dialog[data-passkey] [data-passkey-preload-body] {\n          padding-bottom: calc(${LOADING_MODAL_PADDING}px + env(safe-area-inset-bottom));\n        }\n      }\n      @keyframes _1auth-spin {\n        from { transform: rotate(0deg); }\n        to { transform: rotate(360deg); }\n      }\n      dialog[data-passkey] iframe {\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        border: 0;\n        background-color: transparent;\n        color-scheme: normal;\n        pointer-events: auto;\n        backdrop-filter: blur(${backdropBlur}px);\n        -webkit-backdrop-filter: blur(${backdropBlur}px);\n        transition: none;\n      }\n    `;\n    dialog.appendChild(style);\n\n    const overlay = document.createElement(\"div\");\n    overlay.dataset.passkeyOverlay = \"\";\n\n    const preloadCard = document.createElement(\"div\");\n    preloadCard.dataset.passkeyPreloadCard = \"\";\n\n    const preloadBody = document.createElement(\"div\");\n    preloadBody.dataset.passkeyPreloadBody = \"\";\n    const spinnerWrap = document.createElement(\"div\");\n    spinnerWrap.dataset.passkeyPreloadSpinnerWrap = \"\";\n    const spinner = document.createElement(\"div\");\n    spinner.dataset.passkeyPreloadSpinner = \"\";\n    const spinnerCenter = SPINNER_SIZE / 2;\n    const spinnerGap = SPINNER_CIRCUMFERENCE - SPINNER_ARC;\n    spinner.innerHTML =\n      `<svg viewBox=\"0 0 ${SPINNER_SIZE} ${SPINNER_SIZE}\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">` +\n      `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" opacity=\"0.3\" stroke-width=\"${SPINNER_STROKE}\"/>` +\n      `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" stroke-width=\"${SPINNER_STROKE}\" stroke-linecap=\"round\" stroke-dasharray=\"${SPINNER_ARC} ${spinnerGap}\" transform=\"rotate(-90 ${spinnerCenter} ${spinnerCenter})\"/>` +\n      `</svg>`;\n    spinnerWrap.appendChild(spinner);\n\n    const preloadCopy = document.createElement(\"div\");\n    preloadCopy.dataset.passkeyPreloadCopy = \"\";\n    const preloadTitle = document.createElement(\"p\");\n    preloadTitle.dataset.passkeyPreloadTitle = \"\";\n    preloadTitle.textContent = LOADING_TITLE;\n    const preloadSubtitle = document.createElement(\"p\");\n    preloadSubtitle.dataset.passkeyPreloadSubtitle = \"\";\n    preloadSubtitle.textContent = LOADING_SUBTITLE;\n    preloadCopy.append(preloadTitle, preloadSubtitle);\n    preloadBody.append(spinnerWrap, preloadCopy);\n    preloadCard.appendChild(preloadBody);\n    overlay.appendChild(preloadCard);\n    dialog.appendChild(overlay);\n\n    // Create full-viewport iframe\n    const iframe = document.createElement(\"iframe\");\n    iframe.setAttribute(\n      \"allow\",\n      [\n        \"payment\",\n        `publickey-credentials-get ${hostUrl.origin}`,\n        `publickey-credentials-create ${hostUrl.origin}`,\n        \"clipboard-write\",\n        \"identity-credentials-get\",\n      ].join(\"; \"),\n    );\n    iframe.setAttribute(\"aria-label\", \"Passkey Authentication\");\n    iframe.setAttribute(\"tabindex\", \"0\");\n    // Sandbox with allow-same-origin preserves the iframe's real origin for\n    // WebAuthn and cookies. allow-popups-to-escape-sandbox lets 1Password's\n    // browser extension render its popup UI outside the sandboxed context.\n    // allow-downloads permits same-iframe recovery JSON export.\n    iframe.setAttribute(\n      \"sandbox\",\n      \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads\",\n    );\n    iframe.setAttribute(\"title\", \"Passkey\");\n    // The SDK shell above is visible immediately. Keep the iframe at opacity 0\n    // until PASSKEY_RENDERED so the user never sees the pre-layout first paint\n    // (the dialog page SSRs with fullViewport=false, so its very first client\n    // paint can be the embedded full-width card before the URL-seeded\n    // re-render centres it).\n    iframe.style.opacity = \"0\";\n\n    // Reveal the iframe once it has painted and drop the SDK shell in the same\n    // frame. The shell exists only to make click-to-visual immediate while the\n    // cross-origin iframe boots; once PASSKEY_RENDERED lands, the iframe owns\n    // all visible UI.\n    // Register the message listener before assigning `src`: warmed auth\n    // routes can render and post PASSKEY_RENDERED very quickly, and missing\n    // that one-shot signal would leave the iframe invisible indefinitely.\n    let revealed = false;\n    // Armed when PASSKEY_READY arrives but PASSKEY_RENDERED hasn't yet — see\n    // the handler below. Cleared on reveal so a late RENDERED / teardown\n    // doesn't leave a dangling timer.\n    let readyFailsafe: ReturnType<typeof setTimeout> | undefined;\n    const revealIframe = () => {\n      if (revealed) return;\n      revealed = true;\n      clearTimeout(readyFailsafe);\n      iframe.style.opacity = \"1\";\n      overlay.style.display = \"none\";\n    };\n    // Failsafe: if PASSKEY_RENDERED never arrives (redirect race, message\n    // dropped, iframe crash) we don't want the iframe stuck invisible forever.\n    // After 8s the iframe has either rendered something the user can interact\n    // with or is broken in a way that staying hidden can't help with — either\n    // way, revealing is strictly better than a blank modal. 8s is well above\n    // the normal sub-second iframe-load path so it never preempts the real\n    // PASSKEY_RENDERED signal in healthy flows.\n    const revealFailsafe = setTimeout(revealIframe, 8000);\n\n    const handleMessage = (event: MessageEvent) => {\n      if (event.origin !== hostUrl.origin) return;\n      // Pin to THIS modal's iframe. Origin alone isn't enough: other\n      // same-origin dialog frames can exist on the page (a parked `prewarm()`\n      // frame, a second SDK instance, the persistent sign-eoa iframe). Without\n      // this, a stray RENDERED/READY from one of them could reveal this modal's\n      // iframe before its own content has painted, flashing a blank or\n      // half-rendered dialog. (`prewarm`'s warm route is message-silent, so\n      // this is defense in depth rather than its only guard.)\n      if (event.source !== iframe.contentWindow) return;\n      // PASSKEY_RENDERED is the ONLY signal that the iframe has painted its\n      // final, correct layout: DialogShell / DialogCard post it after a\n      // double-rAF, i.e. once the centered fullViewport card is on screen.\n      if (event.data?.type === \"PASSKEY_RENDERED\") {\n        revealIframe();\n      }\n      // PASSKEY_READY fires on mount, BEFORE the iframe has painted the\n      // fullViewport layout. The dialog page server-renders with\n      // `fullViewport=false` (no `window` on the server), so its first client\n      // paint is the embedded, full-width Loading card; the centered layout\n      // only lands after the URL-seeded client re-render. Revealing the\n      // iframe on READY therefore flashes that full-width card for a frame or\n      // two — the exact \"loading screen flash\" we're avoiding. So READY does\n      // NOT reveal directly; it only arms a short fallback in case RENDERED is\n      // lost (redirect remount, dropped frame). By the time this fires the\n      // layout has long settled, so we still never expose the full-width card —\n      // and we recover far faster than the 8s `revealFailsafe`. Every modal\n      // route (auth/connect/account/grant-permission/sign/sign-eoa) reliably\n      // posts RENDERED in fullViewport mode, so in healthy flows this never\n      // fires.\n      else if (\n        event.data?.type === \"PASSKEY_READY\" &&\n        !revealed &&\n        readyFailsafe === undefined\n      ) {\n        readyFailsafe = setTimeout(revealIframe, 1000);\n      }\n      // Application-session cleanup is handled by the client-wide listener so\n      // popup and iframe transports share one idempotent path.\n    };\n    window.addEventListener(\"message\", handleMessage);\n\n    // Append `fullViewport=1` so the iframe's DialogProvider can seed its\n    // initial state synchronously. Without this, `fullViewport` defaults to\n    // false until PASSKEY_INIT arrives by postMessage — and on slow runs the\n    // first paint of Loading.tsx renders as an embedded (full-width, top-of-\n    // iframe) card before the message corrects it. Since we reveal the iframe\n    // on PASSKEY_RENDERED, that wrong layout would be briefly visible.\n    // Reading the flag from the URL eliminates the race.\n    const iframeUrl = new URL(url, window.location.href);\n    iframeUrl.searchParams.set(\"fullViewport\", \"1\");\n    iframe.setAttribute(\"src\", iframeUrl.toString());\n    dialog.appendChild(iframe);\n\n    // Tell the dialog about the parent viewport so its DialogCard can\n    // cap at 75% of screen height. Modal flow sets `fullViewport:\n    // true` (which uses its own `calc(100dvh - 100px)` outer cap and\n    // makes this no-op), but we wire it up defensively so any future\n    // non-fullViewport modal route picks up the same gating without\n    // a separate SDK change.\n    const viewportInfoCleanup = this.wireViewportInfo(iframe);\n\n    // 1Password extension adds `inert` attribute to <dialog>, making it\n    // non-interactive. Watch for this and remove it immediately.\n    const inertObserver = new MutationObserver((mutations) => {\n      for (const mutation of mutations) {\n        if (mutation.attributeName === \"inert\") {\n          dialog.removeAttribute(\"inert\");\n        }\n      }\n    });\n    inertObserver.observe(dialog, { attributes: true });\n\n    // Handle escape key\n    const handleEscape = (event: KeyboardEvent) => {\n      if (event.key === \"Escape\") {\n        cleanup();\n      }\n    };\n    document.addEventListener(\"keydown\", handleEscape);\n\n    const reveal = () => {\n      delete dialog.dataset.passkeyHidden;\n      if (!revealed) {\n        revealed = true;\n        clearTimeout(readyFailsafe);\n        clearTimeout(revealFailsafe);\n      }\n      iframe.style.opacity = \"1\";\n      overlay.style.display = \"none\";\n    };\n\n    // Re-assert `target` as the host scroll position across the browser's\n    // focus-restore scroll. That scroll fires when a focus-stealing child\n    // window closes (the `/sign-ceremony` popup, a PM popout, an OAuth popup)\n    // OR when `dialog.close()` hands focus back to the element that opened the\n    // modal — and it does NOT reliably land within a fixed rAF or two: some\n    // browser×password-manager combos scroll several frames late, so a one-shot\n    // restore loses the race and the page snaps (usually to the top). Instead\n    // correct every frame for a short budget — once the browser's scroll lands\n    // we snap it straight back, and every other frame is a cheap no-op. The\n    // budget is short enough never to fight a deliberate user scroll, and while\n    // it runs the modal is either up (host isn't scrollable behind it) or was\n    // just torn down (position must be held through the close).\n    // ponytail: 18-frame (~300ms) budget — bump only if a browser restores later.\n    const RESTORE_FRAME_BUDGET = 18;\n    const holdScroll = (target: number) => {\n      let frames = 0;\n      const tick = () => {\n        if (window.scrollY !== target) {\n          window.scrollTo({ top: target, left: window.scrollX, behavior: \"auto\" });\n        }\n        if (++frames < RESTORE_FRAME_BUDGET) requestAnimationFrame(tick);\n      };\n      tick();\n    };\n\n    // Snapshot the settled scroll (after any host-app re-centering) when a\n    // focus-stealing child window opened *by the passkey iframe while this\n    // dialog is open* blurs the host — chiefly its top-level `/sign-ceremony`\n    // popup (browser×password-manager combos that can't run WebAuthn inline)\n    // and OAuth popups — then re-apply it when focus returns. The SDK's iframe\n    // never leaves the DOM, so an integrator's own dialog-lifecycle scroll\n    // handling never fires. Gated on `dialog.open` so a closed persistent\n    // dialog never hijacks page scroll; the teardown path (see `destroy`)\n    // covers the symmetric snap when the dialog itself closes.\n    let scrollBeforeBlur: number | null = null;\n    const onHostBlur = () => {\n      if (dialog.open) scrollBeforeBlur = window.scrollY;\n    };\n    const onHostFocus = () => {\n      if (!dialog.open || scrollBeforeBlur === null) return;\n      holdScroll(scrollBeforeBlur);\n    };\n    window.addEventListener(\"blur\", onHostBlur);\n    window.addEventListener(\"focus\", onHostFocus);\n\n    // Hidden blind-signing requests must not make the host page inert. They\n    // still need a rendered iframe so the passkey origin can run WebAuthn.\n    if (options?.hidden) {\n      dialog.show();\n    } else {\n      dialog.showModal();\n    }\n\n    let cleanedUp = false;\n    const destroy = () => {\n      if (cleanedUp) return;\n      cleanedUp = true;\n      clearTimeout(revealFailsafe);\n      clearTimeout(readyFailsafe);\n      inertObserver.disconnect();\n      viewportInfoCleanup();\n      window.removeEventListener(\"message\", handleMessage);\n      window.removeEventListener(\"blur\", onHostBlur);\n      window.removeEventListener(\"focus\", onHostFocus);\n      document.removeEventListener(\"keydown\", handleEscape);\n      // Preserve host scroll across the close's focus-restore. Closing a modal\n      // <dialog> returns focus to whatever opened it (e.g. the integrator's\n      // trigger button, which after a pre-dialog re-center can sit near the top\n      // of the page), and the browser scroll-restores to that element — snapping\n      // the page to the top the moment the card vanishes. The blur/focus path\n      // above is gated on `dialog.open`, so it cannot cover this. Skip hidden\n      // (blind-signing) frames: off-screen, with no user scroll position to hold.\n      const scrollAtClose = !options?.hidden && dialog.open ? window.scrollY : null;\n      dialog.close();\n      // Clean up 1Password inert attributes left on dialog siblings\n      if (dialog.parentNode) {\n        for (const sibling of Array.from(dialog.parentNode.children)) {\n          if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute(\"inert\")) {\n            sibling.removeAttribute(\"inert\");\n          }\n        }\n      }\n      dialog.remove();\n      if (scrollAtClose !== null) holdScroll(scrollAtClose);\n    };\n\n    // In persistent mode the iframe lives across many open/close cycles\n    // (used by `requestWithWallet` so the WalletConnect SignClient inside\n    // the iframe is not recreated for every EOA request). `cleanup` here\n    // just hides the dialog; full teardown is reachable via `destroy`.\n    const cleanup = options?.persistent\n      ? () => {\n          if (!dialog.open) return;\n          // Same close-time focus-restore snap as `destroy`; hold scroll here\n          // too so hiding a persistent dialog doesn't jump the host page.\n          const scrollAtClose = options?.hidden ? null : window.scrollY;\n          dialog.close();\n          if (scrollAtClose !== null) holdScroll(scrollAtClose);\n        }\n      : destroy;\n\n    return { dialog, iframe, cleanup, destroy, reveal };\n  }\n\n  /**\n   * Listen for the auth result from the modal dialog.\n   *\n   * Each modal call generates a per-session nonce that the iframe must\n   * echo back in `PASSKEY_CLOSE` / `PASSKEY_LOGIN_RESULT` /\n   * `PASSKEY_RETRY_POPUP` messages. Without an echo, a queued CLOSE\n   * from the previous iframe could be dispatched to the new modal's\n   * listener (postMessage events tagged with `event.source` from a now-\n   * destroyed iframe still reach the parent's message handler) and\n   * silently cancel the fresh auth attempt. The nonce makes that race\n   * harmless: a stale message that doesn't carry the current modal's\n   * nonce is ignored.\n   *\n   * Also handles the `PASSKEY_RETRY_POPUP` message: sent by the dialog when a\n   * password manager (e.g. Bitwarden) intercepts the WebAuthn call inside the\n   * iframe. In that case the SDK seamlessly re-opens a standalone popup window,\n   * where WebAuthn works without cross-origin iframe restrictions, and waits\n   * for the result from there instead.\n   *\n   * @param _dialog - Unused; kept for signature consistency.\n   * @param iframe - The iframe element; used to send `PASSKEY_INIT` on ready.\n   * @param cleanup - Idempotent teardown for the modal dialog.\n   * @returns An `AuthResult` discriminated union.\n   */\n  private waitForModalAuthResponse(\n    _dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    requestId?: string\n  ): Promise<AuthResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    // Per-modal nonce so stale messages from a previous iframe can't\n    // cancel a fresh auth attempt. The dialog echoes this back on every\n    // result-bearing message; messages without the matching nonce are\n    // ignored.\n    const modalNonce = generateModalNonce();\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n        const data = event.data;\n\n        const matchesSource = event.source === iframe.contentWindow;\n        const matchesRequest =\n          typeof requestId === \"string\" && data?.requestId === requestId;\n        const matchesNonce = data?.modalNonce === modalNonce;\n        const isCurrentFrameClose =\n          data?.type === \"PASSKEY_CLOSE\" && matchesSource;\n\n        if (\n          data?.type === \"PASSKEY_CLOSE\" &&\n          (matchesRequest || matchesNonce || isCurrentFrameClose)\n        ) {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            error: {\n              code: \"USER_CANCELLED\",\n              message: \"Authentication was cancelled\",\n            },\n          });\n          return;\n        }\n\n        // Send init message once the dialog signals it's ready to receive\n        // it; many entry routes fire this from their first useEffect.\n        // The nonce travels with INIT and the dialog stores it for later\n        // echo on CLOSE / RESULT messages.\n        if (data?.type === \"PASSKEY_READY\") {\n\n          iframe.contentWindow?.postMessage({\n            type: \"PASSKEY_INIT\",\n            mode: \"iframe\",\n            fullViewport: true,\n            modalNonce,\n          }, dialogOrigin);\n          return;\n        }\n\n        const hasModalNonce = typeof data?.modalNonce === \"string\";\n        const isCurrentDialogMessage =\n          matchesSource || matchesNonce || !hasModalNonce;\n        if (!isCurrentDialogMessage) return;\n\n        // Result-bearing messages without the current modal's nonce are\n        // late-arriving CLOSE / RESULT events from a previously cleaned-\n        // up iframe (postMessage queue, tab-throttling, etc.). Drop them\n        // so they can't cancel or hijack the fresh modal.\n        if (data?.modalNonce && data.modalNonce !== modalNonce) return;\n\n        if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n\n          if (data.success) {\n            resolve({\n              success: true,\n              user: {\n                id: data.data?.user?.id,\n                address: data.data?.address as `0x${string}`,\n              },\n              signerType: data.data?.signerType ?? \"passkey\",\n            });\n          } else {\n            resolve({\n              success: false,\n              error: data.error,\n            });\n          }\n        } else if (data?.type === \"PASSKEY_RETRY_POPUP\") {\n          // Password manager (e.g. Bitwarden) interfered with WebAuthn in iframe\n          // Retry in popup mode where WebAuthn works without cross-origin restrictions\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n\n          // Get the current dialog URL and switch to popup mode\n          const popupUrl = data.data?.url?.replace(\"mode=iframe\", \"mode=popup\")\n            || `${this.getDialogUrl()}/dialog/auth?mode=popup${this.config.clientId ? `&clientId=${this.config.clientId}` : ''}`;\n\n          // Open popup and wait for result\n          this.waitForPopupAuthResponse(popupUrl).then(resolve);\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Open a popup for auth and wait for the result.\n   * Used when iframe mode fails (e.g., due to password manager interference).\n   */\n  private waitForPopupAuthResponse(url: string): Promise<AuthResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    const modalNonce = generateModalNonce();\n    const popup = this.openPopup(url);\n\n    if (!popup) {\n      return Promise.resolve({\n        success: false,\n        error: {\n          code: \"USER_CANCELLED\",\n          message: \"Authentication was cancelled\",\n        },\n      });\n    }\n\n    return new Promise((resolve) => {\n      let settled = false;\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin || event.source !== popup) return;\n\n        const data = event.data;\n        if (data?.type === \"PASSKEY_READY\") {\n          popup.postMessage({\n            type: \"PASSKEY_INIT\",\n            mode: \"popup\",\n            fullViewport: true,\n            modalNonce,\n          }, dialogOrigin);\n          return;\n        }\n\n        if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n          finish(\n            data.success\n              ? {\n                  success: true,\n                  user: {\n                    id: data.data?.user?.id,\n                    address: data.data?.address as `0x${string}`,\n                  },\n                  signerType: data.data?.signerType ?? \"passkey\",\n                }\n              : { success: false, error: data.error },\n            true,\n          );\n        } else if (data?.type === \"PASSKEY_CLOSE\") {\n          finish({\n            success: false,\n            error: {\n              code: \"USER_CANCELLED\",\n              message: \"Authentication was cancelled\",\n            },\n          }, true);\n        }\n      };\n\n      const finish = (result: AuthResult, closePopup: boolean) => {\n        if (settled) return;\n        settled = true;\n        clearInterval(pollTimer);\n        window.removeEventListener(\"message\", handleMessage);\n        if (closePopup) popup.close();\n        resolve(result);\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n\n      // Poll because users can close the popup without sending PASSKEY_CLOSE.\n      const pollTimer = setInterval(() => {\n        if (popup.closed) {\n          finish({\n            success: false,\n            error: {\n              code: \"USER_CANCELLED\",\n              message: \"Authentication was cancelled\",\n            },\n          }, false);\n        }\n      }, 500);\n    });\n  }\n\n  /**\n   * Listen for the connect result from the connect dialog.\n   *\n   * The connect flow is a lightweight \"are you still you?\" confirmation that\n   * does not require a new passkey ceremony. On success, the dialog returns the\n   * user's address and an `autoConnected` flag indicating whether the\n   * user had previously enabled auto-connect (in which case no UI was shown).\n   *\n   * On failure with `action: \"switch\"`, the caller should redirect to the full\n   * auth flow because the user has no cached session to confirm.\n   *\n   * @param _dialog - Unused; kept for signature consistency.\n   * @param _iframe - Unused; kept for signature consistency.\n   * @param cleanup - Idempotent teardown for the modal dialog.\n   * @returns A `ConnectResult` discriminated union.\n   */\n  private waitForConnectResponse(\n    _dialog: HTMLDialogElement,\n    _iframe: HTMLIFrameElement,\n    cleanup: () => void\n  ): Promise<ConnectResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const data = event.data;\n        if (data?.type === \"PASSKEY_CONNECT_RESULT\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n\n          if (data.success) {\n            resolve({\n              success: true,\n              user: {\n                address: data.data?.address as `0x${string}`,\n              },\n              // Carry the signer type through so the SDK/provider can route EOA\n              // sessions to the connected wallet (plain tx, no intents) instead\n              // of defaulting to passkey intents. Absent = legacy passkey.\n              signerType: data.data?.signerType ?? \"passkey\",\n              autoConnected: data.data?.autoConnected,\n            });\n          } else {\n            resolve({\n              success: false,\n              action: data.data?.action,\n              error: data.error,\n            });\n          }\n        } else if (data?.type === \"PASSKEY_CLOSE\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            action: \"cancel\",\n            error: {\n              code: \"USER_CANCELLED\",\n              message: \"Connection was cancelled\",\n            },\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Listen for grant-permission results and bridge sponsorship token requests.\n   *\n   * The grant iframe owns the passkey ceremony and install intent submission.\n   * Extension-token minting stays in the app origin, so the SDK exposes a\n   * narrow postMessage round-trip that never gives the iframe app secrets.\n   *\n   * @param _dialog - Unused; kept for signature consistency.\n   * @param iframe - The grant iframe that receives extension-token responses.\n   * @param cleanup - Idempotent teardown for the modal dialog.\n   * @param sponsor - Whether this grant flow should request an extension token.\n   * @returns A `GrantPermissionsResult` discriminated union.\n   */\n  private waitForGrantPermissionResponse(\n    dialog: HTMLDialogElement,\n    iframe: HTMLIFrameElement,\n    cleanup: () => void,\n    sponsor: boolean,\n    initPayload: Record<string, unknown>\n  ): Promise<GrantPermissionsResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      let readySeen = false;\n\n      const teardown = () => {\n        clearTimeout(readyTimeout);\n        window.removeEventListener(\"message\", handleMessage);\n        dialog.removeEventListener(\"close\", handleClose);\n      };\n\n      const postInit = () => {\n        iframe.contentWindow?.postMessage(\n          { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n          dialogOrigin,\n        );\n      };\n\n      const handleClose = () => {\n        teardown();\n        resolve({\n          success: false,\n          error: {\n            code: \"USER_CANCELLED\",\n            message: \"User closed the dialog\",\n          },\n        });\n      };\n\n      const handleMessage = async (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const data = event.data;\n\n        if (data?.type === \"PASSKEY_READY\") {\n          readySeen = true;\n          clearTimeout(readyTimeout);\n          // Grant iframe routes can remount in dev/HMR and after Suspense\n          // boundaries. Re-send init on every READY so the review page never\n          // gets stranded on its initial loading state.\n          postInit();\n          return;\n        }\n\n        if (data?.type === \"PASSKEY_GRANT_EXTENSION_TOKEN_REQUEST\") {\n          const requestId = data.requestId as string | undefined;\n          const intentOp = data.intentOp as string | undefined;\n          const postResponse = (payload: Record<string, unknown>) => {\n            iframe.contentWindow?.postMessage(\n              { type: \"PASSKEY_GRANT_EXTENSION_TOKEN_RESPONSE\", requestId, ...payload },\n              dialogOrigin\n            );\n          };\n\n          if (!requestId || !intentOp) {\n            postResponse({ success: false, error: \"Invalid extension token request\" });\n            return;\n          }\n\n          if (!sponsor) {\n            postResponse({ success: true });\n            return;\n          }\n\n          if (!this.sponsorship) {\n            postResponse({ success: false, error: MISSING_APP_CREDENTIALS_MESSAGE });\n            return;\n          }\n\n          try {\n            const token = await this.sponsorship.getExtensionToken(intentOp);\n            postResponse({ success: true, token });\n          } catch (err) {\n            postResponse({\n              success: false,\n              error: err instanceof Error ? err.message : String(err),\n            });\n          }\n          return;\n        }\n\n        if (data?.type === \"PASSKEY_GRANT_PERMISSION_RESULT\") {\n          if (data.success) {\n            // Resolve the grant result but DELIBERATELY keep the dialog open.\n            // The grant dialog's `success` state renders a \"Permission granted\"\n            // confirmation with a green Done button (mirroring the sign flow's\n            // `confirmed` screen). Calling cleanup() here — as we still do on\n            // the failure path — would destroy that iframe before it paints, so\n            // the user would never see a success screen. Instead we just stop\n            // listening for grant messages; grantPermissions() then awaits\n            // waitForDialogClose() so the confirmation stays up until the user\n            // clicks Done (PASSKEY_CLOSE). This matches sendIntent, where\n            // waitForSigningResponse resolves on success without cleanup and the\n            // caller awaits the dialog close.\n            teardown();\n            resolve({ success: true, ...(data.data ?? {}) });\n            return;\n          }\n\n          // Failure: there's no success screen to preserve, and the passkey app\n          // sends PASSKEY_CLOSE right after this RESULT — but teardown() removes\n          // the listener, so that follow-up would be dropped. Close here, the\n          // same way the sign failure path does.\n          teardown();\n          cleanup();\n          resolve({\n            success: false,\n            error: data.error ?? data.data?.error ?? {\n              code: \"GRANT_PERMISSION_FAILED\",\n              message: \"Permission grant failed\",\n            },\n          });\n        } else if (\n          data?.type === \"PASSKEY_CLOSE\" &&\n          event.source === iframe.contentWindow\n        ) {\n          // Same cross-frame guard as the sign/ready paths: a stray\n          // PASSKEY_CLOSE from another same-origin dialog (e.g. an auth modal\n          // tearing down) must not cancel an in-flight grant. Only honor the\n          // close from THIS grant iframe.\n          teardown();\n          cleanup();\n          resolve({\n            success: false,\n            error: {\n              code: \"USER_CANCELLED\",\n              message: \"User closed the dialog\",\n            },\n          });\n        }\n      };\n\n      const readyTimeout = setTimeout(() => {\n        if (readySeen) return;\n        teardown();\n        cleanup();\n        resolve({\n          success: false,\n          error: {\n            code: \"USER_CANCELLED\",\n            message: \"User closed the dialog\",\n          },\n        });\n      }, 10000);\n\n      window.addEventListener(\"message\", handleMessage);\n      dialog.addEventListener(\"close\", handleClose);\n    });\n  }\n\n  /**\n   * Listen for a signing result from a server-request-based modal dialog.\n   *\n   * Similar to `waitForIntentSigningResponse` but intended for the older\n   * `signWithModal` path that pre-creates a signing request via the API (rather\n   * than inlining all data in `PASSKEY_INIT`). Filters by `requestId` to handle\n   * the case where stale messages from a previous dialog may still be in flight.\n   *\n   * @param requestId - The signing request ID to match against incoming messages.\n   * @param _dialog - Unused; kept for signature consistency.\n   * @param _iframe - Unused; kept for signature consistency.\n   * @param cleanup - Idempotent teardown that closes and removes the dialog.\n   * @returns A `SigningResult` discriminated union.\n   */\n  private waitForModalSigningResponse(\n    requestId: string,\n    _dialog: HTMLDialogElement,\n    _iframe: HTMLIFrameElement,\n    cleanup: () => void\n  ): Promise<SigningResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) return;\n\n        const message = event.data;\n        // The Messenger sends: { type, success, data: { requestId, signature }, error }\n        // So we need to check message.data.requestId, not message.requestId\n        const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tcleanup();\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\trequestId,\n\t\t\t\terror: { code: \"USER_REJECTED\", message: \"Session disconnected\" },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n\n          if (message.success && payload.signature) {\n            resolve({\n              success: true,\n              requestId,\n              signature: payload.signature,\n            });\n          } else {\n            resolve({\n              success: false,\n              requestId,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        } else if (message?.type === \"PASSKEY_CLOSE\") {\n          window.removeEventListener(\"message\", handleMessage);\n          cleanup();\n          resolve({\n            success: false,\n            requestId,\n            error: {\n              code: \"USER_REJECTED\",\n              message: \"Signing was cancelled\",\n            },\n          });\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Listen for a signing result from a popup window.\n   *\n   * Polls for popup closure every 500 ms as a fallback to detect when the user\n   * closes the popup without completing the signing flow (no `PASSKEY_CLOSE`\n   * message is fired in that case because the popup's unload event cannot\n   * reliably postMessage to the opener on all browsers).\n   *\n   * On success or cancellation, the popup is programmatically closed and the\n   * interval is cleared.\n   *\n   * @param requestId - The signing request ID to match against incoming messages.\n   * @param popup - The popup `Window` reference returned by `openPopup`.\n   * @returns A `SigningResult` discriminated union.\n   */\n  private waitForPopupResponse(\n    requestId: string,\n    popup: Window\n  ): Promise<SigningResult> {\n    const dialogOrigin = this.getDialogOrigin();\n    return new Promise((resolve) => {\n      const checkClosed = setInterval(() => {\n        if (popup.closed) {\n          clearInterval(checkClosed);\n          window.removeEventListener(\"message\", handleMessage);\n          resolve({\n            success: false,\n            requestId,\n            error: {\n              code: \"USER_REJECTED\",\n              message: \"Popup was closed without completing\",\n            },\n          });\n        }\n      }, 500);\n\n      const handleMessage = (event: MessageEvent) => {\n        if (event.origin !== dialogOrigin) {\n          return;\n        }\n\n        const message = event.data;\n        // The Messenger sends: { type, success, data: { requestId, signature }, error }\n        const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n\t\tif (message?.type === \"PASSKEY_DISCONNECT\") {\n\t\t\tclearInterval(checkClosed);\n\t\t\twindow.removeEventListener(\"message\", handleMessage);\n\t\t\tpopup.close();\n\t\t\tresolve({\n\t\t\t\tsuccess: false,\n\t\t\t\trequestId,\n\t\t\t\terror: { code: \"USER_REJECTED\", message: \"Session disconnected\" },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n        if (\n          message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n          payload?.requestId === requestId\n        ) {\n          clearInterval(checkClosed);\n          window.removeEventListener(\"message\", handleMessage);\n          popup.close();\n\n          if (message.success && payload.signature) {\n            resolve({\n              success: true,\n              requestId,\n              signature: payload.signature,\n            });\n          } else {\n            resolve({\n              success: false,\n              requestId,\n              error: parseSigningResultError(message.error),\n            });\n          }\n        }\n      };\n\n      window.addEventListener(\"message\", handleMessage);\n    });\n  }\n\n  /**\n   * Fetch the completed signing result from the passkey service by request ID.\n   *\n   * Used by the redirect flow: after the passkey service redirects back to\n   * `redirectUrl`, the integrator calls `handleRedirectCallback()`, which\n   * extracts `requestId` from the URL query params and delegates here to\n   * retrieve the full signature from the server.\n   *\n   * @param requestId - The signing request ID from the redirect callback URL.\n   * @returns A `SigningResult` discriminated union.\n   */\n  private async fetchSigningResult(requestId: string): Promise<SigningResult> {\n    const response = await fetch(\n      `${this.config.providerUrl}/api/sign/request/${requestId}`,\n      {\n        headers: this.config.clientId\n          ? { \"x-client-id\": this.config.clientId }\n          : {},\n      }\n    );\n\n    if (!response.ok) {\n      return {\n        success: false,\n        requestId,\n        error: {\n          code: \"NETWORK_ERROR\",\n          message: \"Failed to fetch signing result\",\n        },\n      };\n    }\n\n    const data = (await response.json()) as Omit<SigningRequestStatus, \"error\"> & { error?: unknown };\n\n    if (data.status === \"COMPLETED\" && data.signature) {\n      return {\n        success: true,\n        requestId,\n        signature: data.signature,\n      };\n    }\n\n    const error = parseSigningResultError(\n      data.error,\n      data.status === \"EXPIRED\" ? \"EXPIRED\" : \"UNKNOWN\",\n      `Request status: ${data.status}`,\n    );\n    return {\n      success: false,\n      requestId,\n      error: {\n        ...error,\n      },\n    };\n  }\n}\n","import { isTestnet } from \"./registry\";\nimport type { AssetBalance, AssetsResponse } from \"./types\";\n\ntype PortfolioChainBalance = {\n  chainId?: number;\n  chain?: number;\n  address?: string;\n  token?: string;\n  balance?: string;\n  amount?: string;\n  decimals?: number;\n  isTestnet?: boolean;\n};\n\ntype PortfolioAsset = {\n  symbol?: string;\n  decimals?: number;\n  balance?: string;\n  amount?: string;\n  address?: string;\n  token?: string;\n  usdValue?: number;\n  chains?: PortfolioChainBalance[];\n};\n\ntype FetchAssetsResponseOptions = {\n  providerUrl: string;\n  identifier: string;\n  clientId?: string;\n  accessToken?: string;\n  headers?: Record<string, string>;\n};\n\n/**\n * Mark a normalized portfolio row with a stable network bucket flag.\n */\nfunction withNetworkBucket(balance: AssetBalance): AssetBalance {\n  return {\n    ...balance,\n    isTestnet: balance.isTestnet ?? isTestnet(balance.chainId),\n  };\n}\n\n/**\n * Split normalized balances into explicit mainnet and testnet buckets.\n */\nfunction bucketAssetBalances(balances: AssetBalance[]): Pick<\n  AssetsResponse,\n  \"mainnets\" | \"testnets\"\n> {\n  const mainnetBalances: AssetBalance[] = [];\n  const testnetBalances: AssetBalance[] = [];\n\n  for (const balance of balances) {\n    const normalized = withNetworkBucket(balance);\n    if (normalized.isTestnet) {\n      testnetBalances.push(normalized);\n    } else {\n      mainnetBalances.push(normalized);\n    }\n  }\n\n  return {\n    mainnets: { balances: mainnetBalances },\n    testnets: { balances: testnetBalances },\n  };\n}\n\n/**\n * Convert passkey portfolio responses into the documented assets response.\n */\nexport function normalizeAssetsResponse(payload: unknown): AssetsResponse {\n  const data = payload && typeof payload === \"object\"\n    ? (payload as Record<string, unknown>)\n    : {};\n  if (Array.isArray(data.balances)) {\n    const balances = (data.balances as AssetBalance[]).map(withNetworkBucket);\n    const buckets = bucketAssetBalances(balances);\n    return { ...data, balances, ...buckets };\n  }\n\n  const balances: AssetBalance[] = [];\n  const assets = Array.isArray(data.assets) ? (data.assets as PortfolioAsset[]) : [];\n  for (const asset of assets) {\n    const symbol = asset.symbol ?? \"UNKNOWN\";\n    const decimals = asset.decimals ?? 18;\n    const chains = Array.isArray(asset.chains) ? asset.chains : [];\n\n    if (chains.length === 0) {\n      const token = asset.token ?? asset.address;\n      if (token) {\n        balances.push(withNetworkBucket({\n          chainId: 0,\n          token,\n          symbol,\n          decimals,\n          balance: asset.balance ?? asset.amount ?? \"0\",\n          ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n        }));\n      }\n      continue;\n    }\n\n    for (const chain of chains) {\n      const chainId = chain.chainId ?? chain.chain;\n      const token = chain.token ?? chain.address;\n      if (typeof chainId !== \"number\" || !token) continue;\n      balances.push(withNetworkBucket({\n        chainId,\n        token,\n        symbol,\n        decimals: chain.decimals ?? decimals,\n        balance: chain.balance ?? chain.amount ?? \"0\",\n        ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n        ...(chain.isTestnet !== undefined && { isTestnet: chain.isTestnet }),\n      }));\n    }\n  }\n\n  return { ...data, balances, ...bucketAssetBalances(balances) };\n}\n\n/**\n * Fetch the unified passkey portfolio and return normalized wallet assets.\n */\nexport async function fetchAssetsResponse(\n  options: FetchAssetsResponseOptions,\n): Promise<AssetsResponse> {\n  const portfolioUrl = new URL(\n    `/api/users/${encodeURIComponent(options.identifier)}/portfolio`,\n    options.providerUrl,\n  );\n  // `all=true` keeps the SDK from silently hiding testnet balances when the\n  // caller is using a mixed mainnet/testnet account during dogfooding.\n  portfolioUrl.searchParams.set(\"all\", \"true\");\n\n  const response = await fetch(portfolioUrl.toString(), {\n    headers: {\n      ...options.headers,\n      ...(options.accessToken ? { Authorization: `Bearer ${options.accessToken}` } : {}),\n      ...(options.clientId ? { \"x-client-id\": options.clientId } : {}),\n    },\n  });\n  if (!response.ok) {\n    const data = await response.json().catch(() => ({}));\n    throw new Error(data.error || \"Failed to get assets\");\n  }\n  return normalizeAssetsResponse(await response.json());\n}\n","// Shared constants for the loading screen that's rendered in two places:\n//   1. packages/sdk/src/client.ts — host-page overlay (vanilla DOM, before\n//      the passkey iframe paints).\n//   2. apps/passkey/src/components/dialog/screens/Loading.tsx — same screen\n//      drawn by the iframe via React + DialogShell + IconWithStatus.\n//\n// The handoff between the two is a crossfade on `PASSKEY_RENDERED`, so any\n// drift in geometry / colour / copy produces a visible flash. SDK-side\n// values live here instead of being inlined; the iframe side imports from\n// here too. If a value isn't in this file, BOTH sides duplicated it inline\n// — drift is now likely.\n//\n// Theme tokens are mirrored from apps/passkey/src/app/globals.css. If the\n// CSS values change there, update the LIGHT/DARK pairs below in the same PR.\n\n// === Spinner geometry =====================================================\n// 82×82 SVG with two concentric circles; the foreground arc covers 17 % of\n// the circumference and rotates via CSS `animate-spin`.\nexport const SPINNER_SIZE = 82;\nexport const SPINNER_STROKE = 2.4118;\nexport const SPINNER_RADIUS = (SPINNER_SIZE - SPINNER_STROKE) / 2;\nexport const SPINNER_CIRCUMFERENCE = 2 * Math.PI * SPINNER_RADIUS;\nexport const SPINNER_ARC_FRACTION = 0.17;\nexport const SPINNER_ARC = SPINNER_CIRCUMFERENCE * SPINNER_ARC_FRACTION;\n// One full rotation, in ms. Shared so the SDK host-page overlay and the\n// iframe's `IconWithStatus` spinner rotate at the SAME rate — otherwise the\n// arc visibly changes speed at the PASSKEY_RENDERED crossfade and the two\n// loading screens read as different. The iframe side previously inherited\n// Tailwind's `animate-spin` default (1s) while the SDK hardcoded 0.8s.\nexport const SPINNER_SPIN_DURATION_MS = 800;\n\n// === Modal geometry =======================================================\n// Mirrors apps/passkey DialogShell's full-viewport iframe placement:\n// centered desktop card at Tailwind's `sm` breakpoint, bottom sheet below it.\n// Source of truth: Figma \"Sizing changes\" frame (3036:9897) — Modal width\n// is 380px on desktop. Must stay in sync with `--spacing-modal-width` /\n// `--spacing-modal-padding` in apps/passkey/src/app/globals.css and with\n// the SDK's POPUP_WIDTH / DEFAULT_EMBED_WIDTH in packages/sdk/src/client.ts.\nexport const LOADING_MODAL_WIDTH = 380;\nexport const LOADING_MODAL_PADDING = 12;\nexport const LOADING_MODAL_RADIUS = 16;\nexport const LOADING_MOBILE_BREAKPOINT = 640;\n\n// === Spacing (inside the card) ============================================\n// Vertical rhythm between body and footer, and within the body block.\n// 16px between body and footer is the same value DialogShell uses for the\n// outer column gap; we keep them in lockstep so embedded dialogs share the\n// rhythm too.\nexport const LOADING_CARD_GAP = 16;\nexport const LOADING_BODY_GAP = 12;\nexport const LOADING_ICON_PADDING = 12;\nexport const LOADING_TITLE_BLOCK_GAP = 4;\nexport const LOADING_FOOTER_GAP = 4;\n\n// === Typography ===========================================================\n// Title + subtitle + footer. `line-height: normal` is critical: the host\n// page may set a different value on <body> (Tailwind preflight 1.5, etc)\n// and inheritance would otherwise blow up the card height.\nexport const LOADING_TITLE_FONT_SIZE = 20;\nexport const LOADING_TITLE_FONT_WEIGHT = 700;\nexport const LOADING_SUBTITLE_FONT_SIZE = 12;\nexport const LOADING_SUBTITLE_FONT_WEIGHT = 500;\nexport const LOADING_FOOTER_FONT_SIZE = 11;\nexport const LOADING_FOOTER_FONT_WEIGHT = 500;\nexport const LOADING_LINE_HEIGHT = \"normal\" as const;\n// Font stack matches `data-connect-v2` in apps/passkey globals.css. Inter\n// is loaded by the host app; the rest are safe fallbacks. Includes emoji\n// stack for screens that render copy with emoji characters.\nexport const LOADING_FONT_FAMILY =\n  \"'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'\";\n\n// === Rhinestone wordmark ==================================================\n// Footer \"Powered by [logo]\". Source SVG is 72×16; both consumers render\n// at native size.\nexport const LOGO_WIDTH = 72;\nexport const LOGO_HEIGHT = 16;\n\n// === Brand colour =========================================================\n// Mirrors `--color-primary-500` in apps/passkey globals.css.\nexport const BRAND_PURPLE = \"#685bff\";\n\n// === Theme tokens =========================================================\n// Hex pairs mirroring the iframe's `light-dark()` CSS custom properties.\n// The host-page SDK overlay can't read those custom properties (different\n// document), so it picks light/dark from the `theme` URL param and falls\n// back to `prefers-color-scheme`.\nexport type LoadingThemeTokens = {\n  /** `--color-modal-bg` */\n  bgPrimary: string;\n  /** `--color-modal-border` */\n  borderColor: string;\n  /** `--color-view-text-primary` */\n  textPrimary: string;\n  /** `--color-view-text-secondary` */\n  textSecondary: string;\n};\n\nexport const LIGHT_TOKENS: LoadingThemeTokens = {\n  bgPrimary: \"#ffffff\",\n  borderColor: \"#f4f4f5\",\n  textPrimary: \"#27272a\",\n  textSecondary: \"#71717b\",\n};\n\nexport const DARK_TOKENS: LoadingThemeTokens = {\n  bgPrimary: \"#0a0a0a\",\n  borderColor: \"#18181b\",\n  textPrimary: \"#e4e4e7\",\n  textSecondary: \"#9f9fa9\",\n};\n\n// `--color-modal-text-footer` — a single value across both themes.\nexport const FOOTER_TEXT_COLOR = \"#71717b\";\n\n// === Copy =================================================================\nexport const LOADING_TITLE = \"Loading...\";\nexport const LOADING_SUBTITLE =\n  \"This will only take a few moments, do not close the window.\";\n","/**\n * EIP-1193 JSON-RPC provider factory for the 1auth passkey authentication system.\n *\n * Creates a browser-side provider object that implements the EIP-1193 standard so any\n * Ethereum library (ethers, viem, wagmi) can use 1auth passkey signing and cross-chain\n * intent execution without modification. All transaction signing is delegated to the\n * passkey service rather than holding private keys in the browser.\n *\n * Supported RPC methods:\n *   - eth_chainId, eth_accounts, eth_requestAccounts\n *   - personal_sign, eth_sign, eth_signTypedData, eth_signTypedData_v4\n *   - eth_sendTransaction\n *   - wallet_connect, wallet_disconnect, wallet_switchEthereumChain\n *   - wallet_sendCalls, wallet_getCallsStatus, wallet_getCallsHistory (EIP-5792)\n *   - wallet_getCapabilities, wallet_getAssets\n *\n * @module\n */\n\nimport {\n  hexToString,\n  isHex,\n  numberToHex,\n  type Address,\n  type Hex,\n} from \"viem\";\nimport { OneAuthClient, registerSessionForgetHandler } from \"./client\";\nimport { getSupportedChainIds } from \"./registry\";\nimport type { CloseOnStatus, IntentCall, IntentTokenRequest, SignerType } from \"./types\";\nimport { toOneAuthError } from \"./errors\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\ntype ProviderRequest = {\n  method: string;\n  params?: unknown[] | Record<string, unknown>;\n};\n\ntype Listener = (...args: unknown[]) => void;\n\ntype StoredUser = {\n  address: Address;\n  /** Absent = legacy passkey user; populated on new sessions. */\n  signerType?: SignerType;\n  /** Wagmi connector id for EOA sessions. Iframe-side lookup uses this. */\n  connectorId?: string;\n};\n\nexport type OneAuthProvider = {\n  request: (args: ProviderRequest) => Promise<unknown>;\n  on: (event: string, listener: Listener) => void;\n  removeListener: (event: string, listener: Listener) => void;\n  disconnect: () => Promise<void>;\n  /**\n   * Bind the active session in-memory and persist it to `localStorage`.\n   *\n   * Used by {@link createOneAuthConnection} to hand a freshly connected session\n   * to the provider the instant `connect()` resolves — before the app has\n   * written `1auth-user` itself. This closes a race where a provider built right\n   * after connect would read stale/empty storage and default an EOA session to\n   * passkey intents. Passing `null` clears the session (same effect as\n   * `disconnect()` minus the events).\n   *\n   * Existing `createOneAuthProvider` consumers never call this, so their\n   * behavior is unchanged: `getStoredUser` falls back to the localStorage read.\n   */\n  setSession: (\n    session:\n      | { address: Address; signerType?: SignerType; connectorId?: string }\n      | null,\n  ) => void;\n};\n\nexport type OneAuthProviderOptions = {\n  client: OneAuthClient;\n  chainId: number;\n  storageKey?: string;\n  /** When to close the dialog and return success. Defaults to \"preconfirmed\" */\n  closeOn?: CloseOnStatus;\n  waitForHash?: boolean;\n  hashTimeoutMs?: number;\n  hashIntervalMs?: number;\n};\n\nconst DEFAULT_STORAGE_KEY = \"1auth-user\";\n\n/**\n * Creates an EIP-1193 compatible JSON-RPC provider backed by 1auth passkey authentication.\n *\n * The returned provider object can be used anywhere a standard Ethereum provider is\n * accepted (e.g. passed to `createWalletClient` in viem, used as `window.ethereum`, or\n * supplied to ethers.js `BrowserProvider`). Connection state (the account address) is\n * persisted in `localStorage` under the configured `storageKey`.\n *\n * @param options - Provider configuration\n * @param options.client - Configured `OneAuthClient` instance used to open auth/sign dialogs\n * @param options.chainId - Default chain ID the provider reports via `eth_chainId`\n * @param options.storageKey - localStorage key for persisting the connected user.\n *   Defaults to `\"1auth-user\"`. Override to support multiple concurrent connections.\n * @param options.closeOn - Controls when the signing dialog closes and shows the \"Done\" button.\n *   `\"preconfirmed\"` (default) closes as soon as the intent is confirmed by the orchestrator.\n *   The `waitForHash` option independently controls whether the SDK continues polling for\n *   a transaction hash after the dialog closes.\n * @param options.waitForHash - When true, polls the intent status until a transaction hash\n *   is available before resolving `eth_sendTransaction` / `wallet_sendCalls`. Defaults to true.\n * @param options.hashTimeoutMs - Maximum milliseconds to wait for a transaction hash.\n *   Passed directly to the passkey service intent submission.\n * @param options.hashIntervalMs - Polling interval in milliseconds when waiting for a hash.\n *   Passed directly to the passkey service intent submission.\n * @returns An EIP-1193 provider with `request`, `on`, `removeListener`, and `disconnect`.\n *\n * @example\n * ```typescript\n * import { OneAuthClient } from \"@rhinestone/1auth\";\n * import { createOneAuthProvider } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const provider = createOneAuthProvider({ client, chainId: 8453 }); // Base\n *\n * // Use with viem\n * import { createWalletClient, custom } from \"viem\";\n * import { base } from \"viem/chains\";\n * const walletClient = createWalletClient({ chain: base, transport: custom(provider) });\n *\n * // Standard EIP-1193 usage\n * const accounts = await provider.request({ method: \"eth_requestAccounts\" });\n * provider.on(\"accountsChanged\", (accounts) => console.log(accounts));\n * ```\n */\nexport function createOneAuthProvider(\n  options: OneAuthProviderOptions\n): OneAuthProvider {\n  const { client } = options;\n  let chainId = options.chainId;\n  const storageKey = options.storageKey || DEFAULT_STORAGE_KEY;\n\n  const listeners = new Map<string, Set<Listener>>();\n\n  // In-memory session override. When set (via setSession), it takes precedence\n  // over the localStorage read so a just-connected provider immediately knows\n  // whether it's driving an EOA (forward to wallet, no intents) or a passkey\n  // (intents). `undefined` = not bound → fall back to localStorage.\n  //\n  // Cleared to `undefined` (never pinned to a \"signed out\" sentinel) on\n  // disconnect/setSession(null): those also wipe localStorage, so falling back\n  // to the (now empty) storage yields null anyway — and it lets the built-in\n  // connect() path repopulate via setStoredUser without a stale override\n  // shadowing it. Pinning it null here would break reconnect for plain\n  // createOneAuthProvider consumers.\n  let sessionOverride: StoredUser | undefined;\n\n  /**\n   * Dispatches an event to all registered listeners for the given event name.\n   *\n   * @param event - EIP-1193 event name (e.g. \"accountsChanged\", \"chainChanged\")\n   * @param args - Arguments forwarded to each listener callback\n   */\n  const emit = (event: string, ...args: unknown[]) => {\n    const set = listeners.get(event);\n    if (!set) return;\n    for (const listener of set) listener(...args);\n  };\n\n  /**\n   * Reads the connected user from localStorage.\n   *\n   * Returns null in non-browser environments (SSR) and when no user has been\n   * persisted yet, or when the stored value is malformed.\n   *\n   * @returns The stored user object, or null if unavailable\n   */\n  const getStoredUser = (): StoredUser | null => {\n    // A set in-memory binding wins over storage (so a just-connected session\n    // routes correctly before the app persists it). `undefined` = unbound, so\n    // read from storage — this is also the state after disconnect, letting the\n    // built-in connect() repopulate storage and be seen on the next call.\n    if (sessionOverride !== undefined) return sessionOverride;\n    if (typeof window === \"undefined\") return null;\n    try {\n      const raw = localStorage.getItem(storageKey);\n      if (!raw) return null;\n      const parsed = JSON.parse(raw) as StoredUser;\n      if (!parsed?.address) return null;\n      return parsed;\n    } catch {\n      return null;\n    }\n  };\n\n  /**\n   * Persists the connected user to localStorage.\n   *\n   * No-ops in non-browser (SSR) environments.\n   *\n   * @param user - User object with at minimum an `address` field\n   */\n  const setStoredUser = (user: StoredUser) => {\n    if (typeof window === \"undefined\") return;\n    localStorage.setItem(storageKey, JSON.stringify(user));\n  };\n\n  /**\n   * Removes the connected user from localStorage, effectively logging them out\n   * from the provider's perspective.\n   *\n   * No-ops in non-browser (SSR) environments.\n   */\n  const clearStoredUser = () => {\n    if (typeof window === \"undefined\") return;\n    localStorage.removeItem(storageKey);\n  };\n\n  /** Clear both persisted and in-memory state after local or dialog logout. */\n  const forgetSession = () => {\n    sessionOverride = undefined;\n    clearStoredUser();\n    emit(\"accountsChanged\", []);\n    emit(\"disconnect\");\n  };\n\n  // Some SSR integrations render with a deferred client and replace it after\n  // hydration. Provider construction supported that shape before disconnect\n  // fan-out was added, so do not make the bookkeeping WeakMap reject `null`.\n  if (client) registerSessionForgetHandler(client, forgetSession);\n\n  /**\n   * Connects the user by returning a cached address or opening the auth flow.\n   *\n   * Returns the dapp-side cached address immediately when present. Otherwise\n   * opens the auth modal (`/dialog/auth`) directly — the iframe-side\n   * returning-user UX lives inside that flow now. On success the address is\n   * stored in localStorage and `accountsChanged` / `connect` events are emitted.\n   *\n   * @returns Array containing the single connected account address\n   * @throws If the user cancels or authentication fails\n   */\n  const connect = async (): Promise<Address[]> => {\n    const stored = getStoredUser();\n    if (stored) {\n      return [stored.address];\n    }\n\n    const authResult = await client.authWithModal();\n    if (!authResult.success) {\n      throw new Error(authResult.error?.message || \"Authentication failed\");\n    }\n    const address = authResult.user?.address;\n    const signerType = authResult.signerType;\n\n    if (!address) {\n      throw new Error(\"No account address available\");\n    }\n\n    setStoredUser({ address, signerType });\n    emit(\"accountsChanged\", [address]);\n    emit(\"connect\", { chainId: numberToHex(chainId) });\n    return [address];\n  };\n\n  /**\n   * Disconnects the current user by clearing persisted state and emitting events.\n   *\n   * Emits `accountsChanged` with an empty array and `disconnect` so that consumers\n   * (e.g. wagmi) can update their state accordingly.\n   */\n  const disconnect = async () => {\n    forgetSession();\n  };\n\n  /**\n   * Bind (or clear) the active session in memory and mirror it to localStorage.\n   * See {@link OneAuthProvider.setSession}.\n   */\n  const setSession = (\n    session:\n      | { address: Address; signerType?: SignerType; connectorId?: string }\n      | null,\n  ) => {\n    if (!session) {\n      forgetSession();\n      return;\n    }\n    sessionOverride = {\n      address: session.address,\n      signerType: session.signerType,\n      connectorId: session.connectorId,\n    };\n    setStoredUser(sessionOverride);\n    emit(\"accountsChanged\", [session.address]);\n    emit(\"connect\", { chainId: numberToHex(chainId) });\n  };\n\n  /**\n   * Returns the currently connected user, triggering the connect flow if needed.\n   *\n   * Used internally by methods that require an authenticated session (e.g. signing,\n   * sending transactions) to guarantee a user is available before proceeding.\n   *\n   * @returns The stored user object with at minimum an `address` field\n   * @throws If connecting fails and no address can be resolved\n   */\n  const ensureUser = async (): Promise<StoredUser> => {\n    const stored = getStoredUser();\n    if (stored) return stored;\n    const [address] = await connect();\n    if (!address) {\n      throw new Error(\"Failed to resolve user session\");\n    }\n    const user = getStoredUser();\n    return user || { address };\n  };\n\n  /**\n   * Read an optional wallet_getAssets account address override from RPC params.\n   */\n  const getAssetsAccountAddress = (\n    assetsParams?: unknown[] | Record<string, unknown>,\n  ): string | undefined => {\n    const raw = Array.isArray(assetsParams) ? assetsParams[0] : assetsParams;\n    if (typeof raw === \"string\" && raw.trim()) return raw.trim();\n    if (!raw || typeof raw !== \"object\") return undefined;\n\n    const request = raw as Record<string, unknown>;\n    const candidates = [\n      request.accountAddress,\n      request.address,\n    ];\n    for (const candidate of candidates) {\n      if (typeof candidate === \"string\" && candidate.trim()) {\n        return candidate.trim();\n      }\n    }\n    return undefined;\n  };\n\n  /**\n   * Parses a chain ID value that may arrive as a hex string, decimal string, or number.\n   *\n   * Handles both `\"0x1\"` (hex) and `\"1\"` / `1` (decimal) representations that are\n   * commonly mixed across different wallet_switchEthereumChain implementations.\n   *\n   * @param value - The raw chain ID value from RPC params\n   * @returns The numeric chain ID, or undefined if the value cannot be parsed\n   */\n  const parseChainId = (value: unknown): number | undefined => {\n    if (typeof value === \"number\") return value;\n    if (typeof value === \"string\") {\n      if (value.startsWith(\"0x\")) return Number.parseInt(value, 16);\n      const parsed = Number(value);\n      return Number.isFinite(parsed) ? parsed : undefined;\n    }\n    return undefined;\n  };\n\n  /**\n   * Normalizes a transaction value to a decimal string expected by the intent service.\n   *\n   * Handles the various formats callers may provide: `bigint`, `number`, hex strings\n   * (e.g. `\"0x38d7ea4c68000\"`), or plain decimal strings. Returns undefined for null\n   * or unsupported types, allowing callers to fall back to `\"0\"`.\n   *\n   * @param value - Raw value from an RPC transaction param\n   * @returns Decimal string representation, or undefined if the input is not usable\n   */\n  const normalizeValue = (value: unknown): string | undefined => {\n    if (value === undefined || value === null) return undefined;\n    if (typeof value === \"bigint\") return value.toString();\n    if (typeof value === \"number\") return Math.trunc(value).toString();\n    if (typeof value === \"string\") {\n      if (value.startsWith(\"0x\")) {\n        return BigInt(value).toString();\n      }\n      return value;\n    }\n    return undefined;\n  };\n\n  /**\n   * Converts raw EIP-1193 call objects into the strongly-typed `IntentCall` format\n   * expected by the passkey service.\n   *\n   * Fills in missing `data` with `\"0x\"` and missing `value` with `\"0\"` so the\n   * intent service never receives undefined fields.\n   *\n   * @param calls - Raw call objects from `wallet_sendCalls` or `eth_sendTransaction` params\n   * @returns Array of normalized `IntentCall` objects\n   */\n  const normalizeCalls = (calls: unknown[]): IntentCall[] => {\n    return calls.map((call) => {\n      const c = call as Record<string, unknown>;\n      return {\n        to: c.to as Address,\n        data: (c.data as Hex | undefined) || \"0x\",\n        value: normalizeValue(c.value) || \"0\",\n        label: c.label as string | undefined,\n        sublabel: c.sublabel as string | undefined,\n        icon: c.icon as string | undefined,\n        abi: c.abi as readonly unknown[] | undefined,\n      };\n    });\n  };\n\n  /**\n   * Converts raw token request objects into the typed `IntentTokenRequest` format.\n   *\n   * Token requests allow callers to specify which tokens and amounts should be sourced\n   * when funding a cross-chain intent (e.g. \"bridge 10 USDC from Optimism to Base\").\n   * Accepts bigint or string/numeric amounts and normalizes them to bigint.\n   *\n   * @param requests - Raw token request array from RPC params, or a non-array value\n   * @returns Array of typed token requests, or undefined if input is not an array\n   */\n  const normalizeTokenRequests = (\n    requests: unknown\n  ): IntentTokenRequest[] | undefined => {\n    if (!Array.isArray(requests)) return undefined;\n    return requests.map((r) => {\n      const req = r as Record<string, unknown>;\n      return {\n        token: req.token as string,\n        amount:\n          typeof req.amount === \"bigint\"\n            ? req.amount\n            : BigInt(String(req.amount || \"0\")),\n      };\n    });\n  };\n\n  /**\n   * Decodes a message that may be hex-encoded into a human-readable string.\n   *\n   * Some signers (e.g. MetaMask) encode plain-text messages as hex before passing them\n   * to `personal_sign`. This helper reverses that encoding so users see the original\n   * text in the signing dialog rather than a raw hex string.\n   *\n   * @param value - A plain string or hex-encoded string (`\"0x...\"`)\n   * @returns The decoded UTF-8 string, or the original value if decoding fails\n   */\n  const decodeMessage = (value: string) => {\n    if (!isHex(value)) return value;\n    try {\n      return hexToString(value as Hex);\n    } catch {\n      return value;\n    }\n  };\n\n  /**\n   * Forwards a raw EIP-1193 request to the iframe at `/dialog/sign-eoa`, which\n   * delegates to the active wagmi connector. The wallet's own prompt is the\n   * review screen — no in-dialog review step for EOA sessions.\n   */\n  const forwardToWallet = async (\n    method: string,\n    params?: unknown[] | Record<string, unknown>,\n    expectedAddress?: Address,\n  ): Promise<unknown> => {\n    const result = await client.requestWithWallet({\n      method,\n      params,\n      expectedAddress,\n    });\n    if (!result.success) {\n      const err = new Error(result.error.message);\n      (err as Error & { code?: string }).code = result.error.code;\n      throw err;\n    }\n    return result.result;\n  };\n\n  /**\n   * EIP-1193 methods forwarded verbatim to the EOA connector. All other methods\n   * (eth_accounts, eth_chainId, wallet_connect, wallet_disconnect,\n   * wallet_switchEthereumChain, wallet_getCapabilities/Assets) are handled\n   * locally against the stored session even for EOA sessions.\n   */\n  const EOA_FORWARDED_METHODS = new Set([\n    \"personal_sign\",\n    \"eth_sign\",\n    \"eth_signTypedData\",\n    \"eth_signTypedData_v3\",\n    \"eth_signTypedData_v4\",\n    \"eth_sendTransaction\",\n    \"wallet_sendCalls\",\n    \"wallet_getCallsStatus\",\n  ]);\n\n  /**\n   * Signs an arbitrary string message via the passkey service.\n   *\n   * Ensures a user session exists before delegating to `OneAuthClient.signMessage`.\n   * The raw WebAuthn signature components are ABI-encoded for ERC-1271 on-chain\n   * verification before being returned.\n   *\n   * @param message - Plain-text message to sign\n   * @returns ABI-encoded WebAuthn signature as a hex string\n   * @throws If no user session is available or the signing dialog is cancelled\n   */\n  const signMessage = async (message: string) => {\n    const user = await ensureUser();\n    if (!user.address) {\n      throw new Error(\"Account address required for signing.\");\n    }\n    const result = await client.signMessage({\n      accountAddress: user.address,\n      message,\n    });\n    if (!result.success) {\n      throw toOneAuthError(result.error, \"Signing failed\", \"SIGNING_FAILED\");\n    }\n    if (!result.signature) {\n      throw toOneAuthError(undefined, \"No signature received\", \"SIGNING_FAILED\");\n    }\n    return encodeWebAuthnSignature(result.signature);\n  };\n\n  /**\n   * Signs EIP-712 typed data via the passkey service.\n   *\n   * Accepts either a parsed typed-data object or a JSON string (as some libraries\n   * serialize the payload before passing it through the provider). The raw WebAuthn\n   * signature is ABI-encoded for ERC-1271 on-chain verification.\n   *\n   * @param typedData - EIP-712 typed data object or its JSON string representation\n   * @returns ABI-encoded WebAuthn signature as a hex string\n   * @throws If no user session is available or the signing dialog is cancelled\n   */\n  const signTypedData = async (typedData: unknown) => {\n    const user = await ensureUser();\n    if (!user.address) {\n      throw new Error(\"Account address required for signing.\");\n    }\n    const data =\n      typeof typedData === \"string\" ? JSON.parse(typedData) : typedData;\n    const result = await client.signTypedData({\n      accountAddress: user.address,\n      domain: (data as any).domain,\n      types: (data as any).types,\n      primaryType: (data as any).primaryType,\n      message: (data as any).message,\n    });\n    if (!result.success) {\n      throw toOneAuthError(result.error, \"Signing failed\", \"SIGNING_FAILED\");\n    }\n    if (!result.signature) {\n      throw toOneAuthError(undefined, \"No signature received\", \"SIGNING_FAILED\");\n    }\n    return encodeWebAuthnSignature(result.signature);\n  };\n\n  /**\n   * Extracts the fields required by `OneAuthClient.sendIntent` from a richer payload.\n   *\n   * This thin wrapper makes it explicit which fields travel to the intent service and\n   * which are local concerns (e.g. `sourceChainId` is handled at the call site).\n   *\n   * @param payload - Full intent payload including user identity and transaction data\n   * @returns Subset of fields forwarded to the intent service\n   */\n  const resolveIntentPayload = (payload: {\n    accountAddress: Address;\n    targetChain: number;\n    calls: IntentCall[];\n    tokenRequests?: IntentTokenRequest[];\n  }) => ({\n    accountAddress: payload.accountAddress,\n    targetChain: payload.targetChain,\n    calls: payload.calls,\n    tokenRequests: payload.tokenRequests,\n  });\n\n  /**\n   * Submits a cross-chain intent through the passkey service and returns the intent ID.\n   *\n   * Opens the signing dialog, waits for user confirmation, then polls the orchestrator\n   * until a transaction hash is available (controlled by `waitForHash` and the timeout\n   * options). The returned intent ID is used as the `callsId` in EIP-5792 responses.\n   *\n   * The dialog closes based on `closeOn` (defaults to `\"preconfirmed\"`). The `waitForHash`\n   * option independently polls for a transaction hash after the dialog closes.\n   *\n   * @param payload - Intent details including target chain, calls, token requests, and\n   *   an optional `sourceChainId` for cross-chain bridging\n   * @returns The orchestrator intent ID string\n   * @throws If the user rejects the signing dialog or the intent fails\n   */\n  const sendIntent = async (payload: {\n    accountAddress: Address;\n    targetChain: number;\n    calls: IntentCall[];\n    tokenRequests?: IntentTokenRequest[];\n    sourceChainId?: number;\n  }) => {\n    const intentPayload = resolveIntentPayload(payload);\n    const result = await client.sendIntent({\n      ...intentPayload,\n      tokenRequests: payload.tokenRequests,\n      sourceChainId: payload.sourceChainId,\n      closeOn: options.closeOn,\n      waitForHash: options.waitForHash ?? true,\n      hashTimeoutMs: options.hashTimeoutMs,\n      hashIntervalMs: options.hashIntervalMs,\n    });\n\n    if (!result.success) {\n      throw toOneAuthError(result.error, \"Transaction failed\", \"INTENT_FAILED\");\n    }\n\n    // Return intentId as callsId for EIP-5792 compatibility\n    return result.intentId;\n  };\n\n  const accountMismatchError = (): Error & { code?: string } => {\n    const err = new Error(\n      \"Requested signer does not match the active wallet connection.\",\n    ) as Error & { code?: string };\n    err.code = \"ACCOUNT_MISMATCH\";\n    return err;\n  };\n\n  const sameAddress = (a: unknown, b: string): boolean =>\n    typeof a === \"string\" && a.toLowerCase() === b.toLowerCase();\n\n  /**\n   * Some wallets (MetaMask, Rabby) reject `eth_sendTransaction` /\n   * `wallet_sendCalls` / `personal_sign` / `eth_signTypedData_v4` when the\n   * signer address is missing. The dapp doesn't know the EOA address, so the\n   * SDK fills it in from the stored session.\n   *\n   * If the caller supplies a `from` (or address arg) that differs from the\n   * connected EOA, we throw `ACCOUNT_MISMATCH` rather than letting the\n   * caller's value win. A dapp asking the wallet to sign on behalf of a\n   * different account than the user connected is a trust-boundary violation\n   * — the user reviewed and approved exactly one address, not whatever the\n   * dapp later substitutes.\n   */\n  const injectEoaSigner = (\n    method: string,\n    params: unknown[] | Record<string, unknown> | undefined,\n    address: Address,\n  ): unknown[] | Record<string, unknown> | undefined => {\n    const list = Array.isArray(params) ? params.slice() : params;\n    if (!Array.isArray(list)) return params;\n\n    if (method === \"eth_sendTransaction\") {\n      const first = (list[0] || {}) as Record<string, unknown>;\n      if (first.from !== undefined && !sameAddress(first.from, address)) {\n        throw accountMismatchError();\n      }\n      list[0] = { ...first, from: address };\n      return list;\n    }\n    if (method === \"wallet_sendCalls\") {\n      const first = (list[0] || {}) as Record<string, unknown>;\n      if (first.from !== undefined && !sameAddress(first.from, address)) {\n        throw accountMismatchError();\n      }\n      // EIP-5792 lets each call carry its own `from`. Validate every one —\n      // a single mismatched call would otherwise sneak through unchecked.\n      const calls = first.calls;\n      if (Array.isArray(calls)) {\n        for (const call of calls) {\n          if (!call || typeof call !== \"object\") continue;\n          const callFrom = (call as Record<string, unknown>).from;\n          if (callFrom !== undefined && !sameAddress(callFrom, address)) {\n            throw accountMismatchError();\n          }\n        }\n      }\n      list[0] = { ...first, from: address };\n      return list;\n    }\n    if (method === \"personal_sign\") {\n      // personal_sign(message, address) — fill address if absent.\n      if (list[1] !== undefined && !sameAddress(list[1], address)) {\n        throw accountMismatchError();\n      }\n      if (list[0] && list[1] === undefined) list[1] = address;\n      return list;\n    }\n    if (\n      method === \"eth_sign\" ||\n      method === \"eth_signTypedData\" ||\n      method === \"eth_signTypedData_v3\" ||\n      method === \"eth_signTypedData_v4\"\n    ) {\n      // signTypedData(address, typedData) — fill address if absent.\n      if (list[0] !== undefined && !sameAddress(list[0], address)) {\n        throw accountMismatchError();\n      }\n      if (list[0] === undefined && list[1] !== undefined) list[0] = address;\n      return list;\n    }\n    return list;\n  };\n\n  // EIP-5792 batches submitted on EOA sessions, keyed by the returned id so\n  // wallet_getCallsStatus can answer without hitting the wallet (most EOA\n  // wallets don't implement 5792). Lost on reload — getCallsStatus tolerates a\n  // miss. ponytail: in-memory is fine; the id IS the last tx hash, so a caller\n  // that lost the map can still fetch the receipt itself.\n  const eoaBatches = new Map<string, string[]>();\n\n  /**\n   * EOA `wallet_sendCalls`: most EOA wallets don't implement EIP-5792, and an\n   * EOA can't batch atomically anyway, so send each call as a sequential\n   * `eth_sendTransaction` (the standard wagmi/RainbowKit fallback). Returns the\n   * last tx hash as the batch id — matching the string-id shape the passkey\n   * path returns.\n   */\n  const sendCallsEoa = async (\n    params: unknown[] | Record<string, unknown> | undefined,\n    address: Address,\n  ): Promise<string> => {\n    // Reuse injectEoaSigner for the account-mismatch validation, then decompose.\n    const validated = injectEoaSigner(\"wallet_sendCalls\", params, address);\n    const payload = (Array.isArray(validated) ? validated[0] : {}) as Record<string, unknown>;\n    const calls = Array.isArray(payload.calls) ? payload.calls : [];\n    if (!calls.length) throw new Error(\"No calls provided\");\n    const batchChainId = payload.chainId;\n    const hashes: string[] = [];\n    for (const raw of calls) {\n      const call = (raw || {}) as Record<string, unknown>;\n      const tx: Record<string, unknown> = { from: address, to: call.to };\n      if (call.data !== undefined) tx.data = call.data;\n      if (call.value !== undefined) tx.value = call.value;\n      const callChain = call.chainId ?? batchChainId;\n      if (callChain !== undefined) tx.chainId = callChain;\n      const hash = await forwardToWallet(\"eth_sendTransaction\", [tx], address);\n      hashes.push(String(hash));\n    }\n    const id = hashes[hashes.length - 1];\n    eoaBatches.set(id, hashes);\n    return id;\n  };\n\n  /** EOA `wallet_getCallsStatus`: answer from the submitted hashes. */\n  const getCallsStatusEoa = (callsId: unknown) => {\n    if (!callsId || typeof callsId !== \"string\") {\n      throw new Error(\"callsId is required\");\n    }\n    const hashes = eoaBatches.get(callsId) ?? [callsId];\n    // CONFIRMED is submission-optimistic — eth_sendTransaction resolves on\n    // submission, and we don't re-poll the chain here. Receipts carry the real\n    // hashes; a caller wanting finality can watch them. ponytail: no receipt\n    // watcher — the EOA's own wallet already showed the confirmation UI.\n    return {\n      status: \"CONFIRMED\",\n      receipts: hashes.map((transactionHash) => ({ transactionHash })),\n    };\n  };\n\n  const request = async ({ method, params }: ProviderRequest) => {\n    // For sign/tx methods, resolve the user first — this opens the auth modal\n    // on the very first call so we know the signerType before deciding\n    // between the passkey path and forwarding to the wagmi connector. Local-\n    // only methods (eth_accounts, eth_chainId, wallet_switchEthereumChain,\n    // etc.) fall through to the switch below and read stored state directly.\n    if (EOA_FORWARDED_METHODS.has(method)) {\n      const user = await ensureUser();\n      if (user.signerType === \"eoa\") {\n        // EIP-5792 isn't universally supported by EOA wallets — handle the\n        // batch methods locally instead of forwarding them blindly.\n        if (method === \"wallet_sendCalls\") {\n          return sendCallsEoa(params, user.address);\n        }\n        if (method === \"wallet_getCallsStatus\") {\n          const list = Array.isArray(params) ? params : [];\n          return getCallsStatusEoa(list[0]);\n        }\n        return forwardToWallet(\n          method,\n          injectEoaSigner(method, params, user.address),\n          user.address,\n        );\n      }\n    }\n\n    switch (method) {\n      case \"eth_chainId\":\n        return numberToHex(chainId);\n      case \"eth_accounts\": {\n        const stored = getStoredUser();\n        return stored ? [stored.address] : [];\n      }\n      case \"eth_requestAccounts\":\n        return connect();\n      case \"wallet_connect\":\n        return connect();\n      case \"wallet_disconnect\":\n        await disconnect();\n        return true;\n      case \"wallet_switchEthereumChain\": {\n        const [param] = (params as any[]) || [];\n        const next = parseChainId(param?.chainId ?? param);\n        if (!next) {\n          throw new Error(\"Invalid chainId\");\n        }\n        const stored = getStoredUser();\n        if (stored?.signerType === \"eoa\") {\n          await forwardToWallet(method, params, stored.address);\n        }\n        chainId = next;\n        emit(\"chainChanged\", numberToHex(chainId));\n        return null;\n      }\n      case \"personal_sign\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const first = paramList[0];\n        const second = paramList[1];\n        // personal_sign param order varies: some callers send [message, address],\n        // others send [hexEncodedMessage, address]. When the first param is hex and\n        // the second is a non-hex string we treat the second as the plain message\n        // (MetaMask-style). Otherwise we always decode the first param.\n        const message =\n          typeof first === \"string\" && first.startsWith(\"0x\") && second\n            ? typeof second === \"string\" && !second.startsWith(\"0x\")\n              ? second\n              : decodeMessage(first)\n            : typeof first === \"string\"\n              ? decodeMessage(first)\n              : typeof second === \"string\"\n                ? decodeMessage(second)\n                : \"\";\n        if (!message) throw new Error(\"Invalid personal_sign payload\");\n        return signMessage(message);\n      }\n      case \"eth_sign\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const message = typeof paramList[1] === \"string\" ? paramList[1] : \"\";\n        if (!message) throw new Error(\"Invalid eth_sign payload\");\n        return signMessage(decodeMessage(message));\n      }\n      case \"eth_signTypedData\":\n      case \"eth_signTypedData_v4\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const typedData = paramList[1] ?? paramList[0];\n        return signTypedData(typedData);\n      }\n      case \"eth_sendTransaction\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const tx = (paramList[0] || {}) as Record<string, unknown>;\n        const user = await ensureUser();\n        const targetChain = parseChainId(tx.chainId) ?? chainId;\n        const calls = normalizeCalls([tx]);\n        const tokenRequests = normalizeTokenRequests(tx.tokenRequests);\n        const txSourceChainId = parseChainId(tx.sourceChainId);\n        return sendIntent({\n          accountAddress: user.address,\n          targetChain,\n          calls,\n          tokenRequests,\n          sourceChainId: txSourceChainId,\n        });\n      }\n      case \"wallet_sendCalls\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const payload = (paramList[0] || {}) as Record<string, unknown>;\n        const user = await ensureUser();\n        const targetChain = parseChainId(payload.chainId) ?? chainId;\n        const calls = normalizeCalls((payload.calls as unknown[]) || []);\n        const tokenRequests = normalizeTokenRequests(payload.tokenRequests);\n        const sourceChainId = parseChainId(payload.sourceChainId);\n        if (!calls.length) throw new Error(\"No calls provided\");\n        return sendIntent({\n          accountAddress: user.address,\n          targetChain,\n          calls,\n          tokenRequests,\n          sourceChainId,\n        });\n      }\n      case \"wallet_getCapabilities\": {\n        const stored = getStoredUser();\n        if (stored?.signerType === \"eoa\") {\n          return {};\n        }\n\n        const paramList = Array.isArray(params) ? params : [];\n        // walletAddress is params[0] - we ignore since all accounts have same capabilities\n        const requestedChains = paramList[1] as `0x${string}`[] | undefined;\n\n        const chainIds = getSupportedChainIds();\n        const capabilities: Record<`0x${string}`, Record<string, unknown>> = {};\n\n        for (const chainId of chainIds) {\n          const hexChainId = `0x${chainId.toString(16)}` as `0x${string}`;\n\n          // Filter if specific chains requested\n          if (requestedChains && !requestedChains.includes(hexChainId)) {\n            continue;\n          }\n\n          // All supported chains advertise atomic batching, gasless transactions via\n          // paymasters, and cross-chain auxiliary funds (EIP-5792 capability keys).\n          capabilities[hexChainId] = {\n            atomic: { status: \"supported\" },\n            paymasterService: { supported: true },\n            auxiliaryFunds: { supported: true },\n          };\n        }\n\n        return capabilities;\n      }\n      case \"wallet_getAssets\": {\n        const explicitAccountAddress = getAssetsAccountAddress(params);\n        const user = explicitAccountAddress ? null : await ensureUser();\n        // The portfolio endpoint resolves identifiers via resolveUserWhere,\n        // and the current SDK account model is address-first. Explicit params\n        // let app-level verified sessions query balances without relying on\n        // the provider's localStorage cache, while connected EIP-1193 consumers\n        // still work with no params.\n        const accountAddress = explicitAccountAddress || user?.address;\n        if (!accountAddress) {\n          throw new Error(\"wallet_getAssets requires accountAddress or a connected account\");\n        }\n        return client.getAssets({ accountAddress: accountAddress as Address });\n      }\n      case \"wallet_getCallsStatus\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const callsId = paramList[0] as string;\n        if (!callsId) {\n          throw new Error(\"callsId is required\");\n        }\n        const statusClientId = client.getClientId();\n        const response = await fetch(\n          `${client.getProviderUrl()}/api/intent/status/${encodeURIComponent(callsId)}`,\n          {\n            headers: statusClientId ? { \"x-client-id\": statusClientId } : {},\n          }\n        );\n        if (!response.ok) {\n          const data = await response.json().catch(() => ({}));\n          throw new Error(data.error || \"Failed to get calls status\");\n        }\n        const data = await response.json();\n        // Map intent status to EIP-5792 status strings.\n        // Both \"failed\" and \"expired\" map to \"CONFIRMED\" because EIP-5792 uses receipts\n        // (and a 0x0 status code) to communicate failure — there is no \"FAILED\" state.\n        const statusMap: Record<string, string> = {\n          pending: \"PENDING\",\n          preconfirmed: \"PENDING\",\n          completed: \"CONFIRMED\",\n          failed: \"CONFIRMED\",\n          expired: \"CONFIRMED\",\n        };\n        return {\n          status: statusMap[data.status] || \"PENDING\",\n          receipts: data.transactionHash\n            ? [\n                {\n                  logs: [],\n                  // 0x1 = success, 0x0 = reverted/failed — mirrors EVM receipt status\n                  status: data.status === \"completed\" ? \"0x1\" : \"0x0\",\n                  blockHash: data.blockHash,\n                  blockNumber: data.blockNumber,\n                  transactionHash: data.transactionHash,\n                },\n              ]\n            : [],\n        };\n      }\n      case \"wallet_getCallsHistory\": {\n        const paramList = Array.isArray(params) ? params : [];\n        const options = (paramList[0] || {}) as {\n          limit?: number;\n          offset?: number;\n          status?: string;\n          from?: string;\n          to?: string;\n        };\n\n        const queryParams = new URLSearchParams();\n        if (options.limit) queryParams.set(\"limit\", String(options.limit));\n        if (options.offset) queryParams.set(\"offset\", String(options.offset));\n        if (options.status) queryParams.set(\"status\", options.status);\n        if (options.from) queryParams.set(\"from\", options.from);\n        if (options.to) queryParams.set(\"to\", options.to);\n\n        const url = `${client.getProviderUrl()}/api/intent/history${\n          queryParams.toString() ? `?${queryParams}` : \"\"\n        }`;\n\n        const historyClientId = client.getClientId();\n        const response = await fetch(url, {\n          headers: historyClientId ? { \"x-client-id\": historyClientId } : {},\n          credentials: \"include\",\n        });\n\n        if (!response.ok) {\n          const data = await response.json().catch(() => ({}));\n          throw new Error(data.error || \"Failed to get calls history\");\n        }\n\n        const data = await response.json();\n\n        // Map intent status to EIP-5792 format\n        const statusMap: Record<string, string> = {\n          pending: \"PENDING\",\n          preconfirmed: \"PENDING\",\n          completed: \"CONFIRMED\",\n          failed: \"CONFIRMED\",\n          expired: \"CONFIRMED\",\n        };\n\n        // intentId IS the orchestrator's ID (used as callsId in EIP-5792)\n        return {\n          calls: data.intents.map(\n            (intent: {\n              intentId: string;\n              status: string;\n              transactionHash?: string;\n              targetChain: number;\n            }) => ({\n              callsId: intent.intentId, // intentId is the orchestrator's ID\n              status: statusMap[intent.status] || \"PENDING\",\n              receipts: intent.transactionHash\n                ? [{ transactionHash: intent.transactionHash }]\n                : [],\n              chainId: `0x${intent.targetChain.toString(16)}`,\n            })\n          ),\n          total: data.total,\n          hasMore: data.hasMore,\n        };\n      }\n      default:\n        throw new Error(`Unsupported method: ${method}`);\n    }\n  };\n\n  return {\n    request,\n    on(event, listener) {\n      const set = listeners.get(event) ?? new Set();\n      set.add(listener);\n      listeners.set(event, set);\n    },\n    removeListener(event, listener) {\n      const set = listeners.get(event);\n      if (!set) return;\n      set.delete(listener);\n      if (set.size === 0) listeners.delete(event);\n    },\n    disconnect,\n    setSession,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,SAAS,qBAA+C;;;ACgBxD,SAAS,kBAAkB,SAAqC;AAC9D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,QAAQ,aAAa,UAAU,QAAQ,OAAO;AAAA,EAC3D;AACF;AAKA,SAAS,oBAAoB,UAG3B;AACA,QAAM,kBAAkC,CAAC;AACzC,QAAM,kBAAkC,CAAC;AAEzC,aAAW,WAAW,UAAU;AAC9B,UAAM,aAAa,kBAAkB,OAAO;AAC5C,QAAI,WAAW,WAAW;AACxB,sBAAgB,KAAK,UAAU;AAAA,IACjC,OAAO;AACL,sBAAgB,KAAK,UAAU;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,UAAU,EAAE,UAAU,gBAAgB;AAAA,IACtC,UAAU,EAAE,UAAU,gBAAgB;AAAA,EACxC;AACF;AAKO,SAAS,wBAAwB,SAAkC;AACxE,QAAM,OAAO,WAAW,OAAO,YAAY,WACtC,UACD,CAAC;AACL,MAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAChC,UAAMA,YAAY,KAAK,SAA4B,IAAI,iBAAiB;AACxE,UAAM,UAAU,oBAAoBA,SAAQ;AAC5C,WAAO,EAAE,GAAG,MAAM,UAAAA,WAAU,GAAG,QAAQ;AAAA,EACzC;AAEA,QAAM,WAA2B,CAAC;AAClC,QAAM,SAAS,MAAM,QAAQ,KAAK,MAAM,IAAK,KAAK,SAA8B,CAAC;AACjF,aAAW,SAAS,QAAQ;AAC1B,UAAM,SAAS,MAAM,UAAU;AAC/B,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,SAAS,CAAC;AAE7D,QAAI,OAAO,WAAW,GAAG;AACvB,YAAM,QAAQ,MAAM,SAAS,MAAM;AACnC,UAAI,OAAO;AACT,iBAAS,KAAK,kBAAkB;AAAA,UAC9B,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS,MAAM,WAAW,MAAM,UAAU;AAAA,UAC1C,GAAI,MAAM,aAAa,UAAa,EAAE,UAAU,MAAM,SAAS;AAAA,QACjE,CAAC,CAAC;AAAA,MACJ;AACA;AAAA,IACF;AAEA,eAAW,SAAS,QAAQ;AAC1B,YAAM,UAAU,MAAM,WAAW,MAAM;AACvC,YAAM,QAAQ,MAAM,SAAS,MAAM;AACnC,UAAI,OAAO,YAAY,YAAY,CAAC,MAAO;AAC3C,eAAS,KAAK,kBAAkB;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,MAAM,YAAY;AAAA,QAC5B,SAAS,MAAM,WAAW,MAAM,UAAU;AAAA,QAC1C,GAAI,MAAM,aAAa,UAAa,EAAE,UAAU,MAAM,SAAS;AAAA,QAC/D,GAAI,MAAM,cAAc,UAAa,EAAE,WAAW,MAAM,UAAU;AAAA,MACpE,CAAC,CAAC;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,GAAG,MAAM,UAAU,GAAG,oBAAoB,QAAQ,EAAE;AAC/D;AAKA,eAAsB,oBACpB,SACyB;AACzB,QAAM,eAAe,IAAI;AAAA,IACvB,cAAc,mBAAmB,QAAQ,UAAU,CAAC;AAAA,IACpD,QAAQ;AAAA,EACV;AAGA,eAAa,aAAa,IAAI,OAAO,MAAM;AAE3C,QAAM,WAAW,MAAM,MAAM,aAAa,SAAS,GAAG;AAAA,IACpD,SAAS;AAAA,MACP,GAAG,QAAQ;AAAA,MACX,GAAI,QAAQ,cAAc,EAAE,eAAe,UAAU,QAAQ,WAAW,GAAG,IAAI,CAAC;AAAA,MAChF,GAAI,QAAQ,WAAW,EAAE,eAAe,QAAQ,SAAS,IAAI,CAAC;AAAA,IAChE;AAAA,EACF,CAAC;AACD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,UAAM,IAAI,MAAM,KAAK,SAAS,sBAAsB;AAAA,EACtD;AACA,SAAO,wBAAwB,MAAM,SAAS,KAAK,CAAC;AACtD;;;AClIO,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB,eAAe,kBAAkB;AACzD,IAAM,wBAAwB,IAAI,KAAK,KAAK;AAC5C,IAAM,uBAAuB;AAC7B,IAAM,cAAc,wBAAwB;AAM5C,IAAM,2BAA2B;AASjC,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAS7B,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAC7B,IAAM,0BAA0B;AAOhC,IAAM,0BAA0B;AAChC,IAAM,4BAA4B;AAClC,IAAM,6BAA6B;AACnC,IAAM,+BAA+B;AAGrC,IAAM,sBAAsB;AAI5B,IAAM,sBACX;AAUK,IAAM,eAAe;AAkBrB,IAAM,eAAmC;AAAA,EAC9C,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,eAAe;AACjB;AAEO,IAAM,cAAkC;AAAA,EAC7C,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,eAAe;AACjB;AAMO,IAAM,gBAAgB;AACtB,IAAM,mBACX;;;AF/BF,SAAS,iCACP,OACuC;AACvC,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,OAAO,MAAM,UAAU,WAAY,QAAsC;AAClF;AA8BA,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,sBAAsB,GAAG,mBAAmB;AAClD,IAAM,uBAAuB;AAC7B,IAAM,uBAAuB;AAQ7B,SAAS,sBAAqC;AAC5C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,SAAS,OAAO,UAAU;AAChC,SAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,SAAS;AACpE;AAOA,SAAS,wBAAwB,QAA+B;AAC9D,QAAM,SAAS,oBAAoB;AACnC,MAAI,OAAQ,QAAO,IAAI,gBAAgB,MAAM;AAC/C;AAQA,IAAM,gBAAgB;AAKtB,IAAM,yBAAyB;AAC/B,IAAM,2BAA2B;AACjC,IAAM,wBAAwB;AAK9B,IAAM,eAAe;AAed,SAAS,qBAAqB,QAGnC;AACA,QAAM,WAAW,OAAO,IAAI,eAAe;AAC3C,QAAM,OAAO,YAAY,aAAa,KAAK,QAAQ,IAAI,WAAW,wBAAwB,MAAM,CAAC;AACjG,QAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,QAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,QAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AAStC,QAAM,cAAc,CAAC,KAAa,KAAa,KAAa,aAA6B;AACvF,UAAM,MAAM,OAAO,IAAI,GAAG;AAC1B,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,IAAI,OAAO,GAAG;AACpB,WAAO,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC,IAAI;AAAA,EAChE;AAEA,QAAM,UAAU,YAAY,mBAAmB,GAAG,GAAG,wBAAwB;AAC7E,QAAM,OAAO,YAAY,gBAAgB,GAAG,IAAI,qBAAqB;AAErE,SAAO,EAAE,YAAY,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,OAAO,KAAK,KAAK;AAClE;AAYA,SAAS,qBAA6B;AACpC,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,YAAY;AAC5E,WAAO,OAAO,WAAW;AAAA,EAC3B;AACA,SAAO,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAC1E;AAkBA,SAAS,+BAAuC;AAC9C,SAAO,SAAS,mBAAmB,CAAC;AACtC;AAMA,SAAS,yBACP,YACwC;AACxC,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,QAAoC,CAAC;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACrD,QAAI,UAAU,OAAW,OAAM,GAAG,IAAI;AAAA,EACxC;AACA,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AACjD;AAMA,SAAS,uBAAuB,OAG9B;AACA,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,MAAI,iBAAiB,OAAO;AAC1B,WAAO,EAAE,WAAW,MAAM,MAAM,cAAc,MAAM,QAAQ;AAAA,EAC9D;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,MAAM;AACZ,WAAO;AAAA,MACL,WAAW,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;AAAA,MACrD,cAAc,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU,OAAO,KAAK;AAAA,IAC5E;AAAA,EACF;AACA,SAAO,EAAE,cAAc,OAAO,KAAK,EAAE;AACvC;AAYA,SAAS,cAAc,OAA2D;AAChF,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,IAAI,CAAC,MAAM;AACtB,UAAM,cACJ,EAAE,SAAS,EAAE,MAAM,SAAS,gBACxB,EAAE,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,WACtC,EAAE;AACR,UAAM,iBACJ,EAAE,YAAY,EAAE,SAAS,SAAS,gBAC9B,EAAE,SAAS,MAAM,GAAG,gBAAgB,CAAC,IAAI,WACzC,EAAE;AACR,QAAI,gBAAgB,EAAE,SAAS,mBAAmB,EAAE,SAAU,QAAO;AACrE,WAAO,EAAE,GAAG,GAAG,OAAO,aAAa,UAAU,eAAe;AAAA,EAC9D,CAAC;AACH;AAOA,SAAS,sBAAyC;AAChD,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,MAAM,OAAO,aAAa,QAAQ,YAAY;AACpD,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,WAAO,QAAQ,eAAe,QAAQ,QAAQ;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAmBA,IAAM,wBAAwB;AAY9B,IAAM,kCACJ;AAaF,SAAS,qBACP,QACkC;AAClC,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,iBAAiB,UAAU,uBAAuB,QAAQ;AAC5D,WAAO;AAAA,EACT;AACA,QAAM,EAAE,gBAAgB,kBAAkB,IAAI;AAC9C,SAAO;AAAA,IACL,aAAa,YAAY;AACvB,YAAM,WAAW,MAAM,MAAM,gBAAgB,EAAE,aAAa,UAAU,CAAC;AACvE,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,MAAM,gBAAgB,gBAAgB,QAAQ;AAAA,MACtD;AACA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,CAAC,KAAK,OAAO;AACf,cAAM,IAAI,MAAM,6CAA6C;AAAA,MAC/D;AACA,aAAO,KAAK;AAAA,IACd;AAAA,IACA,mBAAmB,OAAO,aAAqB;AAC7C,YAAM,WAAW,MAAM,MAAM,mBAAmB;AAAA,QAC9C,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,MACnC,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,MAAM,gBAAgB,mBAAmB,QAAQ;AAAA,MACzD;AACA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,CAAC,KAAK,OAAO;AACf,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AACA,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AACF;AAOA,SAAS,wBAAwB,MAAc,OAAyB;AACtE,SAAO,OAAO,UAAU,WAAW,MAAM,SAAS,IAAI;AACxD;AAEA,SAAS,kBAAqB,OAAa;AACzC,SAAO,KAAK,MAAM,KAAK,UAAU,OAAO,uBAAuB,CAAC;AAClE;AAEA,SAAS,2BAA2B,SAA4C;AAC9E,QAAM,kBAAkB,QAAQ,iBAC9B,QAAQ,gBAAgB,SAAY,CAAC,QAAQ,WAAW,IAAI,CAAC;AAE/D,SAAO,MAAM,KAAK,IAAI,IAAI,eAAe,CAAC;AAC5C;AAEA,SAAS,2BAA2B,SAA4C;AAC9E,SAAO,MAAM,KAAK,IAAI,IAAI,QAAQ,gBAAgB,CAAC,CAAC,CAAC;AACvD;AAEA,IAAM,wBAAwB,oBAAI,QAAwC;AAGnE,SAAS,6BACd,QACA,SACY;AACZ,QAAM,WAAW,sBAAsB,IAAI,MAAM,KAAK,oBAAI,IAAgB;AAC1E,WAAS,IAAI,OAAO;AACpB,wBAAsB,IAAI,QAAQ,QAAQ;AAC1C,SAAO,MAAM;AACX,aAAS,OAAO,OAAO;AACvB,QAAI,SAAS,SAAS,EAAG,uBAAsB,OAAO,MAAM;AAAA,EAC9D;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsEzB,YAAY,QAA+B;AA3D3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAQ,iBAGG;AASX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAQ,eAGG;AAGX;AAAA;AAAA,SAAQ,iBAAmC,QAAQ,QAAQ;AA0CzD,UAAM,cAAc,OAAO,eAAe;AAC1C,UAAM,YAAY,OAAO,aAAa;AACtC,SAAK,SAAS,EAAE,GAAG,QAAQ,aAAa,UAAU;AAClD,SAAK,QAAQ,KAAK,OAAO,SAAS,CAAC;AACnC,SAAK,cAAc,qBAAqB,OAAO,WAAW;AAC1D,SAAK,0BAA0B;AAG/B,QAAI,OAAO,aAAa,aAAa;AACnC,WAAK,iBAAiB,WAAW;AACjC,UAAI,cAAc,aAAa;AAC7B,aAAK,iBAAiB,SAAS;AAAA,MACjC;AAIA,UAAI,KAAK,OAAO,SAAS;AACvB,cAAM,OAAO,MAAM,KAAK,KAAK,QAAQ;AACrC,cAAM,MAAO,OAEV;AACH,YAAI,OAAO,QAAQ,YAAY;AAC7B,cAAI,MAAM,EAAE,SAAS,IAAK,CAAC;AAAA,QAC7B,OAAO;AACL,qBAAW,MAAM,GAAG;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,KAAK,yBAAyB,UAAU;AAAA,MAC5D,aAAa,CAAC,CAAC,KAAK,OAAO;AAAA,MAC3B,sBAAsB,cAAc;AAAA,IACtC,CAAC;AACD,SAAK,cAAc,eAAe,eAAe,EAAE,SAAS,UAAU,CAAC;AAAA,EACzE;AAAA;AAAA,EAzEQ,4BAAkC;AACxC,QAAI,OAAO,WAAW,YAAa,cAAa,WAAW,YAAY;AACvE,eAAW,WAAW,sBAAsB,IAAI,IAAI,KAAK,CAAC,EAAG,SAAQ;AACrE,QAAI;AACF,WAAK,OAAO,eAAe;AAAA,IAC7B,QAAQ;AAAA,IAGR;AAAA,EACF;AAAA;AAAA,EAGQ,4BAAkC;AACxC,QACE,OAAO,WAAW,eAClB,OAAO,aAAa,eACpB,OAAO,OAAO,qBAAqB,WACnC;AACF,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,iBAAiB,WAAW,CAAC,UAAwB;AAC1D,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,MAAM,SAAS,sBAAsB;AAC7C,aAAK,0BAA0B;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAsDA,eAAe,aAAkD;AAC/D,SAAK,cAAc,qBAAqB,WAAW;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAA8B;AACpC,WAAO,CAAC,CAAC,KAAK,OAAO,aAAa,KAAK,OAAO,UAAU,YAAY;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,2BAAqE;AAC3E,UAAM,eAAe,KAAK,OAAO,WAAW;AAC5C,QAAI,CAAC,gBAAgB,CAAC,KAAK,mBAAmB,EAAG,QAAO;AACxD,QAAI;AACF,aAAO,OAAO,iBAAiB,aAAa,aAAa,IAAI;AAAA,IAC/D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAiE;AACvE,UAAM,aAAa,KAAK,OAAO,WAAW;AAC1C,QAAI,CAAC,cAAc,CAAC,KAAK,mBAAmB,EAAG,QAAO;AACtD,QAAI;AACF,YAAM,WAAW,OAAO,eAAe,aAAa,WAAW,IAAI;AACnE,aAAO,yBAAyB,QAAQ;AAAA,IAC1C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,yBACN,MACA,YACoB;AACpB,WAAO;AAAA,MACL,aAAa,6BAA6B;AAAA,MAC1C;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,MACpB,OAAO,KAAK,yBAAyB;AAAA,MACrC,YAAY,yBAAyB;AAAA,QACnC,GAAG,KAAK,uBAAuB;AAAA,QAC/B,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,cACN,MACA,WACA,QAA6B,CAAC,GACxB;AACN,UAAM,UAAU,KAAK,OAAO,WAAW;AACvC,QAAI,CAAC,WAAW,CAAC,KAAK,mBAAmB,EAAG;AAE5C,UAAM,aAAa,yBAAyB;AAAA,MAC1C,GAAG,UAAU;AAAA,MACb,GAAG,MAAM;AAAA,IACX,CAAC;AACD,UAAM,QAA+B;AAAA,MACnC;AAAA,MACA,aAAa,UAAU;AAAA,MACvB,MAAM,UAAU;AAAA,MAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,YAAY,MAAM,cAAc,KAAK,IAAI,IAAI,UAAU;AAAA,MACvD,UAAU,KAAK,OAAO;AAAA,MACtB,aAAa,KAAK,OAAO;AAAA,MACzB,WAAW,KAAK,aAAa;AAAA,MAC7B,OAAO,UAAU;AAAA,MACjB,GAAG;AAAA,MACH;AAAA,IACF;AAEA,QAAI;AACF,cAAQ,KAAK;AAAA,IACf,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,QACA,WACM;AACN,QAAI,CAAC,KAAK,mBAAmB,EAAG;AAChC,WAAO,IAAI,kBAAkB,UAAU,WAAW;AAClD,WAAO,IAAI,oBAAoB,UAAU,IAAI;AAC7C,QAAI,UAAU,OAAO,aAAa;AAChC,aAAO,IAAI,eAAe,UAAU,MAAM,WAAW;AAAA,IACvD;AACA,QAAI,UAAU,OAAO,YAAY;AAC/B,aAAO,IAAI,cAAc,UAAU,MAAM,UAAU;AAAA,IACrD;AACA,QAAI,UAAU,OAAO,SAAS;AAC5B,aAAO,IAAI,cAAc,UAAU,MAAM,OAAO;AAAA,IAClD;AACA,QAAI,UAAU,OAAO,QAAQ;AAC3B,aAAO,IAAI,aAAa,UAAU,MAAM,MAAM;AAAA,IAChD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiB,WAAwD;AAC/E,QAAI,CAAC,aAAa,CAAC,KAAK,mBAAmB,EAAG,QAAO,CAAC;AACtD,WAAO;AAAA,MACL,4BAA4B,UAAU;AAAA,MACtC,oBAAoB,UAAU;AAAA,MAC9B,GAAI,UAAU,OAAO,cAAc,EAAE,aAAa,UAAU,MAAM,YAAY,IAAI,CAAC;AAAA,MACnF,GAAI,UAAU,OAAO,aAAa,EAAE,YAAY,UAAU,MAAM,WAAW,IAAI,CAAC;AAAA,IAClF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,iBACN,WACoC;AACpC,QAAI,CAAC,KAAK,mBAAmB,EAAG,QAAO;AACvC,WAAO;AAAA,MACL,aAAa,UAAU;AAAA,MACvB,MAAM,UAAU;AAAA,MAChB,GAAI,UAAU,OAAO,cAAc,EAAE,aAAa,UAAU,MAAM,YAAY,IAAI,CAAC;AAAA,MACnF,GAAI,UAAU,OAAO,aAAa,EAAE,YAAY,UAAU,MAAM,WAAW,IAAI,CAAC;AAAA,MAChF,GAAI,UAAU,OAAO,UAAU,EAAE,SAAS,UAAU,MAAM,QAAQ,IAAI,CAAC;AAAA,MACvE,GAAI,UAAU,OAAO,SAAS,EAAE,QAAQ,UAAU,MAAM,OAAO,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA;AAAA,EAGQ,uBAAuB,SAGX;AAClB,WAAO,QAAQ,oBAAoB,QAAQ,YAAY,QAAQ,aAAa;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,0BAA0B,SAAuC;AACvE,WAAO,SAAS,iBAAiB,KAAK,OAAO,iBAAiB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAc,mBAAoD;AAChE,QAAI,CAAC,KAAK,aAAa;AACrB,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AACA,QAAI;AACF,YAAM,cAAc,MAAM,KAAK,YAAY,YAAY;AACvD,aAAO,EAAE,IAAI,MAAM,YAAY;AAAA,IACjC,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,qBACZ,yBACA,cACqC;AACrC,QAAI,CAAC,KAAK,aAAa;AACrB,aAAO,EAAE,IAAI,OAAO,SAAS,gCAAgC;AAAA,IAC/D;AACA,UAAM,eAAe,aAAa,KAAK,OAAO;AAC9C,QAAI,CAAC,aAAc,QAAO,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE;AAC1D,QAAI;AACF,YAAM,cAAc,KAAK;AACzB,YAAM,SAAS,MAAM,QAAQ;AAAA,QAC3B,wBAAwB;AAAA,UAAI,CAAC,OAAO,MAClC,aAAa,CAAC,IAAI,YAAY,kBAAkB,KAAK,IAAI,QAAQ,QAAQ,EAAE;AAAA,QAC7E;AAAA,MACF;AACA,aAAO,EAAE,IAAI,MAAM,iBAAiB,OAAO;AAAA,IAC7C,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,OAA0B;AACjC,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,eAAe,eAAqC;AAC1D,UAAM,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,cAAc;AAChD,UAAM,SAAS,IAAI,gBAAgB;AAEnC,QAAI,MAAM,MAAM;AACd,aAAO,IAAI,SAAS,MAAM,IAAI;AAAA,IAChC;AAOA,UAAM,kBAAkB,KAAK,MAAM,gBAAgB,KAAK,MAAM;AAC9D,UAAM,kBAAkB,eAAe,gBAAgB,eAAe;AACtE,UAAM,UAAU,mBAAmB;AACnC,QAAI,SAAS;AACX,aAAO,IAAI,UAAU,OAAO;AAAA,IAC9B;AAMA,UAAM,WAAW,MAAM;AACvB,QAAI,UAAU;AACZ,UAAI,SAAS,OAAO;AAClB,eAAO,IAAI,iBAAiB,SAAS,KAAK;AAAA,MAC5C;AACA,UAAI,SAAS,YAAY,QAAW;AAClC,eAAO,IAAI,mBAAmB,OAAO,SAAS,OAAO,CAAC;AAAA,MACxD;AACA,UAAI,SAAS,SAAS,QAAW;AAC/B,eAAO,IAAI,gBAAgB,OAAO,SAAS,IAAI,CAAC;AAAA,MAClD;AAAA,IACF;AAEA,WAAO,OAAO,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,eAAuB;AAC7B,WAAO,KAAK,OAAO,aAAa,KAAK,OAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeQ,kBAA0B;AAChC,UAAM,YAAY,KAAK,aAAa;AACpC,QAAI;AACF,aAAO,IAAI,IAAI,SAAS,EAAE;AAAA,IAC5B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAyB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAkC;AAChC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAuB;AACrB,WAAO,KAAK,OAAO,YAAY;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,UAAU,SAAoD;AAClE,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,UAAM,YAAY,KAAK,yBAAyB,UAAU;AAAA,MACxD,mBAAmB,CAAC,CAAC,QAAQ;AAAA,IAC/B,CAAC;AAED,QAAI;AACF,YAAM,oBAAoB,MAAM,KAAK,iBAAiB;AACtD,UAAI,CAAC,kBAAkB,IAAI;AACzB,cAAM,IAAI,MAAM,kBAAkB,OAAO;AAAA,MAC3C;AAEA,YAAM,SAAS,MAAM,oBAAoB;AAAA,QACvC,aAAa,KAAK,OAAO;AAAA,QACzB,YAAY,QAAQ;AAAA,QACpB,UAAU,KAAK,OAAO;AAAA,QACtB,aAAa,kBAAkB;AAAA,QAC/B,SAAS,KAAK,iBAAiB,SAAS;AAAA,MAC1C,CAAC;AACD,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,YAAY;AAAA,UACV,cAAc,OAAO,SAAS;AAAA,UAC9B,qBAAqB,OAAO,SAAS,SAAS;AAAA,UAC9C,qBAAqB,OAAO,SAAS,SAAS;AAAA,QAChD;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,WAAK,cAAc,iBAAiB,WAAW;AAAA,QAC7C,SAAS;AAAA,QACT,GAAG,uBAAuB,KAAK;AAAA,MACjC,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAc,uBACZ,UACA,UAAuD,CAAC,GACxD,WAC6B;AAC7B,UAAM,YAAY,QAAQ,aAAa;AACvC,UAAM,aAAa,QAAQ,cAAc;AACzC,UAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,WAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,UAAI;AACF,cAAM,WAAW,MAAM;AAAA,UACrB,GAAG,KAAK,OAAO,WAAW,sBAAsB,QAAQ;AAAA,UACxD;AAAA,YACE,SAAS;AAAA,cACP,GAAG,KAAK,iBAAiB,SAAS;AAAA,cAClC,GAAI,KAAK,OAAO,WAAW,EAAE,eAAe,KAAK,OAAO,SAAS,IAAI,CAAC;AAAA,YACxE;AAAA,UACF;AAAA,QACF;AACA,YAAI,SAAS,IAAI;AACf,gBAAM,OAAO,MAAM,SAAS,KAAK;AACjC,cAAI,KAAK,iBAAiB;AACxB,mBAAO,KAAK;AAAA,UACd;AACA,cAAI,KAAK,WAAW,YAAY,KAAK,WAAW,WAAW;AACzD,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,UAAU,CAAC;AAAA,IAChE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2BA,MAAM,cAAc,SAAqD;AACvE,WAAO,KAAK,cAAc,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,eAAe,SAAsD;AACzE,WAAO,KAAK,cAAc,EAAE,GAAG,SAAS,MAAM,QAAQ,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,uBAAuB,SAA8D;AACzF,WAAO,KAAK,cAAc,EAAE,GAAG,SAAS,MAAM,iBAAiB,CAAC;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAc,cAAc,SAAqD;AAC/E,UAAM,YAAY,KAAK,yBAAyB,QAAQ;AAAA,MACtD,MAAM,SAAS,QAAQ;AAAA,IACzB,CAAC;AACD,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,YAAY,KAAK,sBAAsB;AAC7C,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,QAAI,KAAK,OAAO,UAAU;AACxB,aAAO,IAAI,YAAY,KAAK,OAAO,QAAQ;AAAA,IAC7C;AACA,QAAI,SAAS,iBAAiB,OAAO;AACnC,aAAO,IAAI,SAAS,GAAG;AAAA,IACzB;AACA,QAAI,SAAS,YAAY;AAIvB,aAAO,IAAI,cAAc,GAAG;AAAA,IAC9B;AACA,QAAI,SAAS,SAAS,kBAAkB;AAItC,aAAO,IAAI,UAAU,GAAG;AAAA,IAC1B;AAGA,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAG5C,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AAEA,UAAM,WAAW,KAAK,kBAAkB,SAAS,IAAI;AACrD,UAAM,MAAM,GAAG,SAAS,GAAG,QAAQ,IAAI,OAAO,SAAS,CAAC;AAExD,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,GAAG;AAE9D,SAAK,cAAc,iBAAiB,WAAW,EAAE,SAAS,UAAU,CAAC;AACrE,UAAM,SAAS,MAAM,KAAK,yBAAyB,QAAQ,QAAQ,SAAS,SAAS;AACrF,QAAI,OAAO,SAAS;AAClB,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,YAAY,EAAE,YAAY,OAAO,cAAc,UAAU;AAAA,MAC3D,CAAC;AAAA,IACH,OAAO;AACL,WAAK;AAAA,QACH,OAAO,OAAO,SAAS,mBAAmB,qBAAqB;AAAA,QAC/D;AAAA,QACA;AAAA,UACE,SAAS,OAAO,OAAO,SAAS,mBAAmB,cAAc;AAAA,UACjE,GAAG,uBAAuB,OAAO,KAAK;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,wBAAgC;AACtC,QAAI,OAAO,WAAW,eAAe,gBAAgB,QAAQ;AAC3D,aAAO,OAAO,WAAW;AAAA,IAC3B;AACA,WAAO,UAAU,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,OAAiB,QAAgB;AACzD,QAAI,SAAS,QAAS,QAAO;AAC7B,QAAI,SAAS,iBAAkB,QAAO;AACtC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,iBAAiB,SAEI;AACzB,UAAM,YAAY,KAAK,yBAAyB,SAAS;AACzD,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,IACR,CAAC;AACD,QAAI,KAAK,OAAO,UAAU;AACxB,aAAO,IAAI,YAAY,KAAK,OAAO,QAAQ;AAAA,IAC7C;AACA,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAG5C,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AAEA,UAAM,MAAM,GAAG,SAAS,mBAAmB,OAAO,SAAS,CAAC;AAE5D,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,GAAG;AAC9D,SAAK,cAAc,iBAAiB,WAAW,EAAE,SAAS,UAAU,CAAC;AAErE,UAAM,QAAQ,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,SAAS;AAAA,MACnE,MAAM;AAAA,MACN,WAAW,KAAK,iBAAiB,SAAS;AAAA,IAC5C,CAAC;AACD,QAAI,CAAC,OAAO;AACV,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,OAAO,EAAE,MAAM,kBAAkB,SAAS,2BAA2B;AAAA,MACvE;AAAA,IACF;AACA,SAAK,cAAc,gBAAgB,WAAW,EAAE,SAAS,UAAU,CAAC;AAEpE,UAAM,SAAS,MAAM,KAAK,uBAAuB,QAAQ,QAAQ,OAAO;AACxE,QAAI,OAAO,SAAS;AAClB,WAAK,cAAc,qBAAqB,WAAW;AAAA,QACjD,SAAS;AAAA,QACT,YAAY;AAAA,UACV,eAAe,OAAO,kBAAkB;AAAA,UACxC,YAAY,OAAO,cAAc;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,WAAK;AAAA,QACH,OAAO,OAAO,SAAS,mBAAmB,qBAAqB;AAAA,QAC/D;AAAA,QACA;AAAA,UACE,SAAS,OAAO,OAAO,SAAS,mBAAmB,cAAc;AAAA,UACjE,GAAG,uBAAuB,OAAO,KAAK;AAAA,UACtC,YAAY,EAAE,QAAQ,OAAO,OAAO;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCA,MAAM,QAAQ,SAQa;AACzB,UAAM,gBAAgB,MAAM,KAAK;AAAA,MAC/B,SAAS,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI;AAAA,IAC9C;AAGA,QAAI,cAAc,QAAS,QAAO;AAIlC,QAAI,cAAc,WAAW,UAAU;AACrC,YAAM,aAAa,MAAM,KAAK,cAAc,OAAO;AACnD,UAAI,WAAW,WAAW,WAAW,MAAM;AACzC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,MAAM;AAAA,YACJ,SAAS,WAAW,KAAK;AAAA,UAC3B;AAAA;AAAA;AAAA;AAAA,UAIA,YAAY,WAAW,cAAc;AAAA,UACrC,eAAe;AAAA,QACjB;AAAA,MACF;AAGA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,OAAO,WAAW,SAAS;AAAA,UACzB,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAGA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,kBAAkB,SAEN;AAChB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,IACR,CAAC;AAED,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AAEA,UAAM,MAAM,GAAG,SAAS,mBAAmB,OAAO,SAAS,CAAC;AAe5D,UAAM,oBAAoB,MAAM,KAAK,iBAAiB;AACtD,UAAM,cAAuC,EAAE,MAAM,SAAS;AAC9D,QAAI,kBAAkB,IAAI;AACxB,kBAAY,OAAO,EAAE,aAAa,kBAAkB,YAAY;AAAA,IAClE;AAEA,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,GAAG;AAE9D,UAAM,QAAQ,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,SAAS,WAAW;AAChF,QAAI,CAAC,MAAO;AAGZ,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAc,CAAC,YAAY;AACpC,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,MAAM,SAAS,mBAAmB,MAAM,MAAM,SAAS,sBAAsB;AACrF,iBAAO,oBAAoB,WAAW,aAAa;AACnD,iBAAO,oBAAoB,SAAS,WAAW;AAC/C,kBAAQ;AACR,kBAAQ;AAAA,QACV;AAAA,MACF;AACA,YAAM,cAAc,MAAM;AACxB,eAAO,oBAAoB,WAAW,aAAa;AACnD,gBAAQ;AAAA,MACV;AACA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,cAAc,SAEgB;AAClC,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA;AAAA;AAAA,MAGN,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AAEA,UAAM,MAAM,GAAG,SAAS,mBAAmB,OAAO,SAAS,CAAC;AAE5D,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,GAAG;AAE9D,UAAM,QAAQ,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,SAAS;AAAA,MACnE,MAAM;AAAA,IACR,CAAC;AACD,QAAI,CAAC,MAAO,QAAO,EAAE,WAAW,MAAM;AAEtC,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAgC,CAAC,YAAY;AACtD,UAAI,YAAY;AAChB,YAAM,SAAS,MAAM;AACnB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAC/C,gBAAQ;AACR,gBAAQ,EAAE,UAAU,CAAC;AAAA,MACvB;AACA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,cAAM,OAAO,MAAM,MAAM;AACzB,YAAI,SAAS,2BAA2B;AAGtC,sBAAY,QAAQ,MAAM,MAAM,MAAM,aAAa,MAAM,MAAM,OAAO;AACtE;AAAA,QACF;AACA,YAAI,SAAS,mBAAmB,SAAS,sBAAsB;AAC7D,iBAAO;AAAA,QACT;AAAA,MACF;AACA,YAAM,cAAc,MAAM;AACxB,eAAO,oBAAoB,WAAW,aAAa;AACnD,gBAAQ,EAAE,UAAU,CAAC;AAAA,MACvB;AACA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,SAA2D;AAC5E,SAAK;AACL,WAAO,EAAE,YAAY,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAAe,SAA+D;AAClF,SAAK;AACL,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,iBAAiB,SAAmE;AACxF,UAAM,YAAY,KAAK,yBAAyB,oBAAoB;AAAA,MAClE,cAAc,2BAA2B,OAAO,EAAE,KAAK,GAAG;AAAA,MAC1D,SAAS,QAAQ,YAAY;AAAA,IAC/B,CAAC;AACD,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,WAAK,cAAc,2BAA2B,WAAW;AAAA,QACvD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,UAAM,eAAe,2BAA2B,OAAO;AACvD,UAAM,eAAe,2BAA2B,OAAO;AACvD,QAAI,aAAa,WAAW,KAAK,CAAC,QAAQ,qBAAqB,CAAC,QAAQ,aAAa,QAAQ;AAC3F,WAAK,cAAc,2BAA2B,WAAW;AAAA,QACvD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,cAAc,2BAA2B,WAAW;AAAA,QACvD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,oBAAoB,MAAM,KAAK,iBAAiB;AACtD,QAAI,CAAC,kBAAkB,IAAI;AACzB,WAAK,cAAc,2BAA2B,WAAW;AAAA,QACvD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc,kBAAkB;AAAA,MAClC,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,kBAAkB;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe,QAAQ,KAAK;AACrD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,WAAW,GAAG,SAAS,4BAA4B,OAAO,SAAS,CAAC;AAC1E,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,QAAQ;AACnE,UAAM,cAAc;AAAA,MAClB,MAAM;AAAA,MACN,UAAU,KAAK,OAAO;AAAA,MACtB,OAAO,kBAAkB;AAAA,QACvB,gBAAgB,QAAQ;AAAA,QACxB,aAAa,aAAa,CAAC;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,mBAAmB,QAAQ;AAAA,QAC3B,aAAa,QAAQ;AAAA,QACrB,mBAAmB,QAAQ;AAAA,QAC3B,YAAY,QAAQ;AAAA,QACpB,YAAY,QAAQ;AAAA,QACpB,SAAS,QAAQ;AAAA,QACjB,WAAW,QAAQ;AAAA,MACrB,CAAC;AAAA,MACD,MAAM,EAAE,aAAa,kBAAkB,YAAY;AAAA,MACnD,SAAS,QAAQ,YAAY;AAAA,MAC7B,WAAW,KAAK,iBAAiB,SAAS;AAAA,IAC5C;AAEA,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AACD,UAAM,SAAS,MAAM,KAAK;AAAA,MACxB;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,YAAY;AAAA,MACpB;AAAA,IACF;AACA,QAAI,OAAO,SAAS;AAClB,WAAK,cAAc,8BAA8B,WAAW;AAAA,QAC1D,SAAS;AAAA,QACT;AAAA,QACA,QAAQ,OAAO,SAAS,OAAO,OAAO,MAAM,IAAI;AAAA,MAClD,CAAC;AAOD,YAAM,KAAK,mBAAmB,QAAQ,OAAO;AAAA,IAC/C,OAAO;AACL,WAAK;AAAA,QACH,OAAO,OAAO,SAAS,mBAAmB,qBAAqB;AAAA,QAC/D;AAAA,QACA;AAAA,UACE,SAAS,OAAO,OAAO,SAAS,mBAAmB,cAAc;AAAA,UACjE;AAAA,UACA,GAAG,uBAAuB,OAAO,KAAK;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,SACkC;AAClC,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,QAAQ,eAAgB,QAAO,IAAI,kBAAkB,QAAQ,cAAc;AAC/E,QAAI,QAAQ,eAAgB,QAAO,IAAI,kBAAkB,MAAM;AAE/D,QAAI;AACF,YAAM,WAAW,MAAM;AAAA,QACrB,GAAG,KAAK,OAAO,WAAW,wBAAwB,OAAO,SAAS,CAAC;AAAA,QACnE,EAAE,aAAa,UAAU;AAAA,MAC3B;AACA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,MAAM,SAAS,8BAA8B,SAAS,MAAM;AAAA,UACvE;AAAA,QACF;AAAA,MACF;AACA,aAAO,EAAE,SAAS,MAAM,QAAQ,KAAK,UAAU,CAAC,EAAE;AAAA,IACpD,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC1D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCA,MAAM,aAAa,SAAsF;AACvG,UAAM,YAAY,KAAK,yBAAyB,gBAAgB;AAAA,MAC9D,cAAc,CAAC,CAAC,SAAS;AAAA,IAC3B,CAAC;AACD,UAAM,aAAa,MAAM,KAAK,cAAc,SAAS,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAS;AACjG,QAAI,CAAC,WAAW,SAAS;AACvB,WAAK;AAAA,QACH,WAAW,OAAO,SAAS,mBAAmB,qBAAqB;AAAA,QACnE;AAAA,QACA;AAAA,UACE,SAAS,WAAW,OAAO,SAAS,mBAAmB,cAAc;AAAA,UACrE,GAAG,uBAAuB,WAAW,KAAK;AAAA,QAC5C;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,SAAS,WAAW;AACvB,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,YAAY,EAAE,iBAAiB,MAAM;AAAA,MACvC,CAAC;AACD,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,WAAW,MAAM;AACxC,QAAI,CAAC,gBAAgB;AACnB,YAAMC,UAA6B;AAAA,QACjC,SAAS;AAAA,QACT,MAAM,WAAW;AAAA,QACjB,YAAY,WAAW;AAAA,QACvB,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AACA,WAAK,cAAc,eAAe,WAAW;AAAA,QAC3C,SAAS;AAAA,QACT,GAAG,uBAAuBA,QAAO,KAAK;AAAA,MACxC,CAAC;AACD,aAAOA;AAAA,IACT;AAEA,UAAM,aAAa,MAAM,KAAK,YAAY;AAAA,MACxC;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,aAAa;AAAA,MACb,OAAO,QAAQ;AAAA,IACjB,CAAC;AAED,QAAI,WAAW,WAAW,WAAW,aAAa,WAAW,YAAY;AACvE,YAAMA,UAA6B;AAAA,QACjC,GAAG;AAAA,QACH,WAAW;AAAA,UACT,WAAW,WAAW;AAAA,UACtB,YAAY,WAAW;AAAA,QACzB;AAAA,MACF;AACA,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,YAAY,EAAE,iBAAiB,KAAK;AAAA,MACtC,CAAC;AACD,aAAOA;AAAA,IACT;AAEA,UAAM,QAAQ,WAAW,QACrB,EAAE,MAAM,WAAW,MAAM,MAAM,SAAS,WAAW,MAAM,QAAQ,IACjE,EAAE,MAAM,kBAAkB,SAAS,2BAA2B;AAClE,UAAM,SAA6B;AAAA,MACjC,SAAS;AAAA,MACT,MAAM,WAAW;AAAA,MACjB,YAAY,WAAW;AAAA,MACvB;AAAA,IACF;AACA,UAAM,YAAY,MAAM,SAAS,oBAAoB,MAAM,SAAS;AACpE,SAAK;AAAA,MACH,YAAY,qBAAqB;AAAA,MACjC;AAAA,MACA;AAAA,QACE,SAAS,YAAY,cAAc;AAAA,QACnC,GAAG,uBAAuB,KAAK;AAAA,MACjC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,SAAkF;AACpG,UAAM,YAAY,KAAK,yBAAyB,QAAQ;AAAA,MACtD,aAAa;AAAA,MACb,gBAAgB,CAAC,CAAC,QAAQ;AAAA,MAC1B,mBAAmB,CAAC,CAAC,QAAQ;AAAA,IAC/B,CAAC;AACD,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,aAAa,GAAG,SAAS,gBAAgB,OAAO,SAAS,CAAC;AAChE,UAAM,wBAAwB,KAAK,0BAA0B,OAAO;AAEpE,UAAM,EAAE,QAAQ,QAAQ,SAAS,OAAO,IAAI,KAAK,kBAAkB,YAAY;AAAA,MAC7E,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT,YAAY,EAAE,cAAc,sBAAsB;AAAA,IACpD,CAAC;AAED,UAAM,QAAQ,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,SAAS;AAAA,MACnE,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,MACrB,aAAa,QAAQ;AAAA,MACrB,UAAU,QAAQ;AAAA,MAClB,WAAW,KAAK,iBAAiB,SAAS;AAAA,IAC5C,GAAG;AAAA,MACD,cAAc;AAAA,MACd;AAAA,IACF,CAAC;AACD,QAAI,CAAC,OAAO;AACV,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AACA,SAAK,cAAc,gBAAgB,WAAW,EAAE,SAAS,UAAU,CAAC;AAEpE,UAAM,SAAS,MAAM,KAAK,uBAAuB,QAAQ,QAAQ,OAAO;AACxE,QAAI,OAAO,SAAS;AAClB,WAAK,cAAc,kBAAkB,WAAW,EAAE,SAAS,UAAU,CAAC;AAAA,IACxE,OAAO;AACL,WAAK;AAAA,QACH,OAAO,OAAO,SAAS,kBAAkB,qBAAqB;AAAA,QAC9D;AAAA,QACA;AAAA,UACE,SAAS,OAAO,OAAO,SAAS,kBAAkB,cAAc;AAAA,UAChE,GAAG,uBAAuB,OAAO,KAAK;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BA,MAAM,WAAW,SAAuD;AACtE,UAAM,EAAE,gBAAgB,YAAY,IAAI;AAIxC,UAAM,QAAQ,cAAc,QAAQ,KAAK;AACzC,UAAM,kBAAkB,KAAK,uBAAuB,OAAO;AAC3D,UAAM,UAAU,oBAAoB;AACpC,UAAM,YAAY,KAAK,yBAAyB,UAAU;AAAA,MACxD,aAAa,eAAe;AAAA,MAC5B,YAAY,OAAO,UAAU;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,cAAc,KAAK,0BAA0B,OAAO;AAAA,IACtD,CAAC;AAED,QAAI,oBAAoB,MAAM,OAAO;AACnC,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,gBAAgB;AACnB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,CAAC,CAAC,OAAO;AAC1B,UAAM,mBAAmB,CAAC,CAAC,QAAQ,eAAe;AAClD,QAAI,CAAC,eAAgB,CAAC,YAAY,CAAC,kBAAmB;AACpD,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,cAAc,yBAAyB,WAAW;AAAA,QACrD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAGA,UAAM,0BAA0B,QAAQ,eAAe,IAAI,CAAC,OAAO;AAAA,MACjE,OAAO,EAAE;AAAA,MACT,QAAQ,EAAE,OAAO,SAAS;AAAA,IAC5B,EAAE;AACF,QAAI;AAuBJ,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,aAAa,GAAG,SAAS,gBAAgB,OAAO,SAAS,CAAC;AAChE,UAAM,wBAAwB,KAAK,0BAA0B,OAAO;AACpE,UAAM,EAAE,QAAQ,QAAQ,SAAS,OAAO,IAAI,KAAK,kBAAkB,YAAY;AAAA,MAC7E,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT,YAAY,EAAE,cAAc,sBAAsB;AAAA,IACpD,CAAC;AAED,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,iBAAiB,KAAK,IAAI;AAChC,QAAI,sBAAsB;AAE1B,QAAI,sBAAkC,MAAM;AAC5C,UAAM,0BAA0B,IAAI,QAA0B,CAAC,YAAY;AACzE,UAAI,UAAU;AACd,YAAM,OAAO,MAAM;AACjB,YAAI,QAAS;AACb,kBAAU;AACV,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AACA,4BAAsB;AAEtB,YAAM,gBAAgB,CAAC,UAAmB;AACxC,aAAK;AACL,gBAAQ;AACR,gBAAQ,EAAE,MAAM,iBAAiB,MAAM,CAAC;AAAA,MAC1C;AAEA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AASnC,YACE,MAAM,MAAM,SAAS,mBACrB,MAAM,WAAW,OAAO,eACxB;AACA,wBAAc,mBAAmB;AAAA,QACnC;AAAA,MACF;AAEA,YAAM,cAAc,MAAM;AACxB,sBAAc,mBAAmB;AAAA,MACnC;AAKA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AACD,QAAI;AACJ,UAAM,qBAAqB,KAAK,2BAA2B,QAAQ,QAAQ,SAAS;AAAA,MAClF,cAAc;AAAA,MACd;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,WAAW;AAClB,8BAAwB,KAAK,IAAI,IAAI;AACrC,4BAAsB,OAAO;AAC7B,aAAO;AAAA,IACT,CAAC;AACD,UAAM,iCAAiC,mBAAmB;AAAA,MAAK,CAAC,WAC9D,OAAO,QACH,IAAI,QAAe,MAAM,MAAS,IACjC,EAAE,MAAM,iBAA0B,OAAO,MAAM;AAAA,IACtD;AAEA,UAAM,uBAAuB,KAAK,IAAI;AACtC,QAAI;AACJ,UAAM,qBAAqB,KAAK,iBAAiB,EAAE,KAAK,CAAC,WAAW;AAClE,8BAAwB,KAAK,IAAI,IAAI;AACrC,aAAO;AAAA,IACT,CAAC;AAED,UAAM,gBAAgB,MAAM,QAAQ,KAAK;AAAA,MACvC,mBAAmB,KAAK,CAAC,YAAY,EAAE,MAAM,gBAAyB,OAAO,EAAE;AAAA,MAC/E;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,cAAc,SAAS,iBAAiB;AAC1C,0BAAoB;AACpB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc,cAAc,QACxB,gEACA;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,EAAE,MAAM,kBAAkB,SAAS,yBAAyB;AAAA,MACrE;AAAA,IACF;AAEA,UAAM,oBAAoB,cAAc;AAMxC,QAAI,qBAA+D;AACnE,QAAI,CAAC,kBAAkB,IAAI;AACzB,YAAM,YAAY,kBAAkB,QAAQ;AAC5C,WAAK,cAAc,yBAAyB,WAAW;AAAA,QACrD,SAAS;AAAA,QACT;AAAA,QACA,cAAc,kBAAkB;AAAA,QAChC,YAAY;AAAA,UACV;AAAA,UACA;AAAA,UACA,cAAc;AAAA,QAChB;AAAA,MACF,CAAC;AACD,2BAAqB,EAAE,MAAM,WAAW,SAAS,kBAAkB,QAAQ;AAAA,IAC7E;AAIA,QAAI,cAAc,kBAAkB,KAAK,kBAAkB,cAAc;AAGzE,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,MAAM,EAAE,YAAY;AAAA,MACpB,GAAI,KAAK,OAAO,YAAY,EAAE,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/D;AAQA,QAAI,qBAA2C;AAK/C,QAAI,yBACF,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AACnD,QAAI;AACJ,SAAK,cAAc,0BAA0B,WAAW;AAAA,MACtD,SAAS;AAAA,MACT;AAAA,MACA,YAAY;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AACD,UAAM,mBAAmB,KAAK,IAAI;AAClC,QAAI;AAGJ,UAAM,aAAa,YAAoC;AACrD,UAAI;AAEJ,UAAI,oBAAoB,YAAY;AAClC,iBAAS,MAAM,KAAK;AAAA,UAClB,EAAE,GAAG,aAAa,WAAW,SAAS,iBAAiB,cAAc;AAAA,UACrE;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,QAAQ,MAAM,KAAK;AAAA,UACvB,EAAE,GAAG,aAAa,iBAAiB,WAAW;AAAA,UAC9C;AAAA,QACF;AACA,YAAI,CAAC,MAAM,SAAS;AAClB,mBAAS;AAAA,QACX,OAAO;AACL,gBAAM,2BAA2B,KAAK,IAAI;AAC1C,gBAAM,mBAAmB,MAAM,KAAK;AAAA,YAClC,CAAC,KAAK,UAAU,MAAM,sBAAsB,CAAC;AAAA,YAC7C,CAAC,IAAI;AAAA,UACP;AACA,sCAA4B,KAAK,IAAI,IAAI;AACzC,cAAI,CAAC,iBAAiB,IAAI;AACxB,gBAAI,oBAAoB,aAAa;AACnC,uCAAyB,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AAC1E,uBAAS,MAAM,KAAK;AAAA,gBAClB,EAAE,GAAG,aAAa,WAAW,SAAS,iBAAiB,cAAc;AAAA,gBACrE;AAAA,cACF;AAAA,YACF,OAAO;AACL,uBAAS;AAAA,gBACP,SAAS;AAAA,gBACT,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,SAAS,iBAAiB;AAAA,gBAC5B;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AACL,kBAAM,oBAAoB,CAAC,eAAuB,KAAK;AAAA,cACrD;AAAA,gBACE,GAAG;AAAA,gBACH,WAAW;AAAA,gBACX,iBAAiB;AAAA,gBACjB,MAAM;AAAA,kBACJ;AAAA,kBACA,gBAAgB;AAAA,gBAClB;AAAA,cACF;AAAA,cACA;AAAA,YACF;AACA,gBAAI,mBAAmB;AACvB,qBAAS,MAAM,kBAAkB,iBAAiB,gBAAgB,CAAC,CAAC;AACpE,gBAAI,CAAC,OAAO,SAAS;AAInB,oBAAM,wBAAwB,MAAM,KAAK;AAAA,gBACvC,CAAC,KAAK,UAAU,MAAM,sBAAsB,CAAC;AAAA,gBAC7C,CAAC,IAAI;AAAA,cACP;AACA,kBAAI,sBAAsB,IAAI;AAC5B,yBAAS,MAAM,kBAAkB,sBAAsB,gBAAgB,CAAC,CAAC;AAAA,cAC3E;AAAA,YACF;AACA,gBAAI,CAAC,OAAO,WAAW,oBAAoB,aAAa;AAItD,uCAAyB,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AAC1E,iCAAmB;AACnB,uBAAS,MAAM,KAAK;AAAA,gBAClB,EAAE,GAAG,aAAa,WAAW,SAAS,iBAAiB,cAAc;AAAA,gBACrE;AAAA,cACF;AAAA,YACF;AACA,gBAAI,OAAO,WAAW,kBAAkB;AACtC,oBAAM,uBAAuB,MAAM,KAAK;AAAA,gBACtC,CAAC,OAAO,KAAK,QAAQ;AAAA,gBACrB,CAAC,IAAI;AAAA,cACP;AACA,0CAA4B,KAAK,IAAI,IAAI;AACzC,kBAAI,CAAC,qBAAqB,IAAI;AAC5B,oBAAI,oBAAoB,aAAa;AACnC,2CAAyB,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AAC1E,qCAAmB;AACnB,2BAAS,MAAM,KAAK;AAAA,oBAClB,EAAE,GAAG,aAAa,WAAW,SAAS,iBAAiB,cAAc;AAAA,oBACrE;AAAA,kBACF;AAAA,gBACF,OAAO;AACL,2BAAS;AAAA,oBACP,SAAS;AAAA,oBACT,OAAO;AAAA,sBACL,MAAM;AAAA,sBACN,SAAS,qBAAqB;AAAA,oBAChC;AAAA,kBACF;AAAA,gBACF;AAAA,cACF,OAAO;AACL,yCAAyB,QAAQ,QAAQ,oBAAoB;AAAA,cAC/D;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,2BAAqB;AACrB,0BAAoB,KAAK,IAAI,IAAI;AACjC,WAAK;AAAA,QACH,OAAO,UAAU,6BAA6B;AAAA,QAC9C;AAAA,QACA,OAAO,UACH;AAAA,UACE,SAAS;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,UACR,YAAY,EAAE,uBAAuB,uBAAuB,kBAAkB;AAAA,QAChF,IACA;AAAA,UACE,SAAS;AAAA,UACT;AAAA,UACA,GAAG,uBAAuB,OAAO,KAAK;AAAA,UACtC,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAAA,QACF;AAAA,MACN;AACA,aAAO;AAAA,IACT;AAKA,UAAM,iBAAiB,qBACnB,QAAQ,QAAuB;AAAA,MAC7B,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC,EAAE,KAAK,CAAC,MAAM;AACb,2BAAqB;AACrB,aAAO;AAAA,IACT,CAAC,IACD,WAAW;AAOf,UAAM,eAAe,YAAoC;AACvD,YAAM,mBAAmB,MAAM,KAAK,iBAAiB;AACrD,UAAI,CAAC,iBAAiB,IAAI;AACxB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM,iBAAiB,QAAQ;AAAA,YAC/B,SAAS,iBAAiB;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AACA,oBAAc,iBAAiB;AAC/B,kBAAY,OAAO,EAAE,YAAY;AACjC,+BAAyB,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AAC1E,aAAO,WAAW;AAAA,IACpB;AAGA,UAAM,eAAe,MAAM,QAAQ,KAAK;AAAA,MACtC,mBAAmB,KAAK,CAAC,YAAY,EAAE,MAAM,SAAkB,OAAO,EAAE;AAAA,MACxE;AAAA,IACF,CAAC;AACD,QAAI,aAAa,SAAS,iBAAiB;AACzC,0BAAoB;AACpB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc,aAAa,QACvB,gEACA;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,EAAE,MAAM,kBAAkB,SAAS,yBAAyB;AAAA,MACrE;AAAA,IACF;AACA,UAAM,eAAe,aAAa;AAGlC,QAAI,CAAC,aAAa,OAAO;AACvB,0BAAoB;AACpB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,EAAE,MAAM,kBAAkB,SAAS,yBAAyB;AAAA,MACrE;AAAA,IACF;AACA,UAAM,eAAe,aAAa;AAClC,SAAK,cAAc,gBAAgB,WAAW;AAAA,MAC5C,SAAS;AAAA,MACT,YAAY;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAGD,QAAI;AACJ,UAAM,eAAe,YAAY;AAC/B,UAAI;AAMF,cAAM,uBAAuB,MAAM,KAAK,iBAAiB;AACzD,cAAM,eAAe,qBAAqB,KACtC,qBAAqB,cACrB;AACJ,sBAAc;AACd,oBAAY,OAAO,EAAE,aAAa,aAAa;AAC/C,iCAAyB,QAAQ,QAAQ,EAAE,IAAI,MAAM,iBAAiB,CAAC,EAAE,CAAC;AAC1E,cAAM,kBAAkB,MAAM,WAAW;AACzC,YAAI,CAAC,gBAAgB,SAAS;AAC5B,kBAAQ,MAAM,+BAA+B,gBAAgB,MAAM,OAAO;AAC1E,iBAAO;AAAA,QACT;AACA,cAAM,gBAAgB,gBAAgB;AACtC,cAAM,kBAAkB,MAAM;AAC9B,YAAI,CAAC,gBAAgB,IAAI;AACvB,kBAAQ,MAAM,yCAAyC,gBAAgB,OAAO;AAC9E,iBAAO;AAAA,QACT;AACA,cAAM,gBAAmC;AAAA,UACvC,aAAa;AAAA,UACb,iBAAiB,gBAAgB;AAAA,QACnC;AAIA,0BAAkB;AAClB,iCAAyB,QAAQ,QAAQ,eAAe;AAGxD,6BAAqB;AAAA,UACnB,GAAG;AAAA,UACH,aAAa,cAAc;AAAA,UAC3B,WAAW,cAAc;AAAA,UACzB,gBAAgB,cAAc;AAAA,UAC9B,WAAW,cAAc;AAAA,UACzB,UAAU,cAAc;AAAA,UACxB,cAAc,cAAc;AAAA;AAAA;AAAA;AAAA,UAI5B,SAAS,cAAc;AAAA,UACvB,MAAM;AAAA,QACR;AACA,eAAO;AAAA,UACL,UAAU,cAAc;AAAA,UACxB,WAAW,cAAc;AAAA,UACzB,WAAW,cAAc;AAAA,UACzB,gBAAgB,cAAc,gBAAgB,IAAI,CAAC,aAAa;AAAA,YAC9D,SAAS,QAAQ;AAAA,YACjB,MAAM,QAAQ;AAAA,UAChB,EAAE;AAAA,UACF,aAAa,cAAc;AAAA,UAC3B,cAAc,cAAc;AAAA,UAC5B,SAAS,cAAc;AAAA;AAAA;AAAA;AAAA,UAIvB,MAAM;AAAA,QACR;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,8BAA8B,KAAK;AACjD,eAAO;AAAA,MACT;AAAA,IACF;AAIA,UAAM,uBAAuB,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,wBAAoB;AAEpB,QAAI,oBAAoB;AAGtB,UAAI,gBAAgB;AAIpB,iBAAS;AACP,eAAO,CAAC,cAAc,SAAS;AAC7B,eAAK,iBAAiB,QAAQ,cAAc,MAAM,OAAO;AACzD,cAAI,cAAc;AAEhB,oBAAQ;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,OAAO,cAAc;AAAA,YACvB;AAAA,UACF;AACA,gBAAMC,QAAO,MAAM,KAAK,2BAA2B,QAAQ,OAAO;AAClE,cAAIA,UAAS,UAAU;AACrB,mBAAO;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,OAAO,cAAc;AAAA,YACvB;AAAA,UACF;AACA,0BAAgB,MAAM,aAAa;AAAA,QACrC;AACA,0BAAkB,cAAc;AAChC,cAAM,kBAAkB,MAAM;AAC9B,YAAI,gBAAgB,IAAI;AACtB,gBAAM,oBAAuC;AAAA,YAC3C;AAAA,YACA,iBAAiB,gBAAgB;AAAA,UACnC;AACA,+BAAqB;AAAA,YACnB,MAAM;AAAA,YACN;AAAA,YACA,SAAS;AAAA,YACT,aAAa,gBAAgB;AAAA,YAC7B,WAAW,gBAAgB;AAAA,YAC3B,gBAAgB,gBAAgB;AAAA,YAChC,gBAAgB,gBAAgB;AAAA,YAChC,eAAe;AAAA,YACf,WAAW,gBAAgB;AAAA,YAC3B,QAAQ,gBAAgB;AAAA,YACxB,UAAU,gBAAgB;AAAA,YAC1B,cAAc,gBAAgB;AAAA,YAC9B,SAAS,gBAAgB;AAAA,YACzB,MAAM,cAAc;AAAA,YACpB,MAAM;AAAA,YACN,WAAW,KAAK,iBAAiB,SAAS;AAAA,UAC5C;AACA,uBAAa,SAAS,kBAAkB;AACxC;AAAA,QACF;AACA,aAAK,cAAc,yBAAyB,WAAW;AAAA,UACrD,SAAS;AAAA,UACT,WAAW;AAAA,UACX,cAAc,gBAAgB;AAAA,UAC9B,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAAA,QACF,CAAC;AACD,aAAK,iBAAiB,QAAQ,gBAAgB,OAAO;AACrD,YAAI,cAAc;AAChB,kBAAQ;AACR,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,OAAO,EAAE,MAAM,4BAA4B,SAAS,gBAAgB,QAAQ;AAAA,UAC9E;AAAA,QACF;AACA,cAAM,OAAO,MAAM,KAAK,2BAA2B,QAAQ,OAAO;AAClE,YAAI,SAAS,UAAU;AACrB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,OAAO,EAAE,MAAM,4BAA4B,SAAS,gBAAgB,QAAQ;AAAA,UAC9E;AAAA,QACF;AAGA,wBAAgB,MAAM,aAAa;AAAA,MACrC;AAAA,IACF,OAAO;AAQL,2BAAqB;AAAA,QACnB,MAAM;AAAA,QACN,aAAa;AAAA,QACb;AAAA,QACA,SAAS;AAAA,QACT,gBAAgB,QAAQ;AAAA,QACxB,eAAe;AAAA,QACf,WAAW,KAAK,iBAAiB,SAAS;AAAA,MAC5C;AACA,mBAAa,SAAS,kBAAkB;AAGxC,YAAM,kBAAkB,MAAM,QAAQ,KAAK;AAAA,QACzC,eAAe,KAAK,CAACC,oBAAmB;AAAA,UACtC,MAAM;AAAA,UACN,eAAAA;AAAA,QACF,EAAE;AAAA,QACF,qBAAqB,KAAK,CAACC,oBAAmB;AAAA,UAC5C,MAAM;AAAA,UACN,eAAAA;AAAA,QACF,EAAE;AAAA,MACJ,CAAC;AACD,UAAI;AACJ,UAAI,gBAAgB,SAAS,WAAW;AACtC,cAAM,qBAAqB,gBAAgB;AAC3C,YAAI,mBAAmB,SAAS;AAI9B,0BAAgB,MAAM;AAAA,QACxB,OAAO;AACL,gBAAM,eAAe,mBAAmB;AACxC,eAAK;AAAA,YACH,cAAc,SAAS,kBACnB,qBACA;AAAA,YACJ;AAAA,YACA;AAAA,cACE,SAAS,cAAc,SAAS,kBAAkB,cAAc;AAAA,cAChE,GAAG,uBAAuB,YAAY;AAAA,YACxC;AAAA,UACF;AACA,cAAI,aAAc,SAAQ;AAC1B,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,OAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF,OAAO;AACL,wBAAgB,gBAAgB;AAAA,MAClC;AAOA,iBAAS;AACP,eAAO,CAAC,cAAc,SAAS;AAC7B,eAAK,iBAAiB,QAAQ,cAAc,MAAM,OAAO;AACzD,cAAI,cAAc;AAEhB,oBAAQ;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,OAAO,cAAc;AAAA,YACvB;AAAA,UACF;AACA,gBAAMF,QAAO,MAAM,KAAK,2BAA2B,QAAQ,OAAO;AAClE,cAAIA,UAAS,UAAU;AACrB,mBAAO;AAAA,cACL,SAAS;AAAA,cACT,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,OAAO,cAAc;AAAA,YACvB;AAAA,UACF;AACA,0BAAgB,MAAM,aAAa;AAAA,QACrC;AACA,0BAAkB,cAAc;AAChC,cAAM,YACJ,CAAC,UACI;AAAA,UACC;AAAA,UACA,iBAAiB,CAAC;AAAA,QACpB,IACA;AAKN,6BAAqB;AAAA,UACnB,MAAM;AAAA,UACN;AAAA,UACA,SAAS;AAAA,UACT,aAAa,gBAAgB;AAAA,UAC7B,WAAW,gBAAgB;AAAA,UAC3B,gBAAgB,gBAAgB;AAAA,UAChC,gBAAgB,gBAAgB;AAAA,UAChC,eAAe;AAAA,UACf,WAAW,gBAAgB;AAAA,UAC3B,QAAQ,gBAAgB;AAAA,UACxB,UAAU,gBAAgB;AAAA,UAC1B,cAAc,gBAAgB;AAAA,UAC9B,SAAS,gBAAgB;AAAA,UACzB,MAAM,cAAc;AAAA,UACpB,GAAI,aAAa,EAAE,MAAM,UAAU;AAAA,UACnC,WAAW,KAAK,iBAAiB,SAAS;AAAA,QAC5C;AAKA,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,uBAAuB,GAAG,oBAAoB,cAAc,MAAM,aAAa;AAAA,UACvF;AAAA,QACF;AAEA,YAAI,CAAC,QAAS;AAEd,cAAM,kBAAkB,MAAM;AAC9B,YAAI,gBAAgB,IAAI;AACtB,gBAAM,oBAAuC;AAAA,YAC3C;AAAA,YACA,iBAAiB,gBAAgB;AAAA,UACnC;AACA,+BAAqB;AAAA,YACnB,GAAG;AAAA,YACH,MAAM;AAAA,UACR;AACA,iBAAO,eAAe;AAAA,YACpB,EAAE,MAAM,uBAAuB,MAAM,mBAAmB,cAAc,MAAM,aAAa;AAAA,YACzF;AAAA,UACF;AACA;AAAA,QACF;AAEA,aAAK,cAAc,yBAAyB,WAAW;AAAA,UACrD,SAAS;AAAA,UACT,WAAW;AAAA,UACX,cAAc,gBAAgB;AAAA,UAC9B,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAAA,QACF,CAAC;AACD,aAAK,iBAAiB,QAAQ,gBAAgB,OAAO;AACrD,YAAI,cAAc;AAChB,kBAAQ;AACR,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,OAAO,EAAE,MAAM,4BAA4B,SAAS,gBAAgB,QAAQ;AAAA,UAC9E;AAAA,QACF;AACA,cAAM,OAAO,MAAM,KAAK,2BAA2B,QAAQ,OAAO;AAClE,YAAI,SAAS,UAAU;AACrB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,OAAO,EAAE,MAAM,4BAA4B,SAAS,gBAAgB,QAAQ;AAAA,UAC9E;AAAA,QACF;AACA,wBAAgB,MAAM,aAAa;AAAA,MACrC;AAAA,IACF;AAMA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,oBAAoB,cAAc,MAAM,aAAa;AAAA,UAChF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAIhD,UAAM,gBAAgB,MAAM;AAE5B,WAAO,oBAAoB,WAAW,aAAa;AAEnD,QAAI,CAAC,cAAc,SAAS;AAC1B,WAAK;AAAA,QACH,cAAc,OAAO,SAAS,kBAAkB,qBAAqB;AAAA,QACrE;AAAA,QACA;AAAA,UACE,SAAS,cAAc,OAAO,SAAS,kBAAkB,cAAc;AAAA,UACvE,GAAG,uBAAuB,cAAc,KAAK;AAAA,UAC7C,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,UAAI,aAAc,SAAQ;AAC1B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAIA,UAAM,uBAAuB,cAAc,iBAAiB,cAAc;AAG1E,QAAI;AAEJ,QAAI,sBAAsB;AAExB,wBAAkB;AAAA,QAChB,SAAS;AAAA,QACT,UAAU,cAAc;AAAA,QACxB,QAAQ;AAAA,MACV;AACA,WAAK,cAAc,yBAAyB,WAAW;AAAA,QACrD,SAAS;AAAA,QACT,YAAY;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AAKL,YAAM,kBAAkB,MAAM;AAC9B,UAAI,CAAC,gBAAgB,IAAI;AACvB,aAAK,cAAc,sBAAsB,WAAW;AAAA,UAClD,SAAS;AAAA,UACT,WAAW;AAAA,UACX,cAAc,gBAAgB;AAAA,UAC9B,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,cAAc;AAAA,UAChB;AAAA,QACF,CAAC;AACD,aAAK,sBAAsB,QAAQ,QAAQ;AAC3C,cAAM,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACtE,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,OAAO,EAAE,MAAM,4BAA4B,SAAS,gBAAgB,QAAQ;AAAA,QAC9E;AAAA,MACF;AACA,YAAM,kBAAkB,gBAAgB;AACxC,UAAI;AACF,aAAK,cAAc,yBAAyB,WAAW;AAAA,UACrD,SAAS;AAAA,UACT,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,gBAAgB;AAAA,UAClB;AAAA,QACF,CAAC;AACD,aAAK,cAAc,0BAA0B,WAAW;AAAA,UACtD,SAAS;AAAA,UACT,aAAa,gBAAgB;AAAA,UAC7B,YAAY;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AACD,cAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,uBAAuB;AAAA,UAC5E,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,GAAG,KAAK,iBAAiB,SAAS;AAAA,UACpC;AAAA,UACA,MAAM,KAAK,UAAU;AAAA;AAAA,YAEnB,UAAU,gBAAgB;AAAA,YAC1B,QAAQ,gBAAgB;AAAA,YACxB,aAAa,gBAAgB;AAAA,YAC7B,OAAO,gBAAgB;AAAA,YACvB,WAAW,gBAAgB;AAAA,YAC3B,cAAc,gBAAgB;AAAA;AAAA,YAE9B,SAAS,gBAAgB;AAAA;AAAA,YAEzB,WAAW,cAAc;AAAA,YACzB,SAAS,iCAAiC,cAAc,OAAO;AAAA;AAAA;AAAA,YAG/D,MAAM;AAAA,cACJ;AAAA,cACA,GAAI,gBAAgB,SAAS,KAAK;AAAA,gBAChC,gBAAgB,gBAAgB,CAAC;AAAA,cACnC;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAExD,eAAK,sBAAsB,QAAQ,QAAQ;AAC3C,gBAAM,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACtE,eAAK,cAAc,yBAAyB,WAAW;AAAA,YACrD,SAAS;AAAA,YACT,aAAa,gBAAgB;AAAA,YAC7B,WAAW,iBAAiB,SAAS;AAAA,YACrC,cAAc,UAAU,SAAS;AAAA,UACnC,CAAC;AACD,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA;AAAA,YACV,QAAQ;AAAA,YACR,OAAO;AAAA,cACL,MAAM,iBAAiB,SAAS;AAAA,cAChC,SAAS,UAAU,SAAS;AAAA,cAC5B,SAAS,oBAAoB,UAAU,KAAK;AAAA,YAC9C;AAAA,UACF;AAAA,QACF;AAEA,0BAAkB,MAAM,SAAS,KAAK;AACtC,aAAK,cAAc,4BAA4B,WAAW;AAAA,UACxD,SAAS;AAAA,UACT,aAAa,gBAAgB;AAAA,UAC7B,QAAQ,gBAAgB;AAAA,QAC1B,CAAC;AAAA,MACH,SAAS,OAAO;AAEd,aAAK,sBAAsB,QAAQ,QAAQ;AAC3C,cAAM,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACtE,aAAK,cAAc,yBAAyB,WAAW;AAAA,UACrD,SAAS;AAAA,UACT,aAAa,gBAAgB;AAAA,UAC7B,GAAG,uBAAuB,KAAK;AAAA,QACjC,CAAC;AACD,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA;AAAA,UACV,QAAQ;AAAA,UACR,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,cAAc,gBAAgB;AAClC,QAAI,cAAc,gBAAgB;AAElC,QAAI,gBAAgB,WAAW;AAE7B,WAAK,sBAAsB,QAAQ,SAAS;AAC5C,WAAK,cAAc,yBAAyB,WAAW;AAAA,QACrD,SAAS;AAAA,QACT,QAAQ;AAAA,MACV,CAAC;AAID,UAAI,kBAAkB;AACtB,YAAMG,gBAAe,KAAK,gBAAgB;AAC1C,YAAM,oBAAoB,CAAC,UAAwB;AACjD,YAAI,MAAM,WAAWA,cAAc;AAKnC,YACE,MAAM,MAAM,SAAS,mBACrB,MAAM,WAAW,OAAO,eACxB;AACA,4BAAkB;AAClB,kBAAQ;AAAA,QACV;AAAA,MACF;AACA,aAAO,iBAAiB,WAAW,iBAAiB;AAGpD,YAAM,cAAc;AACpB,YAAM,iBAAiB;AACvB,UAAI,aAAa;AAEjB,eAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,YAAI,gBAAiB;AAErB,YAAI;AACF,gBAAM,iBAAiB,MAAM;AAAA,YAC3B,GAAG,KAAK,OAAO,WAAW,sBAAsB,gBAAgB,QAAQ;AAAA,YACxE;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,GAAG,KAAK,iBAAiB,SAAS;AAAA,gBAClC,GAAI,KAAK,OAAO,WAAW,EAAE,eAAe,KAAK,OAAO,SAAS,IAAI,CAAC;AAAA,cACxE;AAAA,YACF;AAAA,UACF;AAEA,cAAI,eAAe,IAAI;AACrB,kBAAM,eAAe,MAAM,eAAe,KAAK;AAC/C,0BAAc,aAAa;AAC3B,0BAAc,aAAa;AAG3B,gBAAI,gBAAgB,YAAY;AAC9B,mBAAK,sBAAsB,QAAQ,aAAa,WAAW;AAC3D,2BAAa;AAAA,YACf;AAIA,kBAAMC,WAAU,QAAQ,WAAW;AACnC,kBAAMC,mBAA4C;AAAA,cAChD,SAAS,CAAC,WAAW,gBAAgB,UAAU,WAAW;AAAA,cAC1D,cAAc,CAAC,gBAAgB,UAAU,WAAW;AAAA,cACpD,QAAQ,CAAC,UAAU,WAAW;AAAA,cAC9B,WAAW,CAAC,WAAW;AAAA,YACzB;AACA,kBAAM,aAAa,gBAAgB,YAAY,gBAAgB;AAC/D,kBAAM,YAAYA,iBAAgBD,QAAO,GAAG,SAAS,WAAW,KAAK;AACrE,gBAAI,cAAc,WAAW;AAC3B;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,WAAW;AAClB,kBAAQ,MAAM,iCAAiC,SAAS;AAAA,QAC1D;AAGA,cAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,cAAc,CAAC;AAAA,MACpE;AAEA,aAAO,oBAAoB,WAAW,iBAAiB;AAGvD,UAAI,iBAAiB;AACnB,gBAAQ;AACR,aAAK,cAAc,wBAAwB,WAAW;AAAA,UACpD,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,cAAc;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU,gBAAgB;AAAA,UAC1B,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,aAAa,gBAAgB;AAAA,UAC7B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAIA,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,kBAA4C;AAAA,MAChD,SAAS,CAAC,WAAW,gBAAgB,UAAU,WAAW;AAAA,MAC1D,cAAc,CAAC,gBAAgB,UAAU,WAAW;AAAA,MACpD,QAAQ,CAAC,UAAU,WAAW;AAAA,MAC9B,WAAW,CAAC,WAAW;AAAA,IACzB;AACA,UAAM,kBAAkB,gBAAgB,OAAO,GAAG,SAAS,WAAW,KAAK;AAC3E,UAAM,gBAAgB,kBAAkB,cAAc;AAItD,UAAM,eAAe,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACrF,SAAK,sBAAsB,QAAQ,eAAe,WAAW;AAG7D,UAAM;AAEN,QAAI,QAAQ,eAAe,CAAC,aAAa;AACvC,YAAM,OAAO,MAAM,KAAK,uBAAuB,gBAAgB,UAAU;AAAA,QACvE,WAAW,QAAQ;AAAA,QACnB,YAAY,QAAQ;AAAA,MACtB,GAAG,SAAS;AACZ,UAAI,MAAM;AACR,sBAAc;AACd,sBAAc;AAAA,MAChB,OAAO;AACL,sBAAc;AACd,aAAK,cAAc,wBAAwB,WAAW;AAAA,UACpD,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,cAAc;AAAA,QAChB,CAAC;AACD,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU,gBAAgB;AAAA,UAC1B,QAAQ;AAAA,UACR,iBAAiB;AAAA,UACjB,aAAa,gBAAgB;AAAA,UAC7B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,cAAc,2BAA2B,WAAW;AAAA,MACvD,SAAS,kBAAkB,YAAY;AAAA,MACvC,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,oBAAoB,WAAW;AAAA,MAChD,SAAS,kBAAkB,YAAY;AAAA,MACvC,QAAQ;AAAA,MACR;AAAA,IACF,CAAC;AAED,WAAO;AAAA,MACL,SAAS;AAAA,MACT,UAAU,gBAAgB;AAAA,MAC1B,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,aAAa,gBAAgB;AAAA,MAC7B,OAAO,gBAAgB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BA,MAAM,gBAAgB,SAAiE;AACrF,UAAM,YAAY,KAAK,yBAAyB,gBAAgB;AAAA,MAC9D,aAAa,QAAQ,SAAS,UAAU;AAAA,MACxC,cAAc,KAAK,0BAA0B,OAAO;AAAA,IACtD,CAAC;AACD,QAAI,oBAAoB,MAAM,OAAO;AACnC,WAAK,cAAc,mBAAmB,WAAW;AAAA,QAC/C,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,QACd,OACE;AAAA,MACJ;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,gBAAgB;AAC3B,WAAK,cAAc,mBAAmB,WAAW;AAAA,QAC/C,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ,SAAS,QAAQ;AAC5B,WAAK,cAAc,mBAAmB,WAAW;AAAA,QAC/C,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,cAAc,wBAAwB,WAAW;AAAA,QACpD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,QACd,OACE;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,mBAAmB,QAAQ,QAAQ,IAAI,CAAC,WAAW,KAAK,uBAAuB,MAAM,CAAC;AAK5F,UAAM,oBAAoB,MAAM,KAAK,iBAAiB;AACtD,QAAI,CAAC,kBAAkB,IAAI;AACzB,WAAK,cAAc,wBAAwB,WAAW;AAAA,QACpD,SAAS;AAAA,QACT,WAAW,kBAAkB,QAAQ;AAAA,QACrC,cAAc,kBAAkB;AAAA,MAClC,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,cAAc,kBAAkB;AAMpC,UAAM,oBAAoB,QAAQ,QAAQ,IAAI,CAAC,YAAY;AAAA,MACzD,aAAa,OAAO;AAAA,MACpB,OAAO,cAAc,OAAO,KAAK;AAAA,MACjC,eAAe,OAAO,eAAe,IAAI,CAAC,OAAO;AAAA,QAC/C,OAAO,EAAE;AAAA,QACT,QAAQ,EAAE,OAAO,SAAS;AAAA,MAC5B,EAAE;AAAA,MACF,cAAc,OAAO;AAAA,MACrB,eAAe,OAAO;AAAA,MACtB,eAAe,OAAO;AAAA,IACxB,EAAE;AAEF,UAAM,cAAc;AAAA,MAClB,GAAI,QAAQ,kBAAkB,EAAE,gBAAgB,QAAQ,eAAe;AAAA,MACvE,SAAS;AAAA,MACT,MAAM,EAAE,YAAY;AAAA,MACpB,GAAI,KAAK,OAAO,YAAY,EAAE,UAAU,KAAK,OAAO,SAAS;AAAA,IAC/D;AAQA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe;AACxC,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,aAAa,GAAG,SAAS,gBAAgB,OAAO,SAAS,CAAC;AAChE,UAAM,wBAAwB,KAAK,0BAA0B,OAAO;AACpE,UAAM,EAAE,QAAQ,QAAQ,SAAS,OAAO,IAAI,KAAK,kBAAkB,YAAY;AAAA,MAC7E,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT,aAAa,QAAQ,QAAQ;AAAA,MAC7B,YAAY,EAAE,cAAc,sBAAsB;AAAA,IACpD,CAAC;AAED,UAAM,eAAe,KAAK,gBAAgB;AAK1C,QAAI,mBAA8C;AAClD,SAAK,cAAc,yBAAyB,WAAW;AAAA,MACrD,SAAS;AAAA,MACT,aAAa,QAAQ,QAAQ;AAAA,MAC7B,cAAc,kBAAkB,IAAI,CAAC,WAAW,OAAO,WAAW;AAAA,IACpE,CAAC;AACD,UAAM,iBAAiB,KAAK,wBAAwB,aAAa,kBAAkB,SAAS,EAAE,KAAK,CAAC,MAAM;AACxG,yBAAmB;AACnB,UAAI,EAAE,SAAS;AACb,aAAK,cAAc,2BAA2B,WAAW;AAAA,UACvD,SAAS;AAAA,UACT,aAAa,EAAE,KAAK,QAAQ;AAAA,UAC5B,cAAc,kBAAkB,IAAI,CAAC,WAAW,OAAO,WAAW;AAAA,QACpE,CAAC;AAAA,MACH,OAAO;AACL,aAAK,cAAc,wBAAwB,WAAW;AAAA,UACpD,SAAS;AAAA,UACT,cAAc,EAAE;AAAA,UAChB,aAAa,QAAQ,QAAQ;AAAA,QAC/B,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC;AAGD,UAAM,eAAe,MAAM,KAAK,2BAA2B,QAAQ,QAAQ,SAAS;AAAA,MAClF,cAAc;AAAA,MACd;AAAA,IACF,CAAC;AAGD,QAAI,CAAC,aAAa,OAAO;AACvB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS,CAAC;AAAA,QACV,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AACA,UAAM,eAAe,aAAa;AAClC,SAAK,cAAc,gBAAgB,WAAW,EAAE,SAAS,UAAU,CAAC;AAGpE,QAAI;AAGJ,UAAM,4BAA4B,OAChC,kBACG;AACH,YAAM,gBAAgB,cAAc;AACpC,YAAM,iBAA4D,eAAe,IAAI,CAAC,OAAO;AAAA,QAC3F,OAAO,EAAE;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,EAAE,SAAS,EAAE,OAAO,MAAM,iBAAiB;AAAA,MACpD,EAAE,KAAK,CAAC;AAER,WAAK,iBAAiB,QAAQ,cAAc,KAAK;AACjD,YAAM,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACtE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,SAAS;AAAA,QACT,cAAc;AAAA,QACd,cAAc,eAAe;AAAA,QAC7B,OAAO,cAAc;AAAA,MACvB;AAAA,IACF;AAGA,QAAI;AAEJ,QAAI,kBAAkB;AAEpB,YAAM,gBAAgB;AACtB,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO,0BAA0B,aAAa;AAAA,MAChD;AACA,wBAAkB,cAAc;AAChC,YAAM,yBAA4C;AAAA,QAChD;AAAA,QACA,iBAAiB,cAAc;AAAA,MACjC;AACA,4BAAsB;AAAA,QACpB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,cAAc,gBAAgB;AAAA,QAC9B,oBAAoB,gBAAgB;AAAA,QACpC,WAAW,gBAAgB;AAAA,QAC3B,SAAS,gBAAgB;AAAA,QACzB,gBAAgB,gBAAgB;AAAA,QAChC,QAAQ,gBAAgB;AAAA,QACxB,WAAW,gBAAgB;AAAA,QAC3B,MAAM,cAAc;AAAA,QACpB,MAAM;AAAA,QACN,WAAW,KAAK,iBAAiB,SAAS;AAAA,MAC5C;AACA,mBAAa,SAAS,mBAAmB;AAAA,IAC3C,OAAO;AAEL,4BAAsB;AAAA,QACpB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,cAAc,kBAAkB,IAAI,CAAC,QAAQ,SAAS;AAAA,UACpD,OAAO;AAAA,UACP,aAAa,OAAO;AAAA,UACpB,OAAO,KAAK,UAAU,OAAO,KAAK;AAAA;AAAA,QAEpC,EAAE;AAAA,QACF,gBAAgB,QAAQ;AAAA,QACxB,WAAW,KAAK,iBAAiB,SAAS;AAAA,MAC5C;AACA,mBAAa,SAAS,mBAAmB;AAGzC,YAAM,gBAAgB,MAAM;AAC5B,UAAI,CAAC,cAAc,SAAS;AAC1B,eAAO,0BAA0B,aAAa;AAAA,MAChD;AACA,wBAAkB,cAAc;AAChC,YAAM,yBAA4C;AAAA,QAChD;AAAA,QACA,iBAAiB,cAAc;AAAA,MACjC;AAGA,4BAAsB;AAAA,QACpB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,cAAc,gBAAgB;AAAA,QAC9B,oBAAoB,gBAAgB;AAAA,QACpC,WAAW,gBAAgB;AAAA,QAC3B,SAAS,gBAAgB;AAAA,QACzB,gBAAgB,gBAAgB;AAAA,QAChC,QAAQ,gBAAgB;AAAA,QACxB,WAAW,gBAAgB;AAAA,QAC3B,MAAM,cAAc;AAAA,QACpB,MAAM;AAAA,QACN,WAAW,KAAK,iBAAiB,SAAS;AAAA,MAC5C;AAGA,aAAO,eAAe;AAAA,QACpB,EAAE,MAAM,gBAAgB,GAAG,qBAAqB,cAAc,MAAM,aAAa;AAAA,QACjF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,qBAAqB,CAAC,UAAwB;AAClD,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,qBAAqB,cAAc,MAAM,aAAa;AAAA,UACjF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,kBAAkB;AAGrD,UAAM,cAAc,MAAM,IAAI,QAA+B,CAAC,YAAY;AACxE,YAAM,gBAAgB,OAAO,UAAwB;AACnD,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,UAAU,MAAM;AAE5B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,eAAK,cAAc,oBAAoB,WAAW;AAAA,YACjD,SAAS;AAAA,YACT,WAAW;AAAA,YACX,cAAc;AAAA,UACf,CAAC;AACD,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT,SAAS,CAAC;AAAA,YACV,cAAc;AAAA,YACd,cAAc;AAAA,UACf,CAAC;AACD;AAAA,QACD;AAGM,YAAI,SAAS,SAAS,yBAAyB;AAC7C,cAAI;AAIF,kBAAM,uBAAuB,MAAM,KAAK,iBAAiB;AACzD,kBAAM,eAAe,qBAAqB,KACtC,qBAAqB,cACrB;AACJ,kBAAM,gBAAgB,MAAM,KAAK;AAAA,cAC/B,EAAE,GAAG,aAAa,MAAM,EAAE,aAAa,aAAa,EAAE;AAAA,cACtD;AAAA,cACA;AAAA,YACF;AAEA,gBAAI,cAAc,SAAS;AACzB,oBAAM,YAAY,cAAc;AAChC,oBAAM,gBAAmC;AAAA,gBACvC,aAAa;AAAA,gBACb,iBAAiB,cAAc;AAAA,cACjC;AAEA,gCAAkB;AAClB,4BAAc;AACd,0BAAY,OAAO,EAAE,aAAa,aAAa;AAE/C,oCAAsB;AAAA,gBACpB,GAAG;AAAA,gBACH,cAAc,UAAU;AAAA,gBACxB,oBAAoB,UAAU;AAAA,gBAC9B,WAAW,UAAU;AAAA,gBACrB,SAAS,UAAU;AAAA,gBACnB,WAAW,UAAU;AAAA,gBACrB,MAAM;AAAA,cACR;AACA,qBAAO,eAAe,YAAY;AAAA,gBAChC,MAAM;AAAA,gBACN,cAAc,UAAU;AAAA,gBACxB,WAAW,UAAU;AAAA,gBACrB,SAAS,UAAU;AAAA,gBACnB,WAAW,UAAU;AAAA,gBACrB,MAAM;AAAA,cACR,GAAG,YAAY;AAAA,YACjB,OAAO;AACL,qBAAO,eAAe,YAAY;AAAA,gBAChC,MAAM;AAAA,gBACN,OAAO;AAAA,cACT,GAAG,YAAY;AAAA,YACjB;AAAA,UACF,QAAQ;AACN,mBAAO,eAAe,YAAY;AAAA,cAChC,MAAM;AAAA,cACN,OAAO;AAAA,YACT,GAAG,YAAY;AAAA,UACjB;AACA;AAAA,QACF;AAGA,YAAI,SAAS,SAAS,0BAA0B;AAC9C,iBAAO,oBAAoB,WAAW,aAAa;AAEnD,cAAI,QAAQ,WAAW,QAAQ,MAAM,cAAc;AACjD,kBAAM,aAOD,QAAQ,KAAK;AAElB,kBAAM,UAAmC,WAAW,IAAI,CAAC,OAAO;AAAA,cAC9D,OAAO,EAAE;AAAA,cACT,SAAS,EAAE,WAAW,EAAE,WAAW;AAAA,cACnC,UAAU,EAAE,YAAY,EAAE,eAAe;AAAA,cACzC,QAAQ,EAAE,WAAW,WAAW,WAAW;AAAA,cAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,SAAS,EAAE,MAAM,IAAI;AAAA,YAClE,EAAE;AAMF,kBAAM,mBAA4C,gBAAgB,iBAAiB,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,cACjG,OAAO,EAAE;AAAA,cACT,SAAS;AAAA,cACT,UAAU;AAAA,cACV,QAAQ;AAAA,cACR,OAAO,EAAE,MAAM,kBAAkB,SAAS,EAAE,MAAM;AAAA,YACpD,EAAE;AACF,kBAAM,aAAa,CAAC,GAAG,SAAS,GAAG,eAAe,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAEpF,kBAAM,eAAe,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAEzD,kBAAM,KAAK,8BAA8B,cAAc,QAAQ,OAAO;AACtE,iBAAK,cAAc,wBAAwB,WAAW;AAAA,cACpD,SAAS;AAAA,cACT,aAAa,WAAW;AAAA,YAC1B,CAAC;AAED,oBAAQ;AAAA,cACN,SAAS,iBAAiB,WAAW;AAAA,cACrC,SAAS;AAAA,cACT;AAAA,cACA,cAAc,WAAW,SAAS;AAAA,YACpC,CAAC;AAAA,UACH,OAAO;AAEL,oBAAQ;AACR,iBAAK,cAAc,qBAAqB,WAAW;AAAA,cACjD,SAAS;AAAA,cACT,WAAW;AAAA,cACX,cAAc;AAAA,YAChB,CAAC;AACD,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,SAAS,CAAC;AAAA,cACV,cAAc;AAAA,cACd,cAAc;AAAA,YAChB,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,SAAS,SAAS,iBAAiB;AACrC,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,eAAK,cAAc,oBAAoB,WAAW;AAAA,YAChD,SAAS;AAAA,YACT,WAAW;AAAA,YACX,cAAc;AAAA,UAChB,CAAC;AACD,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,SAAS,CAAC;AAAA,YACV,cAAc;AAAA,YACd,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAED,WAAO,oBAAoB,WAAW,kBAAkB;AAExD,SAAK,cAAc,mBAAmB,WAAW;AAAA,MAC/C,SAAS,YAAY,UAAU,YAAY;AAAA,MAC3C,aAAa,YAAY,QAAQ;AAAA,MACjC,YAAY;AAAA,QACV,cAAc,YAAY;AAAA,QAC1B,cAAc,YAAY;AAAA,MAC5B;AAAA,MACA,GAAI,YAAY,QAAQ,EAAE,cAAc,YAAY,MAAM,IAAI,CAAC;AAAA,IACjE,CAAC;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,sBACN,QACA,QACA,iBACM;AACN,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,eAAe;AAAA,MACpB;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBQ,6BACN,WACA,QACA,QACA,SACwB;AACxB,UAAM,eAAe,KAAK,gBAAgB;AAE1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,UAAU,MAAM;AACtB,cAAM,UAAU,SAAS;AAE/B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,iBAAiB,SAAS,uBAAuB;AAAA,UACjE,CAAC;AACD;AAAA,QACD;AAEM,YAAI,SAAS,SAAS,4BAA4B,SAAS,cAAc,WAAW;AAClF,iBAAO,oBAAoB,WAAW,aAAa;AAEnD,cAAI,QAAQ,WAAW,QAAQ,WAAW;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,WAAW,QAAQ;AAAA,cACnB,SAAS,QAAQ;AAAA;AAAA,YACnB,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF,WACE,SAAS,SAAS,mBAClB,MAAM,WAAW,OAAO,eACxB;AAIA,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,UAAU;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBQ,uBACN,QACA,QACA,SACkD;AAClD,UAAM,eAAe,KAAK,gBAAgB;AAE1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,UAAU,MAAM;AACtB,cAAM,UAAU,SAAS;AAE/B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,iBAAiB,SAAS,uBAAuB;AAAA,UACjE,CAAC;AACD;AAAA,QACD;AAEM,YAAI,SAAS,SAAS,0BAA0B;AAC9C,iBAAO,oBAAoB,WAAW,aAAa;AAGnD,cAAI,QAAQ,WAAW,SAAS,UAAU;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,UAAU,QAAQ;AAAA,YACpB,CAA+D;AAAA,UACjE,WAAW,QAAQ,WAAW,SAAS,WAAW;AAEhD,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,WAAW,QAAQ;AAAA,cACnB,SAAS,QAAQ;AAAA,cACjB,YAAY,QAAQ;AAAA,YACtB,CAAC;AAAA,UACH,OAAO;AAML,oBAAQ;AACR,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF,WACE,SAAS,SAAS,mBAClB,MAAM,WAAW,OAAO,eACxB;AAIA,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBQ,0BACN,QACA,QACA,SACA,cACA,WAakD;AAClD,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,OAAO,UAAwB;AACnD,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,UAAU,MAAM;AAE5B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,iBAAiB,SAAS,uBAAuB;AAAA,UACjE,CAAC;AACD;AAAA,QACD;AAGM,YAAI,SAAS,SAAS,yBAAyB;AAC7C,gBAAM,gBAAgB,MAAM,UAAU;AAEtC,cAAI,eAAe;AAEjB,mBAAO,eAAe,YAAY;AAAA,cAChC,MAAM;AAAA,cACN,GAAG;AAAA,YACL,GAAG,YAAY;AAAA,UACjB,OAAO;AAEL,mBAAO,eAAe,YAAY;AAAA,cAChC,MAAM;AAAA,cACN,OAAO;AAAA,YACT,GAAG,YAAY;AAAA,UACjB;AACA;AAAA,QACF;AAEA,cAAM,UAAU,SAAS;AAOzB,YAAI,SAAS,SAAS,0BAA0B;AAC9C,iBAAO,oBAAoB,WAAW,aAAa;AAGnD,cAAI,QAAQ,WAAW,SAAS,UAAU;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,UAAU,QAAQ;AAAA,YACpB,CAA+D;AAAA,UACjE,WAAW,QAAQ,WAAW,SAAS,WAAW;AAEhD,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,WAAW,QAAQ;AAAA,cACnB,SAAS,QAAQ;AAAA,cACjB,YAAY,QAAQ;AAAA,YACtB,CAAC;AAAA,UACH,OAAO;AAML,oBAAQ;AACR,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF,WACE,SAAS,SAAS,mBAClB,MAAM,WAAW,OAAO,eACxB;AAIA,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBQ,mBACN,QACA,SACe;AACf,UAAM,eAAe,KAAK,gBAAgB;AAE1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AAEnC,YAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,QACV;AAAA,MACF;AAGA,YAAM,cAAc,MAAM;AACxB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAC/C,gBAAQ;AACR,gBAAQ;AAAA,MACV;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,8BACZ,cACA,QACA,SACe;AACf,QAAI,cAAc;AAChB,cAAQ;AACR;AAAA,IACF;AACA,UAAM,KAAK,mBAAmB,QAAQ,OAAO;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,2BACN,QACA,SAC6B;AAC7B,UAAM,eAAe,KAAK,gBAAgB;AAE1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,OAAO,MAAM;AACjB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AAEA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,MAAM,SAAS,yBAAyB;AAChD,eAAK;AACL,kBAAQ,OAAO;AAAA,QACjB,WAAW,MAAM,MAAM,SAAS,iBAAiB;AAC/C,eAAK;AACL,kBAAQ;AACR,kBAAQ,QAAQ;AAAA,QAClB;AAAA,MACF;AAGA,YAAM,cAAc,MAAM;AACxB,aAAK;AACL,gBAAQ;AACR,gBAAQ,QAAQ;AAAA,MAClB;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeQ,iBAAiB,KAAmB;AAC1C,QAAI;AACF,YAAM,SAAS,IAAI,IAAI,GAAG,EAAE;AAC5B,UAAI,SAAS,cAAc,gCAAgC,MAAM,IAAI,EAAG;AACxE,YAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,WAAK,MAAM;AACX,WAAK,OAAO;AACZ,WAAK,cAAc;AACnB,eAAS,KAAK,YAAY,IAAI;AAAA,IAChC,QAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsCA,MAAM,UAA4B;AAChC,QAAI,OAAO,aAAa,YAAa,QAAO;AAG5C,QAAI,KAAK,aAAc,QAAO,KAAK,aAAa;AAMhD,UAAM,aAAa,IAAI,gBAAgB,EAAE,cAAc,OAAO,SAAS,OAAO,CAAC;AAC/E,UAAM,UAAU,GAAG,KAAK,aAAa,CAAC,gBAAgB,WAAW,SAAS,CAAC;AAM3E,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,aAAa,eAAe,MAAM;AACzC,WAAO,aAAa,YAAY,IAAI;AACpC,WAAO,QAAQ;AAIf,WAAO,MAAM,UACX;AAMF,UAAM,QAAQ,IAAI,QAAiB,CAAC,YAAY;AAC9C,UAAI,UAAU;AACd,YAAM,SAAS,CAAC,UAAmB;AACjC,YAAI,QAAS;AACb,kBAAU;AACV,qBAAa,KAAK;AAClB,gBAAQ,KAAK;AAAA,MACf;AACA,aAAO,SAAS,MAAM,OAAO,IAAI;AACjC,aAAO,UAAU,MAAM,OAAO,KAAK;AAEnC,YAAM,QAAQ,WAAW,MAAM,OAAO,KAAK,GAAG,GAAK;AAAA,IACrD,CAAC;AACD,WAAO,MAAM;AACb,aAAS,KAAK,YAAY,MAAM;AAEhC,SAAK,eAAe,EAAE,QAAQ,MAAM;AACpC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,iBAAuB;AACrB,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,MAAO;AACZ,SAAK,eAAe;AACpB,UAAM,OAAO,OAAO;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBQ,2BACN,QACA,QACA,SACA,UAA2D,CAAC,GAI5D;AACA,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,UAAU;AAEd,YAAM,WAAW,MAAM;AACrB,YAAI,QAAS;AACb,kBAAU;AACV,qBAAa,YAAY;AACzB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AAEA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,gBAAM,eAAe,QAAQ,iBAAiB;AAC9C,mBAAS;AACT,kBAAQ;AAAA,YACN,OAAO;AAAA,YACP;AAAA,YACA,UAAU,CAAC,gBAAyC;AAClD,kBAAI,aAAc,QAAO,MAAM,EAAE,eAAe,KAAK,CAAC;AACtD,qBAAO,eAAe;AAAA,gBACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,MAAM,aAAa;AAAA,gBACzE;AAAA,cACF;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH,WACE,MAAM,MAAM,SAAS,mBACrB,MAAM,WAAW,OAAO,eACxB;AAOA,mBAAS;AACT,kBAAQ;AACR,kBAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,cAAc,MAAM;AACxB,iBAAS;AACT,gBAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,MAC1B;AAEA,YAAM,eAAe,WAAW,MAAM;AACpC,iBAAS;AACT,gBAAQ;AACR,gBAAQ,EAAE,OAAO,MAAM,CAAC;AAAA,MAC1B,GAAG,GAAK;AAER,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAc,wBACZ,aACA,WAIA;AACA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,uBAAuB;AAAA,QAC5E,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,KAAK,iBAAiB,SAAS,EAAE;AAAA,QACnF,MAAM,KAAK,UAAU,EAAE,GAAG,aAAa,WAAW,QAAQ,CAAC;AAAA,MAC7D,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,UAAU,SAAS;AAAA,YAC5B,SAAU,UAAU,WAAW,UAAU,mBAAmB;AAAA,UAC9D;AAAA,QACF;AAAA,MACF;AACA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,KAAK,2BAA2B,QAAW;AAC7C,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO,EAAE,MAAM,kBAAkB,SAAS,oDAAoD;AAAA,QAChG;AAAA,MACF;AACA,aAAO,EAAE,SAAS,MAAM,wBAAwB,KAAK,uBAAuB;AAAA,IAC9E,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,aACA,WAIA;AACA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,uBAAuB;AAAA,QAC5E,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,KAAK,iBAAiB,SAAS,EAAE;AAAA,QACnF,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,cAAM,eAAe,UAAU,SAAS;AAExC,YAAI,aAAa,SAAS,gBAAgB,GAAG;AAC3C,uBAAa,WAAW,YAAY;AAAA,QACtC;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM,aAAa,SAAS,gBAAgB,IAAI,mBAAmB;AAAA,YACnE,SAAS;AAAA,YACT,SAAS;AAAA,cACP,UAAU,YACP,UAAU,oBAAoB,SAC3B,YACA,EAAE,iBAAiB,UAAU,gBAAgB;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,QAAQ,IAAI,eAAe;AACjD,aAAO,EAAE,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK,GAAG,KAAK;AAAA,IAC5D,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAc,wBACZ,aACA,kBACA,WAIA;AACA,UAAM,oBAAoB,iBAAiB;AAAA,MAAI,CAAC,SAC9C,SAAS,aAAa,gBAAyB;AAAA,IACjD;AACA,UAAM,cAAc,MAAM,KAAK;AAAA,MAC7B,EAAE,GAAG,aAAa,WAAW,SAAS,cAAc,kBAAkB;AAAA,MACtE;AAAA,IACF;AACA,QAAI,CAAC,YAAY,QAAS,QAAO;AAEjC,UAAM,qBAAqB,YAAY,KAAK,iBAAiB,CAAC;AAC9D,UAAM,yBAAyB,IAAI;AAAA,MACjC,OAAO,KAAK,YAAY,KAAK,uBAAuB,EAAE,IAAI,MAAM;AAAA,IAClE;AACA,QAAI,uBAAuB,SAAS,GAAG;AACrC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,QACP,eAAe;AAAA,MACjB;AAAA,IACF;AAIA,UAAM,eAAgB,YAAY,QAC/B,QAAQ,CAAC,QAAQ,UAAU,uBAAuB,IAAI,KAAK,IACxD,CAAC,EAAE,GAAG,QAAQ,eAAe,MAAM,CAAC,IACpC,CAAC,CAAC;AAER,UAAM,gBAAwC,CAAC;AAC/C,UAAM,oBAAoB,CAAC,GAAG,iBAAiB;AAC/C,UAAM,mBAAmB,OAAO,KAAK,YAAY,KAAK,uBAAuB,EAC1E,IAAI,MAAM,EACV,OAAO,CAAC,UAAU,iBAAiB,KAAK,MAAM,UAAU;AAC3D,UAAM,eAAe,MAAM,QAAQ;AAAA,MACjC,iBAAiB,IAAI,OAAO,WAAW;AAAA,QACrC;AAAA,QACA,OAAO,MAAM,KAAK,YAAa;AAAA,UAC7B,KAAK,UAAU,YAAY,KAAK,wBAAwB,OAAO,KAAK,CAAC,CAAC;AAAA,QACxE;AAAA,MACF,EAAE;AAAA,IACJ;AACA,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,SAAS,aAAa,CAAC;AAC7B,YAAM,QAAQ,iBAAiB,CAAC;AAChC,UAAI,OAAO,WAAW,aAAa;AACjC,sBAAc,OAAO,KAAK,CAAC,IAAI,OAAO,MAAM;AAAA,MAC9C,WAAW,iBAAiB,KAAK,MAAM,aAAa;AAClD,0BAAkB,KAAK,IAAI;AAAA,MAC7B,OAAO;AACL,eAAO,EAAE,SAAS,OAAO,OAAO,sDAAsD,KAAK,GAAG;AAAA,MAChG;AAAA,IACF;AAEA,UAAM,WAAW,CAAC,iBAChB,KAAK,mBAAmB;AAAA,MACtB,GAAG;AAAA,MACH,SAAS;AAAA,MACT,WAAW;AAAA,MACX;AAAA,MACA,sBAAsB;AAAA,IACxB,GAAG,SAAS;AACd,QAAI,cAAc,MAAM,SAAS,iBAAiB;AAClD,UAAM,6BAA6B,YAAY,WAC1C,YAAY,KAAK,iBAAiB,CAAC,GAAG,IAAI,CAAC,YAAY,QAAQ,KAAK,KACpE,YAAY,iBAAiB,CAAC,GAAG,IAAI,CAAC,YAAY,QAAQ,KAAK;AACpE,UAAM,2BAA2B,2BAA2B;AAAA,MAC1D,CAAC,UAAU,iBAAiB,KAAK,MAAM,eAAe,kBAAkB,KAAK,MAAM;AAAA,IACrF;AACA,QAAI,yBAAyB,SAAS,GAAG;AACvC,iBAAW,SAAS,0BAA0B;AAC5C,0BAAkB,KAAK,IAAI;AAC3B,eAAO,cAAc,OAAO,KAAK,CAAC;AAAA,MACpC;AACA,oBAAc,MAAM,SAAS,iBAAiB;AAAA,IAChD;AACA,QAAI,CAAC,YAAY,QAAS,QAAO;AACjC,QAAI,mBAAmB,SAAS,GAAG;AACjC,YAAM,qBAAqB,IAAI;AAAA,QAC7B,mBAAmB,IAAI,CAAC,YAAY,QAAQ,KAAK;AAAA,MACnD;AACA,oBAAc;AAAA,QACZ,GAAG;AAAA,QACH,MAAM;AAAA,UACJ,GAAG,YAAY;AAAA,UACf,eAAe;AAAA,YACb,GAAG;AAAA,YACH,IAAI,YAAY,KAAK,iBAAiB,CAAC,GAAG;AAAA,cACxC,CAAC,YAAY,CAAC,mBAAmB,IAAI,QAAQ,KAAK;AAAA,YACpD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,2BAA2B,YAAY,KAAK,QAAQ;AAAA,MACxD,CAAC,WAAW,kBAAkB,OAAO,KAAK,MAAM;AAAA,IAClD;AACA,UAAM,wBAAwB,MAAM,QAAQ;AAAA,MAC1C,yBAAyB,IAAI,OAAO,YAAY;AAAA,QAC9C,OAAO,OAAO;AAAA,QACd,OAAO,MAAM,KAAK,YAAa,kBAAkB,OAAO,QAAQ;AAAA,MAClE,EAAE;AAAA,IACJ;AACA,UAAM,yBAAiD,CAAC;AACxD,aAAS,IAAI,GAAG,IAAI,sBAAsB,QAAQ,KAAK;AACrD,YAAM,SAAS,sBAAsB,CAAC;AACtC,YAAM,QAAQ,yBAAyB,CAAC,EAAE;AAC1C,UAAI,OAAO,WAAW,aAAa;AACjC,+BAAuB,OAAO,KAAK,CAAC,IAAI,OAAO,MAAM;AAAA,MACvD,OAAO;AACL,eAAO,EAAE,SAAS,OAAO,OAAO,uDAAuD,KAAK,GAAG;AAAA,MACjG;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,iBAAiB,YAAY,KAAK,QAAQ;AAAA,QAAI,CAAC,WAC7C,kBAAkB,OAAO,KAAK,MAAM,aAAa,uBAAuB,OAAO,OAAO,KAAK,CAAC,KAAK,KAAK;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,kBACZ,aACA,WAIA;AACA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,6BAA6B;AAAA,QAClF,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,KAAK,iBAAiB,SAAS,EAAE;AAAA,QACnF,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AACD,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,eAAO,EAAE,SAAS,OAAO,OAAO,UAAU,SAAS,6CAA6C,eAAe,UAAU,cAAc;AAAA,MACzI;AACA,aAAO,EAAE,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK,GAAG,MAAM,SAAS,QAAQ,IAAI,eAAe,EAAE;AAAA,IACnG,QAAQ;AACN,aAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,IAClD;AAAA,EACF;AAAA,EAEA,MAAc,mBACZ,aACA,WAIA;AACA,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,6BAA6B;AAAA,QAClF,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,oBAAoB,GAAG,KAAK,iBAAiB,SAAS,EAAE;AAAA,QACnF,MAAM,KAAK,UAAU,WAAW;AAAA,MAClC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,cAAM,eAAe,UAAU,SAAS;AAExC,YAAI,aAAa,SAAS,gBAAgB,GAAG;AAC3C,uBAAa,WAAW,YAAY;AAAA,QACtC;AAEA,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,UACP,eAAe,UAAU;AAAA,QAC3B;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,QAAQ,IAAI,eAAe;AACjD,aAAO,EAAE,SAAS,MAAM,MAAM,MAAM,SAAS,KAAK,GAAG,KAAK;AAAA,IAC5D,QAAQ;AACN,aAAO,EAAE,SAAS,OAAO,OAAO,gBAAgB;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,iBAAiB,QAA2B,OAAqB;AACvE,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,eAAe;AAAA,MACpB,EAAE,MAAM,yBAAyB,MAAM;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,UAA6C;AACjE,UAAM,YAAY,KAAK,yBAAyB,QAAQ;AACxD,SAAK,cAAc,yBAAyB,WAAW;AAAA,MACrD,SAAS;AAAA,MACT,YAAY,EAAE,mBAAmB,KAAK;AAAA,IACxC,CAAC;AACD,QAAI;AACF,YAAM,WAAW,MAAM;AAAA,QACrB,GAAG,KAAK,OAAO,WAAW,sBAAsB,QAAQ;AAAA,QACxD;AAAA,UACE,SAAS;AAAA,YACP,GAAG,KAAK,iBAAiB,SAAS;AAAA,YAClC,GAAI,KAAK,OAAO,WAAW,EAAE,eAAe,KAAK,OAAO,SAAS,IAAI,CAAC;AAAA,UACxE;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,aAAK,cAAc,iBAAiB,WAAW;AAAA,UAC7C,SAAS;AAAA,UACT,WAAW;AAAA,UACX,cAAc,UAAU,SAAS;AAAA,QACnC,CAAC;AACD,eAAO;AAAA,UACL,SAAS;AAAA,UACT;AAAA,UACA,QAAQ;AAAA,UACR,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS,UAAU,SAAS;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS,KAAK,WAAW,cAAc,YAAY;AAAA,QACnD,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,aAAO;AAAA,QACL,SAAS,KAAK,WAAW;AAAA,QACzB;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,iBAAiB,KAAK;AAAA,QACtB,aAAa,KAAK;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AACd,WAAK,cAAc,iBAAiB,WAAW;AAAA,QAC7C,SAAS;AAAA,QACT,GAAG,uBAAuB,KAAK;AAAA,MACjC,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,QAAQ;AAAA,QACR,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,iBACJ,SAC8B;AAC9B,UAAM,YAAY,KAAK,yBAAyB,WAAW;AAAA,MACzD,iBAAiB,CAAC,CAAC,SAAS;AAAA,IAC9B,CAAC;AACD,UAAM,cAAc,IAAI,gBAAgB;AACxC,QAAI,SAAS,MAAO,aAAY,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AAClE,QAAI,SAAS,OAAQ,aAAY,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AACrE,QAAI,SAAS,OAAQ,aAAY,IAAI,UAAU,QAAQ,MAAM;AAC7D,QAAI,SAAS,KAAM,aAAY,IAAI,QAAQ,QAAQ,IAAI;AACvD,QAAI,SAAS,GAAI,aAAY,IAAI,MAAM,QAAQ,EAAE;AAEjD,UAAM,MAAM,GAAG,KAAK,OAAO,WAAW,sBACpC,YAAY,SAAS,IAAI,IAAI,WAAW,KAAK,EAC/C;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC,SAAS;AAAA,QACP,GAAG,KAAK,iBAAiB,SAAS;AAAA,QAClC,GAAI,KAAK,OAAO,WAAW,EAAE,eAAe,KAAK,OAAO,SAAS,IAAI,CAAC;AAAA,MACxE;AAAA,MACA,aAAa;AAAA,IACf,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc,UAAU,SAAS;AAAA,MACnC,CAAC;AACD,YAAM,IAAI,MAAM,UAAU,SAAS,8BAA8B;AAAA,IACnE;AAEA,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,SAAK,cAAc,qBAAqB,WAAW;AAAA,MACjD,SAAS;AAAA,MACT,YAAY;AAAA,QACV,OAAO,OAAO;AAAA,QACd,UAAU,OAAO,SAAS,UAAU;AAAA,MACtC;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,kBAAkB,SAQtB;AAIA,UAAM,MAAM,KAAK,eAAe;AAAA,MAC9B,MAAM,KAAK,oBAAoB,OAAO;AAAA,MACtC,MAAM,KAAK,oBAAoB,OAAO;AAAA,IACxC;AACA,SAAK,iBAAiB,IAAI;AAAA,MACxB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,oBAAoB,SAQhC;AACA,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,eAAe,MAAM,KAAK,gBAAgB,SAAS,KAAK;AAC9D,QAAI,CAAC,aAAa,IAAI;AACpB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,EAAE,MAAM,iBAAiB,SAAS,yBAAyB;AAAA,MACpE;AAAA,IACF;AACA,UAAM,EAAE,QAAQ,OAAO,IAAI;AAM3B,UAAM,YACJ,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,aAC1D,OAAO,WAAW,IAClB,GAAG,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAE1D,UAAM,aAAa,MAAM;AACvB,UAAI,OAAO,KAAM,QAAO,MAAM;AAAA,IAChC;AAMA,UAAM,kBAAkB,KAAK;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,MAAM;AAAA,MACN,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,iBAAiB,QAAQ;AAAA,MACzB;AAAA,IACF;AACA,WAAO,eAAe;AAAA,MACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,KAAK;AAAA,MAC3D;AAAA,IACF;AAKA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,WAAW,OAAO,cAAe;AAC3C,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,KAAK;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAEhD,UAAM,SAAS,MAAM;AACrB,WAAO,oBAAoB,WAAW,aAAa;AACnD,eAAW;AACX,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,gBAAgB,OAG5B;AACA,QAAI,KAAK,gBAAgB;AACvB,YAAM,EAAE,QAAAE,SAAQ,QAAAC,QAAO,IAAI,KAAK;AAChC,UAAI,CAACD,QAAO,MAAM;AAEhB,QAAAA,QAAO,UAAU;AAAA,MACnB;AACA,aAAO,EAAE,IAAI,MAAM,QAAAA,SAAQ,QAAAC,QAAO;AAAA,IACpC;AAEA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIrD,4BAAwB,MAAM;AAC9B,UAAM,cAAc,KAAK,eAAe,KAAK;AAC7C,QAAI,aAAa;AACf,UAAI,gBAAgB,WAAW,EAAE,QAAQ,CAAC,OAAO,QAAQ;AACvD,eAAO,IAAI,KAAK,KAAK;AAAA,MACvB,CAAC;AAAA,IACH;AACA,UAAM,aAAa,GAAG,SAAS,oBAAoB,OAAO,SAAS,CAAC;AAEpE,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,KAAK,kBAAkB,YAAY;AAAA,MACrE,YAAY;AAAA,IACd,CAAC;AAED,UAAM,QAAQ,MAAM,KAAK,sBAAsB,MAAM;AACrD,QAAI,CAAC,OAAO;AAGV,cAAQ;AACR,aAAO,EAAE,IAAI,MAAM;AAAA,IACrB;AAEA,SAAK,iBAAiB,EAAE,QAAQ,OAAO;AACvC,WAAO,EAAE,IAAI,MAAM,QAAQ,OAAO;AAAA,EACpC;AAAA,EAEQ,sBAAsB,QAA6C;AACzE,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,YAAkD;AACtD,YAAM,UAAU,MAAM;AACpB,YAAI,cAAc,KAAM,cAAa,SAAS;AAC9C,eAAO,oBAAoB,WAAW,OAAO;AAAA,MAC/C;AACA,YAAM,UAAU,CAAC,UAAwB;AACvC,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,WAAW,OAAO,cAAe;AAC3C,YAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,kBAAQ;AACR,kBAAQ,IAAI;AAAA,QACd;AAAA,MACF;AACA,aAAO,iBAAiB,WAAW,OAAO;AAC1C,kBAAY,WAAW,MAAM;AAC3B,gBAAQ;AACR,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAK;AAAA,IACV,CAAC;AAAA,EACH;AAAA,EAEQ,mBACN,QACA,SACA,WACA,cAIA;AACA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAQ7C,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,WAAW,OAAO,cAAe;AAC3C,cAAM,UAAU,MAAM;AACtB,YACE,SAAS,SAAS,wBAClB,SAAS,SAAS,qBAClB;AACA,cAAI,QAAQ,cAAc,UAAW;AAAA,QACvC,OAAO;AACL;AAAA,QACF;AACA,eAAO,oBAAoB,WAAW,aAAa;AACnD,YAAI,QAAQ,SAAS,qBAAqB;AACxC,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO,EAAE,MAAM,iBAAiB,SAAS,yBAAyB;AAAA,UACpE,CAAC;AACD;AAAA,QACF;AACA,YAAI,QAAQ,SAAS;AACnB,kBAAQ,EAAE,SAAS,MAAM,QAAQ,QAAQ,MAAM,OAAO,CAAC;AAAA,QACzD,OAAO;AACL,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO,QAAQ,SAAS;AAAA,cACtB,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BA,MAAM,YAAY,SAAyD;AACzE,UAAM,YAAY,KAAK,yBAAyB,QAAQ;AAAA,MACtD,aAAa;AAAA,MACb,mBAAmB,CAAC,CAAC,QAAQ;AAAA,IAC/B,CAAC;AACD,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,aAAa,GAAG,SAAS,gBAAgB,OAAO,SAAS,CAAC;AAChE,UAAM,wBAAwB,KAAK,0BAA0B,OAAO;AAEpE,UAAM,EAAE,QAAQ,QAAQ,SAAS,OAAO,IAAI,KAAK,kBAAkB,YAAY;AAAA,MAC7E,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT,YAAY,EAAE,cAAc,sBAAsB;AAAA,IACpD,CAAC;AAED,UAAM,eAAe,MAAM,KAAK,2BAA2B,QAAQ,QAAQ,SAAS;AAAA,MAClF,cAAc;AAAA,MACd;AAAA,IACF,CAAC;AACD,QAAI,CAAC,aAAa,OAAO;AACvB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,MAAM;AAAA,MACN,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ,aAAa,QAAQ;AAAA,MACxC,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,MACrB,UAAU,QAAQ;AAAA,MAClB,WAAW,KAAK,iBAAiB,SAAS;AAAA,IAC5C;AACA,iBAAa,SAAS,WAAW;AACjC,UAAM,eAAe,aAAa;AAClC,SAAK,cAAc,gBAAgB,WAAW,EAAE,SAAS,UAAU,CAAC;AAKpE,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,MAAM,aAAa;AAAA,UACzE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAEhD,UAAM,gBAAgB,MAAM,KAAK,uBAAuB,QAAQ,QAAQ,OAAO;AAE/E,WAAO,oBAAoB,WAAW,aAAa;AACnD,YAAQ;AAER,QAAI,cAAc,SAAS;AACzB,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,YAAY,EAAE,aAAa,UAAU;AAAA,MACvC,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,cAAc;AAAA,QACzB,eAAe,QAAQ;AAAA,QACvB,YAAY,cAAc;AAAA,QAC1B,SAAS,cAAc;AAAA,MACzB;AAAA,IACF;AAEA,SAAK;AAAA,MACH,cAAc,OAAO,SAAS,kBAAkB,qBAAqB;AAAA,MACrE;AAAA,MACA;AAAA,QACE,SAAS,cAAc,OAAO,SAAS,kBAAkB,cAAc;AAAA,QACvE,GAAG,uBAAuB,cAAc,KAAK;AAAA,QAC7C,YAAY,EAAE,aAAa,UAAU;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2CA,MAAM,cAAc,SAA6D;AAC/E,UAAM,YAAY,KAAK,yBAAyB,QAAQ;AAAA,MACtD,aAAa;AAAA,MACb,aAAa,QAAQ;AAAA,MACrB,mBAAmB,CAAC,CAAC,QAAQ;AAAA,IAC/B,CAAC;AAGD,UAAM,aAAa,cAAc;AAAA,MAC/B,QAAQ,QAAQ;AAAA,MAChB,OAAO,QAAQ;AAAA,MACf,aAAa,QAAQ;AAAA,MACrB,SAAS,QAAQ;AAAA,IACnB,CAAmC;AAEnC,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,IAAI,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACrD,4BAAwB,MAAM;AAC9B,SAAK,sBAAsB,QAAQ,SAAS;AAC5C,UAAM,cAAc,KAAK,eAAe,SAAS,KAAK;AACtD,QAAI,aAAa;AACf,YAAM,cAAc,IAAI,gBAAgB,WAAW;AACnD,kBAAY,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,IAC5D;AACA,UAAM,aAAa,GAAG,SAAS,gBAAgB,OAAO,SAAS,CAAC;AAChE,UAAM,wBAAwB,KAAK,0BAA0B,OAAO;AAEpE,UAAM,EAAE,QAAQ,QAAQ,SAAS,OAAO,IAAI,KAAK,kBAAkB,YAAY;AAAA,MAC7E,QAAQ;AAAA,IACV,CAAC;AACD,SAAK,cAAc,iBAAiB,WAAW;AAAA,MAC7C,SAAS;AAAA,MACT,YAAY,EAAE,cAAc,sBAAsB;AAAA,IACpD,CAAC;AAED,UAAM,eAAe,MAAM,KAAK,2BAA2B,QAAQ,QAAQ,SAAS;AAAA,MAClF,cAAc;AAAA,MACd;AAAA,IACF,CAAC;AACD,QAAI,CAAC,aAAa,OAAO;AACvB,WAAK,cAAc,oBAAoB,WAAW;AAAA,QAChD,SAAS;AAAA,QACT,WAAW;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc;AAAA,MAClB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,WAAW;AAAA,QACT,QAAQ,QAAQ;AAAA,QAChB,OAAO,QAAQ;AAAA,QACf,aAAa,QAAQ;AAAA,QACrB,SAAS,QAAQ;AAAA,MACnB;AAAA,MACA,WAAW;AAAA,MACX,gBAAgB,QAAQ;AAAA,MACxB,aAAa,QAAQ;AAAA,MACrB,WAAW,KAAK,iBAAiB,SAAS;AAAA,IAC5C;AACA,iBAAa,SAAS,WAAW;AACjC,UAAM,eAAe,aAAa;AAClC,SAAK,cAAc,gBAAgB,WAAW,EAAE,SAAS,UAAU,CAAC;AAKpE,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,MAAM,aAAa;AAAA,UACzE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAEhD,UAAM,gBAAgB,MAAM,KAAK,uBAAuB,QAAQ,QAAQ,OAAO;AAE/E,WAAO,oBAAoB,WAAW,aAAa;AACnD,YAAQ;AAER,QAAI,cAAc,SAAS;AACzB,WAAK,cAAc,kBAAkB,WAAW;AAAA,QAC9C,SAAS;AAAA,QACT,YAAY,EAAE,aAAa,aAAa,aAAa,QAAQ,YAAY;AAAA,MAC3E,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,cAAc;AAAA,QACzB;AAAA,QACA,SAAS,cAAc;AAAA,MACzB;AAAA,IACF;AAEA,SAAK;AAAA,MACH,cAAc,OAAO,SAAS,kBAAkB,qBAAqB;AAAA,MACrE;AAAA,MACA;AAAA,QACE,SAAS,cAAc,OAAO,SAAS,kBAAkB,cAAc;AAAA,QACvE,GAAG,uBAAuB,cAAc,KAAK;AAAA,QAC7C,YAAY,EAAE,aAAa,aAAa,aAAa,QAAQ,YAAY;AAAA,MAC3E;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,cAAc;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,SAAwD;AAC1E,UAAM,UAAU,MAAM,KAAK,qBAAqB,SAAS,OAAO;AAGhE,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,aAAa,GAAG,SAAS,gBAAgB,QAAQ,SAAS;AAEhE,UAAM,QAAQ,KAAK,UAAU,UAAU;AACvC,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,qBAAqB,QAAQ,WAAW,KAAK;AAAA,EAC3D;AAAA,EAEA,MAAM,iBACJ,SACA,aACe;AACf,UAAM,mBAAmB,eAAe,KAAK,OAAO;AACpD,QAAI,CAAC,kBAAkB;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,aAAa,GAAG,SAAS,gBAAgB,QAAQ,SAAS,8BAA8B,mBAAmB,gBAAgB,CAAC;AAElI,WAAO,SAAS,OAAO;AAAA,EACzB;AAAA,EAEA,MAAM,cACJ,SACA,cACwB;AACxB,UAAM,UAAU,MAAM,KAAK,qBAAqB,SAAS,OAAO;AAEhE,UAAM,SAAS,KAAK,YAAY,QAAQ,WAAW,YAAY;AAE/D,WAAO,KAAK,qBAAqB,QAAQ,WAAW,QAAQ,YAAY;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,YACN,WACA,SACmB;AACnB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,MAAM,GAAG,SAAS,gBAAgB,SAAS;AAClD,WAAO,MAAM,QAAQ,QAAQ,SAAS;AACtC,WAAO,MAAM,SAAS,QAAQ,UAAU;AACxC,WAAO,MAAM,SAAS;AACtB,WAAO,MAAM,eAAe;AAC5B,WAAO,MAAM,YAAY;AACzB,WAAO,KAAK,iBAAiB,SAAS;AACtC,WAAO,QAAQ;AAEf,WAAO,SAAS,MAAM;AACpB,cAAQ,UAAU;AAAA,IACpB;AAEA,YAAQ,UAAU,YAAY,MAAM;AAOpC,SAAK,iBAAiB,MAAM;AAO5B,UAAM,OAAO,IAAI,IAAI,SAAS;AAC9B,UAAM,WAAW,CAAC,UAAwB;AACxC,UAAI,MAAM,WAAW,OAAO,cAAe;AAC3C,UAAI,MAAM,WAAW,KAAK,OAAQ;AAClC,UAAI,MAAM,MAAM,SAAS,iBAAkB;AAC3C,YAAM,IAAI,OAAO,MAAM,KAAK,MAAM;AAClC,UAAI,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG;AAC/B,eAAO,MAAM,SAAS,GAAG,CAAC;AAAA,MAC5B;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,QAAQ;AAM3C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBQ,iBAAiB,QAAuC;AAC9D,UAAM,eAAe,KAAK,gBAAgB;AAE1C,UAAM,OAAO,MAAM;AACjB,aAAO,eAAe;AAAA,QACpB,EAAE,MAAM,yBAAyB,QAAQ,OAAO,YAAY;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAEA,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,WAAW,OAAO,cAAe;AAC3C,UAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,aAAK;AAAA,MACP;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAIhD,QAAI,MAAqB;AACzB,UAAM,WAAW,MAAM;AACrB,UAAI,QAAQ,KAAM;AAClB,YAAM,sBAAsB,MAAM;AAChC,cAAM;AACN,aAAK;AAAA,MACP,CAAC;AAAA,IACH;AACA,WAAO,iBAAiB,UAAU,QAAQ;AAE1C,WAAO,MAAM;AACX,aAAO,oBAAoB,WAAW,aAAa;AACnD,aAAO,oBAAoB,UAAU,QAAQ;AAC7C,UAAI,QAAQ,KAAM,sBAAqB,GAAG;AAAA,IAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeQ,qBACN,WACA,QACA,cACwB;AACxB,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,UAAU,MAAM;AACpB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,OAAO;AACd,qBAAa,UAAU;AAAA,MACzB;AAEA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,cAAc;AACjC;AAAA,QACF;AAEA,cAAM,UAAU,MAAM;AAEtB,cAAM,UAAU,SAAS;AAEzB,YACE,SAAS,SAAS,4BAClB,SAAS,cAAc,WACvB;AACA,kBAAQ;AAER,cAAI,QAAQ,WAAW,QAAQ,WAAW;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,WAAW,QAAQ;AAAA,YACrB,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,WAAyB;AACnC,UAAM,SAAS,SAAS,eAAe,iBAAiB,SAAS,EAAE;AACnE,QAAI,QAAQ;AACV,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,yBAAiD;AACrD,UAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,UAAM,YAAY,OAAO,IAAI,YAAY;AACzC,UAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,UAAM,QAAQ,OAAO,IAAI,OAAO;AAChC,UAAM,eAAe,OAAO,IAAI,eAAe;AAE/C,QAAI,OAAO;AACT,aAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,aAAa;AAAA,QACxB,OAAO;AAAA,UACL,MAAM,wBAAwB,EAAE,MAAM,MAAM,CAAC,EAAE;AAAA,UAC/C,SAAS,gBAAgB;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,QAAI,WAAW,aAAa;AAC1B,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS,sBAAsB,MAAM;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,mBAAmB,SAAS;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAc,qBACZ,SACA,MACA,aACuC;AACvC,UAAM,WAAW,MAAM;AAAA,MACrB,GAAG,KAAK,OAAO,WAAW;AAAA,MAC1B;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,GAAI,KAAK,OAAO,YAAY,EAAE,UAAU,KAAK,OAAO,SAAS;AAAA,UAC7D,gBAAgB,QAAQ;AAAA,UACxB,WAAW,QAAQ;AAAA,UACnB,aAAa,QAAQ;AAAA,UACrB,UAAU,QAAQ;AAAA,UAClB,aAAa,QAAQ;AAAA,UACrB;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACxD,YAAM,IAAI,MAAM,UAAU,SAAS,UAAU,WAAW,kCAAkC;AAAA,IAC5F;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,UAAU,KAA4B;AAC5C,UAAM,OAAO,OAAO,WAAW,OAAO,aAAa,eAAe;AAClE,UAAM,MAAM,OAAO,UAAU;AAE7B,WAAO,OAAO;AAAA,MACZ;AAAA,MACA;AAAA,MACA,SAAS,WAAW,WAAW,YAAY,SAAS,IAAI,QAAQ,GAAG;AAAA,IACrE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBQ,mBACN,QACA,QACA,SACA,aACA,UAA2D,CAAC,GAC1C;AAClB,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,UAAU;AAEd,YAAM,WAAW,MAAM;AACrB,YAAI,QAAS;AACb,kBAAU;AACV,qBAAa,YAAY;AACzB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AAEA,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,YAAI,MAAM,MAAM,SAAS,iBAAiB;AACxC,gBAAM,eAAe,QAAQ,iBAAiB;AAC9C,mBAAS;AACT,cAAI,aAAc,QAAO,MAAM,EAAE,eAAe,KAAK,CAAC;AACtD,iBAAO,eAAe,YAAY;AAAA,YAChC,MAAM;AAAA,YACN,GAAG;AAAA,YACH,cAAc;AAAA,YACd;AAAA,UACF,GAAG,YAAY;AACf,kBAAQ,IAAI;AAAA,QACd,WACE,MAAM,MAAM,SAAS,mBACrB,MAAM,WAAW,OAAO,eACxB;AAIA,mBAAS;AACT,kBAAQ;AACR,kBAAQ,KAAK;AAAA,QACf;AAAA,MACF;AAGA,YAAM,cAAc,MAAM;AACxB,iBAAS;AACT,gBAAQ,KAAK;AAAA,MACf;AAGA,YAAM,eAAe,WAAW,MAAM;AACpC,iBAAS;AACT,gBAAQ;AACR,gBAAQ,KAAK;AAAA,MACf,GAAG,GAAK;AAER,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiCQ,kBAAkB,KAAa,SAMrC;AACA,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,UAAU,IAAI,IAAI,SAAS;AAEjC,UAAM,YAAY,IAAI,IAAI,KAAK,OAAO,SAAS,IAAI,EAAE;AACrD,UAAM,EAAE,YAAY,oBAAoB,MAAM,aAAa,IACzD,qBAAqB,SAAS;AAChC,UAAM,YAAY,UAAU,IAAI,OAAO,KAAK;AAC5C,UAAM,SACJ,cAAc,UACb,cAAc,WACb,OAAO,WAAW,8BAA8B,EAAE;AACtD,UAAM,QAAQ,SAAS,cAAc;AAErC,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ,UAAU;AACzB,QAAI,SAAS,QAAQ;AACnB,aAAO,QAAQ,gBAAgB;AAAA,IACjC;AACA,WAAO,MAAM,UAAU;AACvB,WAAO,MAAM,aAAa;AAC1B,aAAS,KAAK,YAAY,MAAM;AAEhC,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBA4CF,kBAAkB;AAAA,gCACR,YAAY;AAAA,wCACJ,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAQnC,mBAAmB;AAAA;AAAA;AAAA,yBAGX,oBAAoB;AAAA,sBACvB,MAAM,SAAS;AAAA;AAAA,uBAEd,mBAAmB;AAAA,uBACnB,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAU3B,gBAAgB;AAAA,mBACZ,qBAAqB;AAAA,yBACf,oBAAoB;AAAA,sBACvB,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,mBAKlB,oBAAoB;AAAA;AAAA;AAAA;AAAA,iBAItB,YAAY;AAAA,kBACX,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAOb,YAAY;AAAA,iCACI,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAO1C,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKrB,MAAM,WAAW;AAAA,qBACb,uBAAuB;AAAA,uBACrB,yBAAyB;AAAA,uBACzB,mBAAmB;AAAA;AAAA;AAAA;AAAA,iBAIzB,MAAM,aAAa;AAAA,qBACf,0BAA0B;AAAA,uBACxB,4BAA4B;AAAA,uBAC5B,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAYT,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gCAiBtB,YAAY;AAAA,wCACJ,YAAY;AAAA;AAAA;AAAA;AAIhD,WAAO,YAAY,KAAK;AAExB,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,QAAQ,iBAAiB;AAEjC,UAAM,cAAc,SAAS,cAAc,KAAK;AAChD,gBAAY,QAAQ,qBAAqB;AAEzC,UAAM,cAAc,SAAS,cAAc,KAAK;AAChD,gBAAY,QAAQ,qBAAqB;AACzC,UAAM,cAAc,SAAS,cAAc,KAAK;AAChD,gBAAY,QAAQ,4BAA4B;AAChD,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,QAAQ,wBAAwB;AACxC,UAAM,gBAAgB,eAAe;AACrC,UAAM,aAAa,wBAAwB;AAC3C,YAAQ,YACN,qBAAqB,YAAY,IAAI,YAAY,mFAClC,aAAa,SAAS,aAAa,QAAQ,cAAc,uDAAuD,cAAc,kBAC9H,aAAa,SAAS,aAAa,QAAQ,cAAc,yCAAyC,cAAc,8CAA8C,WAAW,IAAI,UAAU,2BAA2B,aAAa,IAAI,aAAa;AAEjQ,gBAAY,YAAY,OAAO;AAE/B,UAAM,cAAc,SAAS,cAAc,KAAK;AAChD,gBAAY,QAAQ,qBAAqB;AACzC,UAAM,eAAe,SAAS,cAAc,GAAG;AAC/C,iBAAa,QAAQ,sBAAsB;AAC3C,iBAAa,cAAc;AAC3B,UAAM,kBAAkB,SAAS,cAAc,GAAG;AAClD,oBAAgB,QAAQ,yBAAyB;AACjD,oBAAgB,cAAc;AAC9B,gBAAY,OAAO,cAAc,eAAe;AAChD,gBAAY,OAAO,aAAa,WAAW;AAC3C,gBAAY,YAAY,WAAW;AACnC,YAAQ,YAAY,WAAW;AAC/B,WAAO,YAAY,OAAO;AAG1B,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE;AAAA,QACA,6BAA6B,QAAQ,MAAM;AAAA,QAC3C,gCAAgC,QAAQ,MAAM;AAAA,QAC9C;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AACA,WAAO,aAAa,cAAc,wBAAwB;AAC1D,WAAO,aAAa,YAAY,GAAG;AAKnC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AACA,WAAO,aAAa,SAAS,SAAS;AAMtC,WAAO,MAAM,UAAU;AASvB,QAAI,WAAW;AAIf,QAAI;AACJ,UAAM,eAAe,MAAM;AACzB,UAAI,SAAU;AACd,iBAAW;AACX,mBAAa,aAAa;AAC1B,aAAO,MAAM,UAAU;AACvB,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAQA,UAAM,iBAAiB,WAAW,cAAc,GAAI;AAEpD,UAAM,gBAAgB,CAAC,UAAwB;AAC7C,UAAI,MAAM,WAAW,QAAQ,OAAQ;AAQrC,UAAI,MAAM,WAAW,OAAO,cAAe;AAI3C,UAAI,MAAM,MAAM,SAAS,oBAAoB;AAC3C,qBAAa;AAAA,MACf,WAgBE,MAAM,MAAM,SAAS,mBACrB,CAAC,YACD,kBAAkB,QAClB;AACA,wBAAgB,WAAW,cAAc,GAAI;AAAA,MAC/C;AAAA,IAGF;AACA,WAAO,iBAAiB,WAAW,aAAa;AAShD,UAAM,YAAY,IAAI,IAAI,KAAK,OAAO,SAAS,IAAI;AACnD,cAAU,aAAa,IAAI,gBAAgB,GAAG;AAC9C,WAAO,aAAa,OAAO,UAAU,SAAS,CAAC;AAC/C,WAAO,YAAY,MAAM;AAQzB,UAAM,sBAAsB,KAAK,iBAAiB,MAAM;AAIxD,UAAM,gBAAgB,IAAI,iBAAiB,CAAC,cAAc;AACxD,iBAAW,YAAY,WAAW;AAChC,YAAI,SAAS,kBAAkB,SAAS;AACtC,iBAAO,gBAAgB,OAAO;AAAA,QAChC;AAAA,MACF;AAAA,IACF,CAAC;AACD,kBAAc,QAAQ,QAAQ,EAAE,YAAY,KAAK,CAAC;AAGlD,UAAM,eAAe,CAAC,UAAyB;AAC7C,UAAI,MAAM,QAAQ,UAAU;AAC1B,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,aAAS,iBAAiB,WAAW,YAAY;AAEjD,UAAM,SAAS,MAAM;AACnB,aAAO,OAAO,QAAQ;AACtB,UAAI,CAAC,UAAU;AACb,mBAAW;AACX,qBAAa,aAAa;AAC1B,qBAAa,cAAc;AAAA,MAC7B;AACA,aAAO,MAAM,UAAU;AACvB,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAeA,UAAM,uBAAuB;AAC7B,UAAM,aAAa,CAAC,WAAmB;AACrC,UAAI,SAAS;AACb,YAAM,OAAO,MAAM;AACjB,YAAI,OAAO,YAAY,QAAQ;AAC7B,iBAAO,SAAS,EAAE,KAAK,QAAQ,MAAM,OAAO,SAAS,UAAU,OAAO,CAAC;AAAA,QACzE;AACA,YAAI,EAAE,SAAS,qBAAsB,uBAAsB,IAAI;AAAA,MACjE;AACA,WAAK;AAAA,IACP;AAWA,QAAI,mBAAkC;AACtC,UAAM,aAAa,MAAM;AACvB,UAAI,OAAO,KAAM,oBAAmB,OAAO;AAAA,IAC7C;AACA,UAAM,cAAc,MAAM;AACxB,UAAI,CAAC,OAAO,QAAQ,qBAAqB,KAAM;AAC/C,iBAAW,gBAAgB;AAAA,IAC7B;AACA,WAAO,iBAAiB,QAAQ,UAAU;AAC1C,WAAO,iBAAiB,SAAS,WAAW;AAI5C,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK;AAAA,IACd,OAAO;AACL,aAAO,UAAU;AAAA,IACnB;AAEA,QAAI,YAAY;AAChB,UAAM,UAAU,MAAM;AACpB,UAAI,UAAW;AACf,kBAAY;AACZ,mBAAa,cAAc;AAC3B,mBAAa,aAAa;AAC1B,oBAAc,WAAW;AACzB,0BAAoB;AACpB,aAAO,oBAAoB,WAAW,aAAa;AACnD,aAAO,oBAAoB,QAAQ,UAAU;AAC7C,aAAO,oBAAoB,SAAS,WAAW;AAC/C,eAAS,oBAAoB,WAAW,YAAY;AAQpD,YAAM,gBAAgB,CAAC,SAAS,UAAU,OAAO,OAAO,OAAO,UAAU;AACzE,aAAO,MAAM;AAEb,UAAI,OAAO,YAAY;AACrB,mBAAW,WAAW,MAAM,KAAK,OAAO,WAAW,QAAQ,GAAG;AAC5D,cAAI,YAAY,UAAU,mBAAmB,eAAe,QAAQ,aAAa,OAAO,GAAG;AACzF,oBAAQ,gBAAgB,OAAO;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AACA,aAAO,OAAO;AACd,UAAI,kBAAkB,KAAM,YAAW,aAAa;AAAA,IACtD;AAMA,UAAM,UAAU,SAAS,aACrB,MAAM;AACJ,UAAI,CAAC,OAAO,KAAM;AAGlB,YAAM,gBAAgB,SAAS,SAAS,OAAO,OAAO;AACtD,aAAO,MAAM;AACb,UAAI,kBAAkB,KAAM,YAAW,aAAa;AAAA,IACtD,IACA;AAEJ,WAAO,EAAE,QAAQ,QAAQ,SAAS,SAAS,OAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BQ,yBACN,SACA,QACA,SACA,WACqB;AACrB,UAAM,eAAe,KAAK,gBAAgB;AAK1C,UAAM,aAAa,mBAAmB;AACtC,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AACnC,cAAM,OAAO,MAAM;AAEnB,cAAM,gBAAgB,MAAM,WAAW,OAAO;AAC9C,cAAM,iBACJ,OAAO,cAAc,YAAY,MAAM,cAAc;AACvD,cAAM,eAAe,MAAM,eAAe;AAC1C,cAAM,sBACJ,MAAM,SAAS,mBAAmB;AAEpC,YACE,MAAM,SAAS,oBACd,kBAAkB,gBAAgB,sBACnC;AACA,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAMA,YAAI,MAAM,SAAS,iBAAiB;AAElC,iBAAO,eAAe,YAAY;AAAA,YAChC,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,YACd;AAAA,UACF,GAAG,YAAY;AACf;AAAA,QACF;AAEA,cAAM,gBAAgB,OAAO,MAAM,eAAe;AAClD,cAAM,yBACJ,iBAAiB,gBAAgB,CAAC;AACpC,YAAI,CAAC,uBAAwB;AAM7B,YAAI,MAAM,cAAc,KAAK,eAAe,WAAY;AAExD,YAAI,MAAM,SAAS,wBAAwB;AACzC,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AAER,cAAI,KAAK,SAAS;AAChB,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,MAAM;AAAA,gBACJ,IAAI,KAAK,MAAM,MAAM;AAAA,gBACrB,SAAS,KAAK,MAAM;AAAA,cACtB;AAAA,cACA,YAAY,KAAK,MAAM,cAAc;AAAA,YACvC,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,OAAO,KAAK;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF,WAAW,MAAM,SAAS,uBAAuB;AAG/C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AAGR,gBAAM,WAAW,KAAK,MAAM,KAAK,QAAQ,eAAe,YAAY,KAC/D,GAAG,KAAK,aAAa,CAAC,0BAA0B,KAAK,OAAO,WAAW,aAAa,KAAK,OAAO,QAAQ,KAAK,EAAE;AAGpH,eAAK,yBAAyB,QAAQ,EAAE,KAAK,OAAO;AAAA,QACtD;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,yBAAyB,KAAkC;AACjE,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,aAAa,mBAAmB;AACtC,UAAM,QAAQ,KAAK,UAAU,GAAG;AAEhC,QAAI,CAAC,OAAO;AACV,aAAO,QAAQ,QAAQ;AAAA,QACrB,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AAAA,IACH;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,UAAU;AAEd,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,gBAAgB,MAAM,WAAW,MAAO;AAE7D,cAAM,OAAO,MAAM;AACnB,YAAI,MAAM,SAAS,iBAAiB;AAClC,gBAAM,YAAY;AAAA,YAChB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,cAAc;AAAA,YACd;AAAA,UACF,GAAG,YAAY;AACf;AAAA,QACF;AAEA,YAAI,MAAM,SAAS,wBAAwB;AACzC;AAAA,YACE,KAAK,UACD;AAAA,cACE,SAAS;AAAA,cACT,MAAM;AAAA,gBACJ,IAAI,KAAK,MAAM,MAAM;AAAA,gBACrB,SAAS,KAAK,MAAM;AAAA,cACtB;AAAA,cACA,YAAY,KAAK,MAAM,cAAc;AAAA,YACvC,IACA,EAAE,SAAS,OAAO,OAAO,KAAK,MAAM;AAAA,YACxC;AAAA,UACF;AAAA,QACF,WAAW,MAAM,SAAS,iBAAiB;AACzC,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,GAAG,IAAI;AAAA,QACT;AAAA,MACF;AAEA,YAAM,SAAS,CAAC,QAAoB,eAAwB;AAC1D,YAAI,QAAS;AACb,kBAAU;AACV,sBAAc,SAAS;AACvB,eAAO,oBAAoB,WAAW,aAAa;AACnD,YAAI,WAAY,OAAM,MAAM;AAC5B,gBAAQ,MAAM;AAAA,MAChB;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAGhD,YAAM,YAAY,YAAY,MAAM;AAClC,YAAI,MAAM,QAAQ;AAChB,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,GAAG,KAAK;AAAA,QACV;AAAA,MACF,GAAG,GAAG;AAAA,IACR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBQ,uBACN,SACA,SACA,SACwB;AACxB,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,OAAO,MAAM;AACnB,YAAI,MAAM,SAAS,0BAA0B;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AAER,cAAI,KAAK,SAAS;AAChB,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,MAAM;AAAA,gBACJ,SAAS,KAAK,MAAM;AAAA,cACtB;AAAA;AAAA;AAAA;AAAA,cAIA,YAAY,KAAK,MAAM,cAAc;AAAA,cACrC,eAAe,KAAK,MAAM;AAAA,YAC5B,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,QAAQ,KAAK,MAAM;AAAA,cACnB,OAAO,KAAK;AAAA,YACd,CAAC;AAAA,UACH;AAAA,QACF,WAAW,MAAM,SAAS,iBAAiB;AACzC,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,QAAQ;AAAA,YACR,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeQ,+BACN,QACA,QACA,SACA,SACA,aACiC;AACjC,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAI,YAAY;AAEhB,YAAM,WAAW,MAAM;AACrB,qBAAa,YAAY;AACzB,eAAO,oBAAoB,WAAW,aAAa;AACnD,eAAO,oBAAoB,SAAS,WAAW;AAAA,MACjD;AAEA,YAAM,WAAW,MAAM;AACrB,eAAO,eAAe;AAAA,UACpB,EAAE,MAAM,gBAAgB,GAAG,aAAa,cAAc,KAAK;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,MAAM;AACxB,iBAAS;AACT,gBAAQ;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,gBAAgB,OAAO,UAAwB;AACnD,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,OAAO,MAAM;AAEnB,YAAI,MAAM,SAAS,iBAAiB;AAClC,sBAAY;AACZ,uBAAa,YAAY;AAIzB,mBAAS;AACT;AAAA,QACF;AAEA,YAAI,MAAM,SAAS,yCAAyC;AAC1D,gBAAM,YAAY,KAAK;AACvB,gBAAM,WAAW,KAAK;AACtB,gBAAM,eAAe,CAAC,YAAqC;AACzD,mBAAO,eAAe;AAAA,cACpB,EAAE,MAAM,0CAA0C,WAAW,GAAG,QAAQ;AAAA,cACxE;AAAA,YACF;AAAA,UACF;AAEA,cAAI,CAAC,aAAa,CAAC,UAAU;AAC3B,yBAAa,EAAE,SAAS,OAAO,OAAO,kCAAkC,CAAC;AACzE;AAAA,UACF;AAEA,cAAI,CAAC,SAAS;AACZ,yBAAa,EAAE,SAAS,KAAK,CAAC;AAC9B;AAAA,UACF;AAEA,cAAI,CAAC,KAAK,aAAa;AACrB,yBAAa,EAAE,SAAS,OAAO,OAAO,gCAAgC,CAAC;AACvE;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,QAAQ,MAAM,KAAK,YAAY,kBAAkB,QAAQ;AAC/D,yBAAa,EAAE,SAAS,MAAM,MAAM,CAAC;AAAA,UACvC,SAAS,KAAK;AACZ,yBAAa;AAAA,cACX,SAAS;AAAA,cACT,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,YACxD,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAEA,YAAI,MAAM,SAAS,mCAAmC;AACpD,cAAI,KAAK,SAAS;AAYhB,qBAAS;AACT,oBAAQ,EAAE,SAAS,MAAM,GAAI,KAAK,QAAQ,CAAC,EAAG,CAAC;AAC/C;AAAA,UACF;AAMA,mBAAS;AACT,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO,KAAK,SAAS,KAAK,MAAM,SAAS;AAAA,cACvC,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH,WACE,MAAM,SAAS,mBACf,MAAM,WAAW,OAAO,eACxB;AAKA,mBAAS;AACT,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,YAAM,eAAe,WAAW,MAAM;AACpC,YAAI,UAAW;AACf,iBAAS;AACT,gBAAQ;AACR,gBAAQ;AAAA,UACN,SAAS;AAAA,UACT,OAAO;AAAA,YACL,MAAM;AAAA,YACN,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH,GAAG,GAAK;AAER,aAAO,iBAAiB,WAAW,aAAa;AAChD,aAAO,iBAAiB,SAAS,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBQ,4BACN,WACA,SACA,SACA,SACwB;AACxB,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,aAAc;AAEnC,cAAM,UAAU,MAAM;AAGtB,cAAM,UAAU,SAAS;AAE/B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,iBAAiB,SAAS,uBAAuB;AAAA,UACjE,CAAC;AACD;AAAA,QACD;AAEM,YAAI,SAAS,SAAS,4BAA4B,SAAS,cAAc,WAAW;AAClF,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AAER,cAAI,QAAQ,WAAW,QAAQ,WAAW;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,WAAW,QAAQ;AAAA,YACrB,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF,WAAW,SAAS,SAAS,iBAAiB;AAC5C,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AACR,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT;AAAA,YACA,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBQ,qBACN,WACA,OACwB;AACxB,UAAM,eAAe,KAAK,gBAAgB;AAC1C,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,cAAc,YAAY,MAAM;AACpC,YAAI,MAAM,QAAQ;AAChB,wBAAc,WAAW;AACzB,iBAAO,oBAAoB,WAAW,aAAa;AACnD,kBAAQ;AAAA,YACN,SAAS;AAAA,YACT;AAAA,YACA,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,GAAG,GAAG;AAEN,YAAM,gBAAgB,CAAC,UAAwB;AAC7C,YAAI,MAAM,WAAW,cAAc;AACjC;AAAA,QACF;AAEA,cAAM,UAAU,MAAM;AAEtB,cAAM,UAAU,SAAS;AAE/B,YAAI,SAAS,SAAS,sBAAsB;AAC3C,wBAAc,WAAW;AACzB,iBAAO,oBAAoB,WAAW,aAAa;AACnD,gBAAM,MAAM;AACZ,kBAAQ;AAAA,YACP,SAAS;AAAA,YACT;AAAA,YACA,OAAO,EAAE,MAAM,iBAAiB,SAAS,uBAAuB;AAAA,UACjE,CAAC;AACD;AAAA,QACD;AAEM,YACE,SAAS,SAAS,4BAClB,SAAS,cAAc,WACvB;AACA,wBAAc,WAAW;AACzB,iBAAO,oBAAoB,WAAW,aAAa;AACnD,gBAAM,MAAM;AAEZ,cAAI,QAAQ,WAAW,QAAQ,WAAW;AACxC,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,WAAW,QAAQ;AAAA,YACrB,CAAC;AAAA,UACH,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT;AAAA,cACA,OAAO,wBAAwB,QAAQ,KAAK;AAAA,YAC9C,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,aAAO,iBAAiB,WAAW,aAAa;AAAA,IAClD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAc,mBAAmB,WAA2C;AAC1E,UAAM,WAAW,MAAM;AAAA,MACrB,GAAG,KAAK,OAAO,WAAW,qBAAqB,SAAS;AAAA,MACxD;AAAA,QACE,SAAS,KAAK,OAAO,WACjB,EAAE,eAAe,KAAK,OAAO,SAAS,IACtC,CAAC;AAAA,MACP;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,QAAI,KAAK,WAAW,eAAe,KAAK,WAAW;AACjD,aAAO;AAAA,QACL,SAAS;AAAA,QACT;AAAA,QACA,WAAW,KAAK;AAAA,MAClB;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA,MACZ,KAAK;AAAA,MACL,KAAK,WAAW,YAAY,YAAY;AAAA,MACxC,mBAAmB,KAAK,MAAM;AAAA,IAChC;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF;;;AG3zNA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AA0DP,IAAM,sBAAsB;AA6CrB,SAAS,sBACd,SACiB;AACjB,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,UAAU,QAAQ;AACtB,QAAM,aAAa,QAAQ,cAAc;AAEzC,QAAM,YAAY,oBAAI,IAA2B;AAajD,MAAI;AAQJ,QAAM,OAAO,CAAC,UAAkB,SAAoB;AAClD,UAAM,MAAM,UAAU,IAAI,KAAK;AAC/B,QAAI,CAAC,IAAK;AACV,eAAW,YAAY,IAAK,UAAS,GAAG,IAAI;AAAA,EAC9C;AAUA,QAAM,gBAAgB,MAAyB;AAK7C,QAAI,oBAAoB,OAAW,QAAO;AAC1C,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAI;AACF,YAAM,MAAM,aAAa,QAAQ,UAAU;AAC3C,UAAI,CAAC,IAAK,QAAO;AACjB,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,CAAC,QAAQ,QAAS,QAAO;AAC7B,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AASA,QAAM,gBAAgB,CAAC,SAAqB;AAC1C,QAAI,OAAO,WAAW,YAAa;AACnC,iBAAa,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC;AAAA,EACvD;AAQA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,WAAW,YAAa;AACnC,iBAAa,WAAW,UAAU;AAAA,EACpC;AAGA,QAAM,gBAAgB,MAAM;AAC1B,sBAAkB;AAClB,oBAAgB;AAChB,SAAK,mBAAmB,CAAC,CAAC;AAC1B,SAAK,YAAY;AAAA,EACnB;AAKA,MAAI,OAAQ,8BAA6B,QAAQ,aAAa;AAa9D,QAAM,UAAU,YAAgC;AAC9C,UAAM,SAAS,cAAc;AAC7B,QAAI,QAAQ;AACV,aAAO,CAAC,OAAO,OAAO;AAAA,IACxB;AAEA,UAAM,aAAa,MAAM,OAAO,cAAc;AAC9C,QAAI,CAAC,WAAW,SAAS;AACvB,YAAM,IAAI,MAAM,WAAW,OAAO,WAAW,uBAAuB;AAAA,IACtE;AACA,UAAM,UAAU,WAAW,MAAM;AACjC,UAAM,aAAa,WAAW;AAE9B,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAEA,kBAAc,EAAE,SAAS,WAAW,CAAC;AACrC,SAAK,mBAAmB,CAAC,OAAO,CAAC;AACjC,SAAK,WAAW,EAAE,SAAS,YAAY,OAAO,EAAE,CAAC;AACjD,WAAO,CAAC,OAAO;AAAA,EACjB;AAQA,QAAM,aAAa,YAAY;AAC7B,kBAAc;AAAA,EAChB;AAMA,QAAM,aAAa,CACjB,YAGG;AACH,QAAI,CAAC,SAAS;AACZ,oBAAc;AACd;AAAA,IACF;AACA,sBAAkB;AAAA,MAChB,SAAS,QAAQ;AAAA,MACjB,YAAY,QAAQ;AAAA,MACpB,aAAa,QAAQ;AAAA,IACvB;AACA,kBAAc,eAAe;AAC7B,SAAK,mBAAmB,CAAC,QAAQ,OAAO,CAAC;AACzC,SAAK,WAAW,EAAE,SAAS,YAAY,OAAO,EAAE,CAAC;AAAA,EACnD;AAWA,QAAM,aAAa,YAAiC;AAClD,UAAM,SAAS,cAAc;AAC7B,QAAI,OAAQ,QAAO;AACnB,UAAM,CAAC,OAAO,IAAI,MAAM,QAAQ;AAChC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,UAAM,OAAO,cAAc;AAC3B,WAAO,QAAQ,EAAE,QAAQ;AAAA,EAC3B;AAKA,QAAM,0BAA0B,CAC9B,iBACuB;AACvB,UAAM,MAAM,MAAM,QAAQ,YAAY,IAAI,aAAa,CAAC,IAAI;AAC5D,QAAI,OAAO,QAAQ,YAAY,IAAI,KAAK,EAAG,QAAO,IAAI,KAAK;AAC3D,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAE5C,UAAMC,WAAU;AAChB,UAAM,aAAa;AAAA,MACjBA,SAAQ;AAAA,MACRA,SAAQ;AAAA,IACV;AACA,eAAW,aAAa,YAAY;AAClC,UAAI,OAAO,cAAc,YAAY,UAAU,KAAK,GAAG;AACrD,eAAO,UAAU,KAAK;AAAA,MACxB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAWA,QAAM,eAAe,CAAC,UAAuC;AAC3D,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,MAAM,WAAW,IAAI,EAAG,QAAO,OAAO,SAAS,OAAO,EAAE;AAC5D,YAAM,SAAS,OAAO,KAAK;AAC3B,aAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAYA,QAAM,iBAAiB,CAAC,UAAuC;AAC7D,QAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,QAAI,OAAO,UAAU,SAAU,QAAO,MAAM,SAAS;AACrD,QAAI,OAAO,UAAU,SAAU,QAAO,KAAK,MAAM,KAAK,EAAE,SAAS;AACjE,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,eAAO,OAAO,KAAK,EAAE,SAAS;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAYA,QAAM,iBAAiB,CAAC,UAAmC;AACzD,WAAO,MAAM,IAAI,CAAC,SAAS;AACzB,YAAM,IAAI;AACV,aAAO;AAAA,QACL,IAAI,EAAE;AAAA,QACN,MAAO,EAAE,QAA4B;AAAA,QACrC,OAAO,eAAe,EAAE,KAAK,KAAK;AAAA,QAClC,OAAO,EAAE;AAAA,QACT,UAAU,EAAE;AAAA,QACZ,MAAM,EAAE;AAAA,QACR,KAAK,EAAE;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAYA,QAAM,yBAAyB,CAC7B,aACqC;AACrC,QAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACrC,WAAO,SAAS,IAAI,CAAC,MAAM;AACzB,YAAM,MAAM;AACZ,aAAO;AAAA,QACL,OAAO,IAAI;AAAA,QACX,QACE,OAAO,IAAI,WAAW,WAClB,IAAI,SACJ,OAAO,OAAO,IAAI,UAAU,GAAG,CAAC;AAAA,MACxC;AAAA,IACF,CAAC;AAAA,EACH;AAYA,QAAM,gBAAgB,CAAC,UAAkB;AACvC,QAAI,CAAC,MAAM,KAAK,EAAG,QAAO;AAC1B,QAAI;AACF,aAAO,YAAY,KAAY;AAAA,IACjC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAOA,QAAM,kBAAkB,OACtB,QACA,QACA,oBACqB;AACrB,UAAM,SAAS,MAAM,OAAO,kBAAkB;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,MAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAC1C,MAAC,IAAkC,OAAO,OAAO,MAAM;AACvD,YAAM;AAAA,IACR;AACA,WAAO,OAAO;AAAA,EAChB;AAQA,QAAM,wBAAwB,oBAAI,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAaD,QAAM,cAAc,OAAO,YAAoB;AAC7C,UAAM,OAAO,MAAM,WAAW;AAC9B,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AACA,UAAM,SAAS,MAAM,OAAO,YAAY;AAAA,MACtC,gBAAgB,KAAK;AAAA,MACrB;AAAA,IACF,CAAC;AACD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,eAAe,OAAO,OAAO,kBAAkB,gBAAgB;AAAA,IACvE;AACA,QAAI,CAAC,OAAO,WAAW;AACrB,YAAM,eAAe,QAAW,yBAAyB,gBAAgB;AAAA,IAC3E;AACA,WAAO,wBAAwB,OAAO,SAAS;AAAA,EACjD;AAaA,QAAM,gBAAgB,OAAO,cAAuB;AAClD,UAAM,OAAO,MAAM,WAAW;AAC9B,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AACA,UAAM,OACJ,OAAO,cAAc,WAAW,KAAK,MAAM,SAAS,IAAI;AAC1D,UAAM,SAAS,MAAM,OAAO,cAAc;AAAA,MACxC,gBAAgB,KAAK;AAAA,MACrB,QAAS,KAAa;AAAA,MACtB,OAAQ,KAAa;AAAA,MACrB,aAAc,KAAa;AAAA,MAC3B,SAAU,KAAa;AAAA,IACzB,CAAC;AACD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,eAAe,OAAO,OAAO,kBAAkB,gBAAgB;AAAA,IACvE;AACA,QAAI,CAAC,OAAO,WAAW;AACrB,YAAM,eAAe,QAAW,yBAAyB,gBAAgB;AAAA,IAC3E;AACA,WAAO,wBAAwB,OAAO,SAAS;AAAA,EACjD;AAWA,QAAM,uBAAuB,CAAC,aAKvB;AAAA,IACL,gBAAgB,QAAQ;AAAA,IACxB,aAAa,QAAQ;AAAA,IACrB,OAAO,QAAQ;AAAA,IACf,eAAe,QAAQ;AAAA,EACzB;AAiBA,QAAM,aAAa,OAAO,YAMpB;AACJ,UAAM,gBAAgB,qBAAqB,OAAO;AAClD,UAAM,SAAS,MAAM,OAAO,WAAW;AAAA,MACrC,GAAG;AAAA,MACH,eAAe,QAAQ;AAAA,MACvB,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ,eAAe;AAAA,MACpC,eAAe,QAAQ;AAAA,MACvB,gBAAgB,QAAQ;AAAA,IAC1B,CAAC;AAED,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,eAAe,OAAO,OAAO,sBAAsB,eAAe;AAAA,IAC1E;AAGA,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,uBAAuB,MAAiC;AAC5D,UAAM,MAAM,IAAI;AAAA,MACd;AAAA,IACF;AACA,QAAI,OAAO;AACX,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,CAAC,GAAY,MAC/B,OAAO,MAAM,YAAY,EAAE,YAAY,MAAM,EAAE,YAAY;AAe7D,QAAM,kBAAkB,CACtB,QACA,QACA,YACoD;AACpD,UAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,MAAM,IAAI;AACtD,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO;AAEjC,QAAI,WAAW,uBAAuB;AACpC,YAAM,QAAS,KAAK,CAAC,KAAK,CAAC;AAC3B,UAAI,MAAM,SAAS,UAAa,CAAC,YAAY,MAAM,MAAM,OAAO,GAAG;AACjE,cAAM,qBAAqB;AAAA,MAC7B;AACA,WAAK,CAAC,IAAI,EAAE,GAAG,OAAO,MAAM,QAAQ;AACpC,aAAO;AAAA,IACT;AACA,QAAI,WAAW,oBAAoB;AACjC,YAAM,QAAS,KAAK,CAAC,KAAK,CAAC;AAC3B,UAAI,MAAM,SAAS,UAAa,CAAC,YAAY,MAAM,MAAM,OAAO,GAAG;AACjE,cAAM,qBAAqB;AAAA,MAC7B;AAGA,YAAM,QAAQ,MAAM;AACpB,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,mBAAW,QAAQ,OAAO;AACxB,cAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,gBAAM,WAAY,KAAiC;AACnD,cAAI,aAAa,UAAa,CAAC,YAAY,UAAU,OAAO,GAAG;AAC7D,kBAAM,qBAAqB;AAAA,UAC7B;AAAA,QACF;AAAA,MACF;AACA,WAAK,CAAC,IAAI,EAAE,GAAG,OAAO,MAAM,QAAQ;AACpC,aAAO;AAAA,IACT;AACA,QAAI,WAAW,iBAAiB;AAE9B,UAAI,KAAK,CAAC,MAAM,UAAa,CAAC,YAAY,KAAK,CAAC,GAAG,OAAO,GAAG;AAC3D,cAAM,qBAAqB;AAAA,MAC7B;AACA,UAAI,KAAK,CAAC,KAAK,KAAK,CAAC,MAAM,OAAW,MAAK,CAAC,IAAI;AAChD,aAAO;AAAA,IACT;AACA,QACE,WAAW,cACX,WAAW,uBACX,WAAW,0BACX,WAAW,wBACX;AAEA,UAAI,KAAK,CAAC,MAAM,UAAa,CAAC,YAAY,KAAK,CAAC,GAAG,OAAO,GAAG;AAC3D,cAAM,qBAAqB;AAAA,MAC7B;AACA,UAAI,KAAK,CAAC,MAAM,UAAa,KAAK,CAAC,MAAM,OAAW,MAAK,CAAC,IAAI;AAC9D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAOA,QAAM,aAAa,oBAAI,IAAsB;AAS7C,QAAM,eAAe,OACnB,QACA,YACoB;AAEpB,UAAM,YAAY,gBAAgB,oBAAoB,QAAQ,OAAO;AACrE,UAAM,UAAW,MAAM,QAAQ,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC;AAC5D,UAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D,QAAI,CAAC,MAAM,OAAQ,OAAM,IAAI,MAAM,mBAAmB;AACtD,UAAM,eAAe,QAAQ;AAC7B,UAAM,SAAmB,CAAC;AAC1B,eAAW,OAAO,OAAO;AACvB,YAAM,OAAQ,OAAO,CAAC;AACtB,YAAM,KAA8B,EAAE,MAAM,SAAS,IAAI,KAAK,GAAG;AACjE,UAAI,KAAK,SAAS,OAAW,IAAG,OAAO,KAAK;AAC5C,UAAI,KAAK,UAAU,OAAW,IAAG,QAAQ,KAAK;AAC9C,YAAM,YAAY,KAAK,WAAW;AAClC,UAAI,cAAc,OAAW,IAAG,UAAU;AAC1C,YAAM,OAAO,MAAM,gBAAgB,uBAAuB,CAAC,EAAE,GAAG,OAAO;AACvE,aAAO,KAAK,OAAO,IAAI,CAAC;AAAA,IAC1B;AACA,UAAM,KAAK,OAAO,OAAO,SAAS,CAAC;AACnC,eAAW,IAAI,IAAI,MAAM;AACzB,WAAO;AAAA,EACT;AAGA,QAAM,oBAAoB,CAAC,YAAqB;AAC9C,QAAI,CAAC,WAAW,OAAO,YAAY,UAAU;AAC3C,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,UAAM,SAAS,WAAW,IAAI,OAAO,KAAK,CAAC,OAAO;AAKlD,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,UAAU,OAAO,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,EAAE,QAAQ,OAAO,MAAuB;AAM7D,QAAI,sBAAsB,IAAI,MAAM,GAAG;AACrC,YAAM,OAAO,MAAM,WAAW;AAC9B,UAAI,KAAK,eAAe,OAAO;AAG7B,YAAI,WAAW,oBAAoB;AACjC,iBAAO,aAAa,QAAQ,KAAK,OAAO;AAAA,QAC1C;AACA,YAAI,WAAW,yBAAyB;AACtC,gBAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AAC/C,iBAAO,kBAAkB,KAAK,CAAC,CAAC;AAAA,QAClC;AACA,eAAO;AAAA,UACL;AAAA,UACA,gBAAgB,QAAQ,QAAQ,KAAK,OAAO;AAAA,UAC5C,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,YAAY,OAAO;AAAA,MAC5B,KAAK,gBAAgB;AACnB,cAAM,SAAS,cAAc;AAC7B,eAAO,SAAS,CAAC,OAAO,OAAO,IAAI,CAAC;AAAA,MACtC;AAAA,MACA,KAAK;AACH,eAAO,QAAQ;AAAA,MACjB,KAAK;AACH,eAAO,QAAQ;AAAA,MACjB,KAAK;AACH,cAAM,WAAW;AACjB,eAAO;AAAA,MACT,KAAK,8BAA8B;AACjC,cAAM,CAAC,KAAK,IAAK,UAAoB,CAAC;AACtC,cAAM,OAAO,aAAa,OAAO,WAAW,KAAK;AACjD,YAAI,CAAC,MAAM;AACT,gBAAM,IAAI,MAAM,iBAAiB;AAAA,QACnC;AACA,cAAM,SAAS,cAAc;AAC7B,YAAI,QAAQ,eAAe,OAAO;AAChC,gBAAM,gBAAgB,QAAQ,QAAQ,OAAO,OAAO;AAAA,QACtD;AACA,kBAAU;AACV,aAAK,gBAAgB,YAAY,OAAO,CAAC;AACzC,eAAO;AAAA,MACT;AAAA,MACA,KAAK,iBAAiB;AACpB,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,QAAQ,UAAU,CAAC;AACzB,cAAM,SAAS,UAAU,CAAC;AAK1B,cAAM,UACJ,OAAO,UAAU,YAAY,MAAM,WAAW,IAAI,KAAK,SACnD,OAAO,WAAW,YAAY,CAAC,OAAO,WAAW,IAAI,IACnD,SACA,cAAc,KAAK,IACrB,OAAO,UAAU,WACf,cAAc,KAAK,IACnB,OAAO,WAAW,WAChB,cAAc,MAAM,IACpB;AACV,YAAI,CAAC,QAAS,OAAM,IAAI,MAAM,+BAA+B;AAC7D,eAAO,YAAY,OAAO;AAAA,MAC5B;AAAA,MACA,KAAK,YAAY;AACf,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,UAAU,OAAO,UAAU,CAAC,MAAM,WAAW,UAAU,CAAC,IAAI;AAClE,YAAI,CAAC,QAAS,OAAM,IAAI,MAAM,0BAA0B;AACxD,eAAO,YAAY,cAAc,OAAO,CAAC;AAAA,MAC3C;AAAA,MACA,KAAK;AAAA,MACL,KAAK,wBAAwB;AAC3B,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,YAAY,UAAU,CAAC,KAAK,UAAU,CAAC;AAC7C,eAAO,cAAc,SAAS;AAAA,MAChC;AAAA,MACA,KAAK,uBAAuB;AAC1B,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,KAAM,UAAU,CAAC,KAAK,CAAC;AAC7B,cAAM,OAAO,MAAM,WAAW;AAC9B,cAAM,cAAc,aAAa,GAAG,OAAO,KAAK;AAChD,cAAM,QAAQ,eAAe,CAAC,EAAE,CAAC;AACjC,cAAM,gBAAgB,uBAAuB,GAAG,aAAa;AAC7D,cAAM,kBAAkB,aAAa,GAAG,aAAa;AACrD,eAAO,WAAW;AAAA,UAChB,gBAAgB,KAAK;AAAA,UACrB;AAAA,UACA;AAAA,UACA;AAAA,UACA,eAAe;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,MACA,KAAK,oBAAoB;AACvB,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,UAAW,UAAU,CAAC,KAAK,CAAC;AAClC,cAAM,OAAO,MAAM,WAAW;AAC9B,cAAM,cAAc,aAAa,QAAQ,OAAO,KAAK;AACrD,cAAM,QAAQ,eAAgB,QAAQ,SAAuB,CAAC,CAAC;AAC/D,cAAM,gBAAgB,uBAAuB,QAAQ,aAAa;AAClE,cAAM,gBAAgB,aAAa,QAAQ,aAAa;AACxD,YAAI,CAAC,MAAM,OAAQ,OAAM,IAAI,MAAM,mBAAmB;AACtD,eAAO,WAAW;AAAA,UAChB,gBAAgB,KAAK;AAAA,UACrB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,KAAK,0BAA0B;AAC7B,cAAM,SAAS,cAAc;AAC7B,YAAI,QAAQ,eAAe,OAAO;AAChC,iBAAO,CAAC;AAAA,QACV;AAEA,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AAEpD,cAAM,kBAAkB,UAAU,CAAC;AAEnC,cAAM,WAAW,qBAAqB;AACtC,cAAM,eAA+D,CAAC;AAEtE,mBAAWC,YAAW,UAAU;AAC9B,gBAAM,aAAa,KAAKA,SAAQ,SAAS,EAAE,CAAC;AAG5C,cAAI,mBAAmB,CAAC,gBAAgB,SAAS,UAAU,GAAG;AAC5D;AAAA,UACF;AAIA,uBAAa,UAAU,IAAI;AAAA,YACzB,QAAQ,EAAE,QAAQ,YAAY;AAAA,YAC9B,kBAAkB,EAAE,WAAW,KAAK;AAAA,YACpC,gBAAgB,EAAE,WAAW,KAAK;AAAA,UACpC;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,oBAAoB;AACvB,cAAM,yBAAyB,wBAAwB,MAAM;AAC7D,cAAM,OAAO,yBAAyB,OAAO,MAAM,WAAW;AAM9D,cAAM,iBAAiB,0BAA0B,MAAM;AACvD,YAAI,CAAC,gBAAgB;AACnB,gBAAM,IAAI,MAAM,iEAAiE;AAAA,QACnF;AACA,eAAO,OAAO,UAAU,EAAE,eAA0C,CAAC;AAAA,MACvE;AAAA,MACA,KAAK,yBAAyB;AAC5B,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAM,UAAU,UAAU,CAAC;AAC3B,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,qBAAqB;AAAA,QACvC;AACA,cAAM,iBAAiB,OAAO,YAAY;AAC1C,cAAM,WAAW,MAAM;AAAA,UACrB,GAAG,OAAO,eAAe,CAAC,sBAAsB,mBAAmB,OAAO,CAAC;AAAA,UAC3E;AAAA,YACE,SAAS,iBAAiB,EAAE,eAAe,eAAe,IAAI,CAAC;AAAA,UACjE;AAAA,QACF;AACA,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAMC,QAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,gBAAM,IAAI,MAAMA,MAAK,SAAS,4BAA4B;AAAA,QAC5D;AACA,cAAM,OAAO,MAAM,SAAS,KAAK;AAIjC,cAAM,YAAoC;AAAA,UACxC,SAAS;AAAA,UACT,cAAc;AAAA,UACd,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AACA,eAAO;AAAA,UACL,QAAQ,UAAU,KAAK,MAAM,KAAK;AAAA,UAClC,UAAU,KAAK,kBACX;AAAA,YACE;AAAA,cACE,MAAM,CAAC;AAAA;AAAA,cAEP,QAAQ,KAAK,WAAW,cAAc,QAAQ;AAAA,cAC9C,WAAW,KAAK;AAAA,cAChB,aAAa,KAAK;AAAA,cAClB,iBAAiB,KAAK;AAAA,YACxB;AAAA,UACF,IACA,CAAC;AAAA,QACP;AAAA,MACF;AAAA,MACA,KAAK,0BAA0B;AAC7B,cAAM,YAAY,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACpD,cAAMC,WAAW,UAAU,CAAC,KAAK,CAAC;AAQlC,cAAM,cAAc,IAAI,gBAAgB;AACxC,YAAIA,SAAQ,MAAO,aAAY,IAAI,SAAS,OAAOA,SAAQ,KAAK,CAAC;AACjE,YAAIA,SAAQ,OAAQ,aAAY,IAAI,UAAU,OAAOA,SAAQ,MAAM,CAAC;AACpE,YAAIA,SAAQ,OAAQ,aAAY,IAAI,UAAUA,SAAQ,MAAM;AAC5D,YAAIA,SAAQ,KAAM,aAAY,IAAI,QAAQA,SAAQ,IAAI;AACtD,YAAIA,SAAQ,GAAI,aAAY,IAAI,MAAMA,SAAQ,EAAE;AAEhD,cAAM,MAAM,GAAG,OAAO,eAAe,CAAC,sBACpC,YAAY,SAAS,IAAI,IAAI,WAAW,KAAK,EAC/C;AAEA,cAAM,kBAAkB,OAAO,YAAY;AAC3C,cAAM,WAAW,MAAM,MAAM,KAAK;AAAA,UAChC,SAAS,kBAAkB,EAAE,eAAe,gBAAgB,IAAI,CAAC;AAAA,UACjE,aAAa;AAAA,QACf,CAAC;AAED,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAMD,QAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,gBAAM,IAAI,MAAMA,MAAK,SAAS,6BAA6B;AAAA,QAC7D;AAEA,cAAM,OAAO,MAAM,SAAS,KAAK;AAGjC,cAAM,YAAoC;AAAA,UACxC,SAAS;AAAA,UACT,cAAc;AAAA,UACd,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAGA,eAAO;AAAA,UACL,OAAO,KAAK,QAAQ;AAAA,YAClB,CAAC,YAKM;AAAA,cACL,SAAS,OAAO;AAAA;AAAA,cAChB,QAAQ,UAAU,OAAO,MAAM,KAAK;AAAA,cACpC,UAAU,OAAO,kBACb,CAAC,EAAE,iBAAiB,OAAO,gBAAgB,CAAC,IAC5C,CAAC;AAAA,cACL,SAAS,KAAK,OAAO,YAAY,SAAS,EAAE,CAAC;AAAA,YAC/C;AAAA,UACF;AAAA,UACA,OAAO,KAAK;AAAA,UACZ,SAAS,KAAK;AAAA,QAChB;AAAA,MACF;AAAA,MACA;AACE,cAAM,IAAI,MAAM,uBAAuB,MAAM,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,GAAG,OAAO,UAAU;AAClB,YAAM,MAAM,UAAU,IAAI,KAAK,KAAK,oBAAI,IAAI;AAC5C,UAAI,IAAI,QAAQ;AAChB,gBAAU,IAAI,OAAO,GAAG;AAAA,IAC1B;AAAA,IACA,eAAe,OAAO,UAAU;AAC9B,YAAM,MAAM,UAAU,IAAI,KAAK;AAC/B,UAAI,CAAC,IAAK;AACV,UAAI,OAAO,QAAQ;AACnB,UAAI,IAAI,SAAS,EAAG,WAAU,OAAO,KAAK;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["balances","result","next","prepareResult","signingResult","dialogOrigin","closeOn","successStatuses","dialog","iframe","request","chainId","data","options"]}