{"version":3,"file":"index.cjs","names":["cause?: unknown","data: unknown","response: Response","refreshPromise: Promise<Tokens> | null","subscribers: ((tokens: Tokens) => void)[]","newTokens: Tokens","fullConfig: Required<ManagementApiClientConfig>","url: URL","response: Response","error"],"sources":["../src/errors.ts","../src/auth.ts","../src/index.ts"],"sourcesContent":["/**\n * Error thrown when a network request fails.\n */\nexport class FetchError extends Error {\n  constructor(\n    message: string,\n    /** The underlying error that caused the fetch to fail. */\n    public override readonly cause?: unknown,\n  ) {\n    super(message)\n    this.name = 'FetchError'\n  }\n}\n\n/**\n * Error thrown when authentication fails.\n */\nexport class AuthError extends Error {\n  constructor(\n    message: string,\n    /** Whether the refresh token is invalid/expired and the user needs to re-authenticate. */\n    public readonly refreshTokenInvalid = false,\n  ) {\n    super(message)\n    this.name = 'AuthError'\n  }\n}\n","import { AuthError, FetchError } from './errors'\nimport type { ManagementApiClientConfig, Tokens } from './index'\n\n// JWT utilities\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> {\n  const parts = token.split('.')\n  const payload = parts[1]\n  if (parts.length !== 3 || payload === undefined) {\n    throw new Error('Invalid JWT format')\n  }\n  // Base64url decode: replace URL-safe chars and add padding\n  const base64 = payload.replace(/-/g, '+').replace(/_/g, '/')\n  const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4)\n  const decoded = atob(padded)\n  return JSON.parse(decoded) as Record<string, unknown>\n}\n\nexport function extractWorkspaceId(accessToken: string): string {\n  const payload = decodeJwtPayload(accessToken)\n  const workspaceId = payload['workspace_id']\n  if (typeof workspaceId !== 'string') {\n    throw new Error('workspace_id not found in access token')\n  }\n  return workspaceId\n}\n\n// PKCE utilities\n\nfunction base64urlEncode(buffer: Uint8Array): string {\n  const bytes = Array.from(buffer)\n  const base64 = btoa(String.fromCharCode(...bytes))\n  return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\nexport function generateRandomString(length: number): string {\n  const array = new Uint8Array(length)\n  crypto.getRandomValues(array)\n  return base64urlEncode(array)\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n  const encoder = new TextEncoder()\n  const data = encoder.encode(verifier)\n  const hash = await crypto.subtle.digest('SHA-256', data)\n  return base64urlEncode(new Uint8Array(hash))\n}\n\n// Token exchange utilities\n\nexport function tokenUrl(config: Required<Pick<ManagementApiClientConfig, 'authBaseUrl'>>): string {\n  return `${config.authBaseUrl}/token`\n}\n\nexport type TokenResponse =\n  | { status: 'success'; accessToken: string; refreshToken: string }\n  | { status: 'error'; error: string; refreshTokenInvalid: boolean }\n\nfunction formatOAuthError(data: unknown): string {\n  if (typeof data === 'object' && data !== null) {\n    const errorData = data as Record<string, unknown>\n    const error = errorData['error']\n    const description = errorData['error_description']\n    if (typeof error === 'string') {\n      return typeof description === 'string' ? `${error}: ${description}` : error\n    }\n  }\n  return 'Unknown error'\n}\n\nexport async function parseTokenResponse(response: Response): Promise<TokenResponse> {\n  let data: unknown\n  try {\n    data = await response.json()\n  } catch {\n    return {\n      status: 'error',\n      error: `Failed to parse token response (status ${response.status})`,\n      refreshTokenInvalid: false,\n    }\n  }\n\n  if (response.status >= 400 && response.status < 500) {\n    const errorMessage = formatOAuthError(data)\n    // invalid_grant typically means the refresh token is expired or revoked\n    const isInvalidGrant =\n      typeof data === 'object' &&\n      data !== null &&\n      (data as Record<string, unknown>)['error'] === 'invalid_grant'\n    return {\n      status: 'error',\n      error: errorMessage,\n      refreshTokenInvalid: isInvalidGrant,\n    }\n  }\n\n  if (response.status !== 200) {\n    return {\n      status: 'error',\n      error: `Token request failed with status ${response.status}`,\n      refreshTokenInvalid: false,\n    }\n  }\n\n  if (\n    typeof data !== 'object' ||\n    !data ||\n    typeof (data as Record<string, unknown>)['access_token'] !== 'string' ||\n    typeof (data as Record<string, unknown>)['refresh_token'] !== 'string'\n  ) {\n    return {\n      status: 'error',\n      error: 'Invalid token response format',\n      refreshTokenInvalid: false,\n    }\n  }\n\n  const tokenData = data as { access_token: string; refresh_token: string }\n  return {\n    status: 'success',\n    accessToken: tokenData.access_token,\n    refreshToken: tokenData.refresh_token,\n  }\n}\n\nexport async function refreshAccessToken(\n  config: Required<Pick<ManagementApiClientConfig, 'clientId' | 'authBaseUrl'>>,\n  refreshToken: string,\n): Promise<TokenResponse> {\n  const body = new URLSearchParams({\n    grant_type: 'refresh_token',\n    refresh_token: refreshToken,\n    client_id: config.clientId,\n  })\n\n  let response: Response\n  try {\n    response = await fetch(tokenUrl(config), {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n      body,\n    })\n  } catch {\n    return {\n      status: 'error',\n      error: 'Network error during token refresh',\n      refreshTokenInvalid: false,\n    }\n  }\n\n  return parseTokenResponse(response)\n}\n\nexport function createTokenRefreshingFetch(config: Required<ManagementApiClientConfig>) {\n  let refreshPromise: Promise<Tokens> | null = null\n  const subscribers: ((tokens: Tokens) => void)[] = []\n\n  const doRefresh = async (): Promise<Tokens> => {\n    const currentTokens = await config.tokenStorage.getTokens()\n    if (!currentTokens) {\n      throw new AuthError('No tokens available. Please log in first.')\n    }\n\n    if (!currentTokens.refreshToken) {\n      throw new AuthError('No refresh token available. Please log in again.')\n    }\n\n    const result = await refreshAccessToken(config, currentTokens.refreshToken)\n\n    if (result.status === 'error') {\n      if (result.refreshTokenInvalid) {\n        await config.tokenStorage.clearTokens()\n      }\n      throw new AuthError(result.error, result.refreshTokenInvalid)\n    }\n\n    const newTokens: Tokens = {\n      accessToken: result.accessToken,\n      refreshToken: result.refreshToken,\n      workspaceId: extractWorkspaceId(result.accessToken),\n    }\n    await config.tokenStorage.setTokens(newTokens)\n\n    subscribers.forEach((cb) => cb(newTokens))\n    subscribers.length = 0\n\n    return newTokens\n  }\n\n  const refreshTokens = async (): Promise<Tokens> => {\n    if (refreshPromise) {\n      return new Promise((resolve) => subscribers.push(resolve))\n    }\n\n    refreshPromise = doRefresh().finally(() => {\n      refreshPromise = null\n    })\n\n    return refreshPromise\n  }\n\n  return async function tokenRefreshingFetch(request: globalThis.Request): Promise<Response> {\n    const tokens = await config.tokenStorage.getTokens()\n    if (!tokens) {\n      throw new AuthError('No tokens available. Please log in first.')\n    }\n\n    const requestCloneForRetry = request.clone()\n    request.headers.set('Authorization', `Bearer ${tokens.accessToken}`)\n\n    let response: Response\n    try {\n      response = await fetch(request)\n    } catch (error) {\n      throw new FetchError('Network request failed', error)\n    }\n\n    if (response.status === 401) {\n      const newTokens = await refreshTokens()\n      requestCloneForRetry.headers.set('Authorization', `Bearer ${newTokens.accessToken}`)\n      try {\n        response = await fetch(requestCloneForRetry)\n      } catch (error) {\n        throw new FetchError('Network request failed after token refresh', error)\n      }\n    }\n\n    return response\n  }\n}\n","import type { paths } from './api'\nimport {\n  createTokenRefreshingFetch,\n  extractWorkspaceId,\n  generateCodeChallenge,\n  generateRandomString,\n  parseTokenResponse,\n  tokenUrl,\n} from './auth'\nimport { AuthError, FetchError } from './errors'\nimport type { ClientOptions } from 'openapi-fetch'\nimport createOpenAPIClient from 'openapi-fetch'\n\nexport type * from './api'\nexport { AuthError, FetchError } from './errors'\n\nconst DEFAULT_API_BASE_URL = 'https://api.prisma.io'\nconst DEFAULT_AUTH_BASE_URL = 'https://auth.prisma.io'\n\n// ============================================================================\n// Public Types\n// ============================================================================\n\nexport type Tokens = {\n  /*\n   * This is the workspace ID of the workspace that the tokens are valid for.\n   * It is extracted from the access token payload.\n   */\n  workspaceId: string\n  /*\n   * This is the access token that can be used to make requests to the API.\n   */\n  accessToken: string\n  /*\n   * This is the refresh token that can be used to refresh the access token.\n   * Only present if the scope includes 'offline_access'.\n   */\n  refreshToken?: string\n}\n\n/**\n * Implement this interface to store and retrieve tokens from your environment.\n */\nexport interface TokenStorage {\n  /*\n   * Implement this method to provide the tokens to the SDK.\n   */\n  getTokens(): Promise<Tokens | null>\n  /*\n   * Implement this method to store new or updated tokens when the SDK has successfully authenticated or refreshed tokens.\n   */\n  setTokens(tokens: Tokens): Promise<void>\n  /*\n   * Implement this method to clear the tokens when the user logs out or the refresh token is invalid..\n   */\n  clearTokens(): Promise<void>\n}\n\n/**\n * Configuration options for creating a Management API instance.\n */\nexport type ManagementApiClientConfig = {\n  /** The OAuth client ID for authentication. */\n  clientId: string\n  /** The URI to redirect to after OAuth authentication. */\n  redirectUri: string\n  /** Implementation for storing and retrieving tokens. */\n  tokenStorage: TokenStorage\n  /** Base URL for API requests. Defaults to 'https://api.prisma.io'. */\n  apiBaseUrl?: string\n  /** Base URL for authentication requests. Defaults to 'https://auth.prisma.io'. */\n  authBaseUrl?: string\n}\n\n/**\n * Options for generating an OAuth login URL.\n */\nexport type LoginUrlOptions = {\n  /** The OAuth scopes to request (e.g., 'workspace:admin offline_access'). */\n  scope: string\n  /** Additional query parameters to include in the authorization URL (e.g. UTM parameters). */\n  additionalParams?: Record<string, string>\n}\n\n/**\n * A typed API client for making requests to the Management API.\n */\nexport type ManagementApiClient = ReturnType<typeof createOpenAPIClient<paths>>\n\n/**\n * Result from generating an OAuth login URL.\n */\nexport type LoginResult = {\n  /** The authorization URL to redirect the user to. */\n  url: string\n  /** The state parameter for CSRF protection. Must be stored and verified in the callback. */\n  state: string\n  /** The PKCE code verifier. Must be stored and provided when handling the callback. */\n  verifier: string\n}\n\n/**\n * Options for handling the OAuth callback after user authentication.\n */\nexport type HandleCallbackOptions = {\n  /** The full callback URL including query parameters. */\n  callbackUrl: string | URL\n  /** The PKCE code verifier that was generated with the login URL. */\n  verifier: string\n  /** The state parameter that was generated with the login URL, used for CSRF protection. */\n  expectedState: string\n}\n\n/**\n * The Management API SDK instance with authentication handling.\n */\nexport type ManagementApiSdk = {\n  /** The typed API client for making requests. */\n  client: ManagementApiClient\n  /** Generate an OAuth login URL with PKCE. */\n  getLoginUrl(options: LoginUrlOptions): Promise<LoginResult>\n  /** Handle the OAuth callback, exchange the code for tokens, and store them. */\n  handleCallback(options: HandleCallbackOptions): Promise<void>\n  /** Clear stored tokens and log out. */\n  logout(): Promise<void>\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Creates a raw API client without authentication handling.\n * Useful if you want to manage authentication yourself.\n */\nexport function createManagementApiClient(options: ClientOptions & { token?: string }): ManagementApiClient {\n  const clientOptions = {\n    ...options,\n    baseUrl: options.baseUrl ?? DEFAULT_API_BASE_URL,\n    headers: {\n      ...options.headers,\n      Authorization: options.token ? `Bearer ${options.token}` : undefined,\n    },\n  }\n  delete clientOptions.token\n  return createOpenAPIClient<paths>(clientOptions)\n}\n\n/**\n * Creates a Management API instance with OAuth authentication and automatic token refresh.\n */\nexport function createManagementApiSdk(config: ManagementApiClientConfig): ManagementApiSdk {\n  const fullConfig: Required<ManagementApiClientConfig> = {\n    apiBaseUrl: config.apiBaseUrl ?? DEFAULT_API_BASE_URL,\n    authBaseUrl: config.authBaseUrl ?? DEFAULT_AUTH_BASE_URL,\n    ...config,\n  }\n\n  const client = createManagementApiClient({\n    baseUrl: fullConfig.apiBaseUrl,\n    fetch: createTokenRefreshingFetch(fullConfig),\n  })\n\n  client.use({\n    onError({ error }) {\n      if (error instanceof FetchError || error instanceof AuthError) {\n        return error\n      }\n      return new FetchError('API request failed', error)\n    },\n  })\n\n  async function getLoginUrl(options: LoginUrlOptions): Promise<LoginResult> {\n    const state = generateRandomString(16)\n    const verifier = generateRandomString(32)\n    const challenge = await generateCodeChallenge(verifier)\n\n    const authUrl = new URL(`${fullConfig.authBaseUrl}/authorize`)\n    authUrl.searchParams.set('response_type', 'code')\n    authUrl.searchParams.set('client_id', fullConfig.clientId)\n    authUrl.searchParams.set('redirect_uri', fullConfig.redirectUri)\n    authUrl.searchParams.set('scope', options.scope)\n    authUrl.searchParams.set('state', state)\n    authUrl.searchParams.set('code_challenge', challenge)\n    authUrl.searchParams.set('code_challenge_method', 'S256')\n\n    if (options.additionalParams) {\n      for (const [key, value] of Object.entries(options.additionalParams)) {\n        authUrl.searchParams.set(key, value)\n      }\n    }\n\n    return { url: authUrl.toString(), state, verifier }\n  }\n\n  async function handleCallback(options: HandleCallbackOptions): Promise<void> {\n    let url: URL\n    try {\n      url = typeof options.callbackUrl === 'string' ? new URL(options.callbackUrl) : options.callbackUrl\n    } catch {\n      throw new AuthError('Invalid callback URL')\n    }\n    const params = url.searchParams\n\n    const error = params.get('error')\n    if (error) {\n      const errorDescription = params.get('error_description')\n      throw new AuthError(errorDescription ? `${error}: ${errorDescription}` : error)\n    }\n\n    const code = params.get('code')\n    const state = params.get('state')\n\n    if (!code) {\n      throw new AuthError('No authorization code found in callback URL')\n    }\n\n    if (state !== options.expectedState) {\n      throw new AuthError('Invalid state parameter. Possible CSRF attack.')\n    }\n\n    const body = new URLSearchParams({\n      grant_type: 'authorization_code',\n      code,\n      redirect_uri: fullConfig.redirectUri,\n      client_id: fullConfig.clientId,\n      code_verifier: options.verifier,\n    })\n\n    let response: Response\n    try {\n      response = await fetch(tokenUrl(fullConfig), {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n        body,\n      })\n    } catch (error) {\n      throw new FetchError('Network error during token exchange', error)\n    }\n\n    const result = await parseTokenResponse(response)\n\n    if (result.status === 'error') {\n      throw new AuthError(result.error)\n    }\n\n    await fullConfig.tokenStorage.setTokens({\n      accessToken: result.accessToken,\n      refreshToken: result.refreshToken,\n      workspaceId: extractWorkspaceId(result.accessToken),\n    })\n  }\n\n  async function logout(): Promise<void> {\n    await fullConfig.tokenStorage.clearTokens()\n  }\n\n  return {\n    client,\n    getLoginUrl,\n    handleCallback,\n    logout,\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,IAAa,aAAb,cAAgC,MAAM;CACpC,YACE,SAEA,AAAyBA,OACzB;AACA,QAAM,QAAQ;EAFW;AAGzB,OAAK,OAAO;;;;;;AAOhB,IAAa,YAAb,cAA+B,MAAM;CACnC,YACE,SAEA,AAAgB,sBAAsB,OACtC;AACA,QAAM,QAAQ;EAFE;AAGhB,OAAK,OAAO;;;;;;ACnBhB,SAAS,iBAAiB,OAAwC;CAChE,MAAM,QAAQ,MAAM,MAAM,IAAI;CAC9B,MAAM,UAAU,MAAM;AACtB,KAAI,MAAM,WAAW,KAAK,YAAY,OACpC,OAAM,IAAI,MAAM,qBAAqB;CAGvC,MAAM,SAAS,QAAQ,QAAQ,MAAM,IAAI,CAAC,QAAQ,MAAM,IAAI;CAC5D,MAAM,SAAS,SAAS,IAAI,QAAQ,IAAK,OAAO,SAAS,KAAM,EAAE;CACjE,MAAM,UAAU,KAAK,OAAO;AAC5B,QAAO,KAAK,MAAM,QAAQ;;AAG5B,SAAgB,mBAAmB,aAA6B;CAE9D,MAAM,cADU,iBAAiB,YAAY,CACjB;AAC5B,KAAI,OAAO,gBAAgB,SACzB,OAAM,IAAI,MAAM,yCAAyC;AAE3D,QAAO;;AAKT,SAAS,gBAAgB,QAA4B;CACnD,MAAM,QAAQ,MAAM,KAAK,OAAO;AAEhC,QADe,KAAK,OAAO,aAAa,GAAG,MAAM,CAAC,CACpC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;;AAG1E,SAAgB,qBAAqB,QAAwB;CAC3D,MAAM,QAAQ,IAAI,WAAW,OAAO;AACpC,QAAO,gBAAgB,MAAM;AAC7B,QAAO,gBAAgB,MAAM;;AAG/B,eAAsB,sBAAsB,UAAmC;CAE7E,MAAM,OADU,IAAI,aAAa,CACZ,OAAO,SAAS;CACrC,MAAM,OAAO,MAAM,OAAO,OAAO,OAAO,WAAW,KAAK;AACxD,QAAO,gBAAgB,IAAI,WAAW,KAAK,CAAC;;AAK9C,SAAgB,SAAS,QAA0E;AACjG,QAAO,GAAG,OAAO,YAAY;;AAO/B,SAAS,iBAAiB,MAAuB;AAC/C,KAAI,OAAO,SAAS,YAAY,SAAS,MAAM;EAC7C,MAAM,YAAY;EAClB,MAAM,QAAQ,UAAU;EACxB,MAAM,cAAc,UAAU;AAC9B,MAAI,OAAO,UAAU,SACnB,QAAO,OAAO,gBAAgB,WAAW,GAAG,MAAM,IAAI,gBAAgB;;AAG1E,QAAO;;AAGT,eAAsB,mBAAmB,UAA4C;CACnF,IAAIC;AACJ,KAAI;AACF,SAAO,MAAM,SAAS,MAAM;SACtB;AACN,SAAO;GACL,QAAQ;GACR,OAAO,0CAA0C,SAAS,OAAO;GACjE,qBAAqB;GACtB;;AAGH,KAAI,SAAS,UAAU,OAAO,SAAS,SAAS,IAO9C,QAAO;EACL,QAAQ;EACR,OARmB,iBAAiB,KAAK;EASzC,qBANA,OAAO,SAAS,YAChB,SAAS,QACR,KAAiC,aAAa;EAKhD;AAGH,KAAI,SAAS,WAAW,IACtB,QAAO;EACL,QAAQ;EACR,OAAO,oCAAoC,SAAS;EACpD,qBAAqB;EACtB;AAGH,KACE,OAAO,SAAS,YAChB,CAAC,QACD,OAAQ,KAAiC,oBAAoB,YAC7D,OAAQ,KAAiC,qBAAqB,SAE9D,QAAO;EACL,QAAQ;EACR,OAAO;EACP,qBAAqB;EACtB;CAGH,MAAM,YAAY;AAClB,QAAO;EACL,QAAQ;EACR,aAAa,UAAU;EACvB,cAAc,UAAU;EACzB;;AAGH,eAAsB,mBACpB,QACA,cACwB;CACxB,MAAM,OAAO,IAAI,gBAAgB;EAC/B,YAAY;EACZ,eAAe;EACf,WAAW,OAAO;EACnB,CAAC;CAEF,IAAIC;AACJ,KAAI;AACF,aAAW,MAAM,MAAM,SAAS,OAAO,EAAE;GACvC,QAAQ;GACR,SAAS,EAAE,gBAAgB,qCAAqC;GAChE;GACD,CAAC;SACI;AACN,SAAO;GACL,QAAQ;GACR,OAAO;GACP,qBAAqB;GACtB;;AAGH,QAAO,mBAAmB,SAAS;;AAGrC,SAAgB,2BAA2B,QAA6C;CACtF,IAAIC,iBAAyC;CAC7C,MAAMC,cAA4C,EAAE;CAEpD,MAAM,YAAY,YAA6B;EAC7C,MAAM,gBAAgB,MAAM,OAAO,aAAa,WAAW;AAC3D,MAAI,CAAC,cACH,OAAM,IAAI,UAAU,4CAA4C;AAGlE,MAAI,CAAC,cAAc,aACjB,OAAM,IAAI,UAAU,mDAAmD;EAGzE,MAAM,SAAS,MAAM,mBAAmB,QAAQ,cAAc,aAAa;AAE3E,MAAI,OAAO,WAAW,SAAS;AAC7B,OAAI,OAAO,oBACT,OAAM,OAAO,aAAa,aAAa;AAEzC,SAAM,IAAI,UAAU,OAAO,OAAO,OAAO,oBAAoB;;EAG/D,MAAMC,YAAoB;GACxB,aAAa,OAAO;GACpB,cAAc,OAAO;GACrB,aAAa,mBAAmB,OAAO,YAAY;GACpD;AACD,QAAM,OAAO,aAAa,UAAU,UAAU;AAE9C,cAAY,SAAS,OAAO,GAAG,UAAU,CAAC;AAC1C,cAAY,SAAS;AAErB,SAAO;;CAGT,MAAM,gBAAgB,YAA6B;AACjD,MAAI,eACF,QAAO,IAAI,SAAS,YAAY,YAAY,KAAK,QAAQ,CAAC;AAG5D,mBAAiB,WAAW,CAAC,cAAc;AACzC,oBAAiB;IACjB;AAEF,SAAO;;AAGT,QAAO,eAAe,qBAAqB,SAAgD;EACzF,MAAM,SAAS,MAAM,OAAO,aAAa,WAAW;AACpD,MAAI,CAAC,OACH,OAAM,IAAI,UAAU,4CAA4C;EAGlE,MAAM,uBAAuB,QAAQ,OAAO;AAC5C,UAAQ,QAAQ,IAAI,iBAAiB,UAAU,OAAO,cAAc;EAEpE,IAAIH;AACJ,MAAI;AACF,cAAW,MAAM,MAAM,QAAQ;WACxB,OAAO;AACd,SAAM,IAAI,WAAW,0BAA0B,MAAM;;AAGvD,MAAI,SAAS,WAAW,KAAK;GAC3B,MAAM,YAAY,MAAM,eAAe;AACvC,wBAAqB,QAAQ,IAAI,iBAAiB,UAAU,UAAU,cAAc;AACpF,OAAI;AACF,eAAW,MAAM,MAAM,qBAAqB;YACrC,OAAO;AACd,UAAM,IAAI,WAAW,8CAA8C,MAAM;;;AAI7E,SAAO;;;;;;ACnNX,MAAM,uBAAuB;AAC7B,MAAM,wBAAwB;;;;;AAsH9B,SAAgB,0BAA0B,SAAkE;CAC1G,MAAM,gBAAgB;EACpB,GAAG;EACH,SAAS,QAAQ,WAAW;EAC5B,SAAS;GACP,GAAG,QAAQ;GACX,eAAe,QAAQ,QAAQ,UAAU,QAAQ,UAAU;GAC5D;EACF;AACD,QAAO,cAAc;AACrB,mCAAkC,cAAc;;;;;AAMlD,SAAgB,uBAAuB,QAAqD;CAC1F,MAAMI,aAAkD;EACtD,YAAY,OAAO,cAAc;EACjC,aAAa,OAAO,eAAe;EACnC,GAAG;EACJ;CAED,MAAM,SAAS,0BAA0B;EACvC,SAAS,WAAW;EACpB,OAAO,2BAA2B,WAAW;EAC9C,CAAC;AAEF,QAAO,IAAI,EACT,QAAQ,EAAE,SAAS;AACjB,MAAI,iBAAiB,cAAc,iBAAiB,UAClD,QAAO;AAET,SAAO,IAAI,WAAW,sBAAsB,MAAM;IAErD,CAAC;CAEF,eAAe,YAAY,SAAgD;EACzE,MAAM,QAAQ,qBAAqB,GAAG;EACtC,MAAM,WAAW,qBAAqB,GAAG;EACzC,MAAM,YAAY,MAAM,sBAAsB,SAAS;EAEvD,MAAM,UAAU,IAAI,IAAI,GAAG,WAAW,YAAY,YAAY;AAC9D,UAAQ,aAAa,IAAI,iBAAiB,OAAO;AACjD,UAAQ,aAAa,IAAI,aAAa,WAAW,SAAS;AAC1D,UAAQ,aAAa,IAAI,gBAAgB,WAAW,YAAY;AAChE,UAAQ,aAAa,IAAI,SAAS,QAAQ,MAAM;AAChD,UAAQ,aAAa,IAAI,SAAS,MAAM;AACxC,UAAQ,aAAa,IAAI,kBAAkB,UAAU;AACrD,UAAQ,aAAa,IAAI,yBAAyB,OAAO;AAEzD,MAAI,QAAQ,iBACV,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,iBAAiB,CACjE,SAAQ,aAAa,IAAI,KAAK,MAAM;AAIxC,SAAO;GAAE,KAAK,QAAQ,UAAU;GAAE;GAAO;GAAU;;CAGrD,eAAe,eAAe,SAA+C;EAC3E,IAAIC;AACJ,MAAI;AACF,SAAM,OAAO,QAAQ,gBAAgB,WAAW,IAAI,IAAI,QAAQ,YAAY,GAAG,QAAQ;UACjF;AACN,SAAM,IAAI,UAAU,uBAAuB;;EAE7C,MAAM,SAAS,IAAI;EAEnB,MAAM,QAAQ,OAAO,IAAI,QAAQ;AACjC,MAAI,OAAO;GACT,MAAM,mBAAmB,OAAO,IAAI,oBAAoB;AACxD,SAAM,IAAI,UAAU,mBAAmB,GAAG,MAAM,IAAI,qBAAqB,MAAM;;EAGjF,MAAM,OAAO,OAAO,IAAI,OAAO;EAC/B,MAAM,QAAQ,OAAO,IAAI,QAAQ;AAEjC,MAAI,CAAC,KACH,OAAM,IAAI,UAAU,8CAA8C;AAGpE,MAAI,UAAU,QAAQ,cACpB,OAAM,IAAI,UAAU,iDAAiD;EAGvE,MAAM,OAAO,IAAI,gBAAgB;GAC/B,YAAY;GACZ;GACA,cAAc,WAAW;GACzB,WAAW,WAAW;GACtB,eAAe,QAAQ;GACxB,CAAC;EAEF,IAAIC;AACJ,MAAI;AACF,cAAW,MAAM,MAAM,SAAS,WAAW,EAAE;IAC3C,QAAQ;IACR,SAAS,EAAE,gBAAgB,qCAAqC;IAChE;IACD,CAAC;WACKC,SAAO;AACd,SAAM,IAAI,WAAW,uCAAuCA,QAAM;;EAGpE,MAAM,SAAS,MAAM,mBAAmB,SAAS;AAEjD,MAAI,OAAO,WAAW,QACpB,OAAM,IAAI,UAAU,OAAO,MAAM;AAGnC,QAAM,WAAW,aAAa,UAAU;GACtC,aAAa,OAAO;GACpB,cAAc,OAAO;GACrB,aAAa,mBAAmB,OAAO,YAAY;GACpD,CAAC;;CAGJ,eAAe,SAAwB;AACrC,QAAM,WAAW,aAAa,aAAa;;AAG7C,QAAO;EACL;EACA;EACA;EACA;EACD"}