{"version":3,"file":"index.cjs","names":["cookie","Joi","MonoCloudValidationError","MonoCloudOidcClient","MonoCloudValidationError","MonoCloudOPError","MonoCloudTokenError"],"sources":["../src/monocloud-session-service.ts","../src/monocloud-state-service.ts","../src/options/defaults.ts","../src/options/validation.ts","../src/options/get-options.ts","../src/monocloud-node-core-client.ts"],"sourcesContent":["import { serialize } from 'cookie';\nimport { decrypt, encrypt } from '@monocloud/auth-core/utils';\nimport type { MonoCloudSession, MonoCloudUser } from '@monocloud/auth-core';\nimport { now } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase } from './types';\nimport {\n  CookieOptions,\n  IMonoCloudCookieRequest,\n  IMonoCloudCookieResponse,\n  SessionCookieValue,\n} from './types/internal';\n\nconst CHUNK_BYTE_SIZE = 4090;\n\nexport class MonoCloudSessionService {\n  constructor(private readonly options: MonoCloudOptionsBase) {}\n\n  async setSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    session: MonoCloudSession\n  ): Promise<string> {\n    // Generate a session Id\n    const key = crypto.randomUUID();\n\n    // Set the issued and updated time\n    const iat = now();\n    const uat = iat;\n\n    // Calculate the lifetime of the cookie\n    const exp = this.getExpiry(iat, uat);\n\n    // Set the Cookie Value\n    const cookieValue: SessionCookieValue = {\n      key,\n      lifetime: { c: iat, u: uat, e: exp },\n    };\n\n    // Save the Session\n    await this.saveSession(req, res, cookieValue, session);\n\n    // Return the session Id\n    return key;\n  }\n\n  async getSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    shouldResave = true\n  ): Promise<MonoCloudSession | undefined> {\n    // Get the current cookie value\n    const cookieValue = await this.getCookieData(req);\n\n    // Handle no cookie value\n    if (!cookieValue) {\n      await this.deleteAllCookies(req, res);\n      return undefined;\n    }\n\n    // Ensure that the session is valid\n    const isValid = await this.validateSession(req, res, cookieValue);\n\n    // Handle an invalid session\n    if (!isValid) {\n      return undefined;\n    }\n\n    // Get the new expiry for the cookie\n    const uat = now();\n    const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n    // if there is no session store\n    if (!this.options.session.store) {\n      const session: MonoCloudSession = { user: {} as MonoCloudUser };\n\n      // ensure that the cookie has a session\n      if (!cookieValue.session) {\n        return undefined;\n      }\n\n      // create a session object\n      Object.assign(session, JSON.parse(JSON.stringify(cookieValue.session)));\n\n      // Resave the session if the new expiry is different from the old one\n      if (shouldResave && exp !== cookieValue.lifetime.e) {\n        await this.saveSession(\n          req,\n          res,\n          {\n            ...cookieValue,\n            lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n          },\n          session\n        );\n      }\n\n      // return the sesison\n      return session;\n    }\n\n    // Get the session from the store\n    const sessionObj = await this.options.session.store.get(cookieValue.key);\n\n    // if there is no session in the store then delete the cookie\n    if (!sessionObj) {\n      await this.deleteAllCookies(req, res);\n      return undefined;\n    }\n\n    // Get the instance of the session\n    const session: MonoCloudSession = { user: {} as MonoCloudUser };\n    Object.assign(session, JSON.parse(JSON.stringify(sessionObj)));\n\n    // Resave the session if the new expiry is different from the old one\n    if (shouldResave && exp !== cookieValue.lifetime.e) {\n      await this.saveSession(\n        req,\n        res,\n        {\n          ...cookieValue,\n          lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n        },\n        session\n      );\n    }\n\n    // return the sesison\n    return session;\n  }\n\n  async updateSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    session: MonoCloudSession\n  ): Promise<boolean> {\n    // Get the current cookie value\n    const cookieValue = await this.getCookieData(req);\n\n    // Handle no cookie value\n    if (!cookieValue) {\n      await this.deleteAllCookies(req, res);\n      return false;\n    }\n\n    // Ensure that the session is valid\n    const isValid = await this.validateSession(req, res, cookieValue);\n\n    // Handle an invalid session\n    if (!isValid) {\n      return false;\n    }\n\n    // Get the new expiry for the cookie\n    const uat = now();\n    const exp = this.getExpiry(cookieValue.lifetime.c, uat);\n\n    // Save the session\n    await this.saveSession(\n      req,\n      res,\n      {\n        ...cookieValue,\n        lifetime: { c: cookieValue.lifetime.c, u: uat, e: exp },\n      },\n      session\n    );\n\n    return true;\n  }\n\n  async removeSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse\n  ): Promise<void> {\n    // Get the current cookie value\n    const cookieValue = await this.getCookieData(req);\n\n    // Handle no cookie value\n    if (!cookieValue) {\n      await this.deleteAllCookies(req, res);\n      return;\n    }\n\n    // If session store is present\n    if (this.options.session.store) {\n      // Delete the current session from the store\n      /* v8 ignore else -- @preserve */\n      if (cookieValue.key) {\n        await this.options.session.store.delete(cookieValue.key);\n      }\n    }\n\n    await this.deleteAllCookies(req, res);\n  }\n\n  private async validateSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    cookieValue: SessionCookieValue\n  ): Promise<boolean> {\n    // Get the current time\n    const nowTime = now();\n\n    let isValid = true;\n\n    // Ensure that the expiration has not passed\n    if (cookieValue.lifetime.e && cookieValue.lifetime.e < nowTime) {\n      isValid = false;\n    }\n\n    // If the session is sliding then ensure that the session has not expired based on the last updated time\n    if (\n      this.options.session.sliding &&\n      cookieValue.lifetime.u + this.options.session.duration < nowTime\n    ) {\n      isValid = false;\n    }\n\n    // If the session is sliding then ensure that the session has not crossed the maximum duration allowed\n    if (\n      cookieValue.lifetime.c + this.options.session.maximumDuration <\n      nowTime\n    ) {\n      isValid = false;\n    }\n\n    // return Is Valid if all ok\n    if (isValid) {\n      return true;\n    }\n\n    // If there is a session store then delete the session from the store\n    if (this.options.session.store) {\n      await this.options.session.store.delete(cookieValue.key);\n    }\n\n    await this.deleteAllCookies(req, res);\n\n    return false;\n  }\n\n  private async saveSession(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    cookieValue: SessionCookieValue,\n    session: MonoCloudSession\n  ): Promise<void> {\n    const cookies = new Set((await this.getRequestCookie(req))?.keys ?? []);\n\n    // If no session store is present\n    if (!this.options.session.store) {\n      // Set the cookie session Value\n      // eslint-disable-next-line no-param-reassign\n      cookieValue.session = session;\n    }\n\n    // If session store is present\n    if (this.options.session.store) {\n      // Get the cookie containing the session Id\n      const cookieData = await this.getCookieData(req);\n\n      // Delete the current session from the store\n      if (cookieData?.key) {\n        await this.options.session.store.delete(cookieData.key);\n      }\n\n      // Ensure there is no session in the cookie value\n      // eslint-disable-next-line no-param-reassign\n      cookieValue.session = undefined;\n\n      // Set the new session in the store\n      await this.options.session.store.set(\n        cookieValue.key,\n        session,\n        cookieValue.lifetime\n      );\n    }\n\n    // Encrypt the cookie value\n    const encryptedData = await encrypt(\n      JSON.stringify(cookieValue),\n      this.options.cookieSecret\n    );\n\n    const cookieExpiry = cookieValue.lifetime.e\n      ? new Date(cookieValue.lifetime.e * 1000)\n      : undefined;\n\n    const cookieOptions = this.getCookieOptions(cookieExpiry);\n    const chunkSize =\n      CHUNK_BYTE_SIZE -\n      serialize(`${this.options.session.cookie.name}.0`, '', cookieOptions)\n        .length;\n\n    // Calculate the number of cookie chunks\n    const chunks = Math.ceil(encryptedData.length / chunkSize);\n\n    for (let i = 0; i < chunks; i += 1) {\n      const encryptedChunk = encryptedData.slice(\n        i * chunkSize,\n        (i + 1) * chunkSize\n      );\n\n      const cookieName =\n        chunks === 1\n          ? this.options.session.cookie.name\n          : `${this.options.session.cookie.name}.${i}`;\n\n      await res.setCookie(\n        cookieName,\n        encryptedChunk,\n        this.getCookieOptions(cookieExpiry)\n      );\n\n      cookies.delete(cookieName);\n    }\n\n    // Delete all cookies which are not required anymore\n    for (const cookie of cookies) {\n      await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n    }\n  }\n\n  private async getCookieData(\n    req: IMonoCloudCookieRequest\n  ): Promise<SessionCookieValue | undefined> {\n    // Get all the cookies\n    const cookieData = await this.getRequestCookie(req);\n\n    // Handle no cookies\n    if (!cookieData?.value) {\n      return undefined;\n    }\n\n    // Decrypt the cookie\n    const data = await decrypt(cookieData.value, this.options.cookieSecret);\n\n    // Handle no data\n    if (!data) {\n      return undefined;\n    }\n\n    // Return the parsed session cookie value\n    return JSON.parse(data);\n  }\n\n  private async getRequestCookie(\n    req: IMonoCloudCookieRequest\n  ): Promise<{ keys: string[]; value: string } | undefined> {\n    // Get all the cookies\n    const cookies = await req.getAllCookies();\n\n    // Handle no cookies\n    if (!cookies.size) {\n      return undefined;\n    }\n\n    // If a cookie exists without chunks then return it\n    const val = cookies.get(this.options.session.cookie.name);\n\n    if (val) {\n      return { keys: [this.options.session.cookie.name], value: val };\n    }\n\n    // Filter out the cookies and only keep the relevant ones\n    const cookieValues = Array.from(cookies.entries())\n      .filter(([cookie]) =>\n        cookie.startsWith(`${this.options.session.cookie.name}.`)\n      )\n      .map(([cookie, value]) => ({\n        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        key: parseInt(cookie.split('.').pop() || '0', 10),\n        value,\n      }))\n      .sort((a, b) => a.key - b.key);\n\n    // Sort the cookies by chunk numbers\n    const cookieValue = cookieValues.map(({ value }) => value).join('');\n\n    // Handle empty cookie value\n    if (!cookieValue) {\n      return undefined;\n    }\n\n    // Return the cookie names and values\n    return {\n      keys: cookieValues.map(\n        ({ key }) => `${this.options.session.cookie.name}.${key}`\n      ),\n      value: cookieValue,\n    };\n  }\n\n  private getExpiry(iat: number, uat: number): number | undefined {\n    // Return null if session is not persistent\n    if (!this.options.session.cookie.persistent) {\n      return undefined;\n    }\n\n    // If session is not sliding the return the absolute expiration\n    if (!this.options.session.sliding) {\n      return Math.floor(iat + this.options.session.duration);\n    }\n\n    // If session is sliding then return the lesser of the next extended time or the maximum duration\n    return Math.floor(\n      Math.min(\n        uat + this.options.session.duration,\n        iat + this.options.session.maximumDuration\n      )\n    );\n  }\n\n  private getCookieOptions(exp?: Date): CookieOptions {\n    return {\n      domain: this.options.session.cookie.domain,\n      httpOnly: this.options.session.cookie.httpOnly,\n      sameSite: this.options.session.cookie.sameSite,\n      secure: this.options.session.cookie.secure,\n      path: this.options.session.cookie.path,\n      expires: exp,\n    };\n  }\n\n  private async deleteAllCookies(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse\n  ): Promise<void> {\n    const reqCookie = await this.getRequestCookie(req);\n\n    const cookies = reqCookie?.keys?.filter(x =>\n      x.startsWith(this.options.session.cookie.name)\n    );\n\n    for (const cookie of cookies ?? []) {\n      await res.setCookie(cookie, '', this.getCookieOptions(new Date(0)));\n    }\n  }\n}\n","import { decryptAuthState, encryptAuthState } from '@monocloud/auth-core/utils';\nimport { sha256 } from '@monocloud/auth-core/internal';\nimport { MonoCloudOptionsBase, MonoCloudState, SameSiteValues } from './types';\nimport {\n  CookieOptions,\n  IMonoCloudCookieRequest,\n  IMonoCloudCookieResponse,\n} from './types/internal';\n\nexport class MonoCloudStateService {\n  constructor(private readonly options: MonoCloudOptionsBase) {}\n\n  async setState(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    state: MonoCloudState,\n    overrideSameSite?: SameSiteValues\n  ): Promise<void> {\n    const cookieName = await this.getCookieName(state.state);\n\n    await this.evictSurplusStates(req, res, cookieName);\n\n    await res.setCookie(\n      cookieName,\n      await encryptAuthState(\n        state,\n        this.options.cookieSecret,\n        this.options.state.duration\n      ),\n      this.getCookieOptions(overrideSameSite)\n    );\n  }\n\n  async getState(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    state: string\n  ): Promise<MonoCloudState | undefined> {\n    const cookieName = await this.getCookieName(state);\n    const cookie = await req.getCookie(cookieName);\n\n    // Handle no cookie\n    if (!cookie) {\n      return undefined;\n    }\n\n    let decryptedResult: MonoCloudState;\n\n    try {\n      // Decrypt the cookie value\n      decryptedResult = await decryptAuthState(\n        cookie,\n        this.options.cookieSecret\n      );\n    } catch {\n      await this.removeCookie(res, cookieName);\n      return undefined;\n    }\n\n    // Remove the cookie\n    await this.removeCookie(res, cookieName);\n\n    // return the state\n    return decryptedResult;\n  }\n\n  async removeAllStates(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse\n  ): Promise<void> {\n    for (const [name] of await this.getStateCookies(req)) {\n      await this.removeCookie(res, name);\n    }\n  }\n\n  private async getCookieName(state: string): Promise<string> {\n    return `${this.options.state.cookie.name}.${await sha256(state)}`;\n  }\n\n  private async getStateCookies(\n    req: IMonoCloudCookieRequest\n  ): Promise<Map<string, string>> {\n    const { name } = this.options.state.cookie;\n\n    const cookies = await req.getAllCookies();\n\n    return new Map(\n      [...cookies].filter(\n        ([cookieName]) =>\n          cookieName === name ||\n          (cookieName.startsWith(`${name}.`) &&\n            /^[\\w-]+$/.test(cookieName.slice(name.length + 1)))\n      )\n    );\n  }\n\n  private async evictSurplusStates(\n    req: IMonoCloudCookieRequest,\n    res: IMonoCloudCookieResponse,\n    cookieName: string\n  ): Promise<void> {\n    const cookies = await this.getStateCookies(req);\n\n    // The cookie is going to be overwritten and does not count towards the limit.\n    cookies.delete(cookieName);\n\n    await this.pruneStates(res, cookies, this.options.state.maxConcurrent - 1);\n  }\n\n  /**\n   * Retains the latest usable transactions, up to the specified capacity.\n   */\n  private async pruneStates(\n    res: IMonoCloudCookieResponse,\n    cookies: Map<string, string>,\n    capacity: number\n  ): Promise<void> {\n    const names = [...cookies.keys()];\n\n    const surplus = Math.max(names.length - capacity, 0);\n\n    for (const name of names.slice(0, surplus)) {\n      await this.removeCookie(res, name);\n    }\n\n    for (const name of names.slice(surplus)) {\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      if (!(await this.isUsable(cookies.get(name)!))) {\n        await this.removeCookie(res, name);\n      }\n    }\n  }\n\n  private async isUsable(value: string): Promise<boolean> {\n    try {\n      await decryptAuthState(value, this.options.cookieSecret);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  private async removeCookie(\n    res: IMonoCloudCookieResponse,\n    name: string\n  ): Promise<void> {\n    await res.setCookie(name, '', {\n      ...this.getCookieOptions(),\n      maxAge: undefined,\n      expires: new Date(0),\n    });\n  }\n\n  private getCookieOptions(sameSite?: SameSiteValues): CookieOptions {\n    return {\n      domain: this.options.state.cookie.domain,\n      httpOnly: this.options.state.cookie.httpOnly,\n      sameSite: sameSite ?? this.options.state.cookie.sameSite,\n      secure: this.options.state.cookie.secure,\n      path: this.options.state.cookie.path,\n      maxAge: this.options.state.duration,\n    };\n  }\n}\n","export const DEFAULT_OPTIONS = {\n  routes: {\n    callback: '/api/auth/callback',\n    backChannelLogout: '/api/auth/backchannel-logout',\n    signIn: '/api/auth/signin',\n    signOut: '/api/auth/signout',\n    userInfo: '/api/auth/userinfo',\n  },\n  clockSkew: 0,\n  clockTolerance: 60,\n  responseTimeout: 10000,\n  usePar: false,\n  fetchUserInfo: true,\n  refetchUserInfo: false,\n  federatedSignOut: true,\n  defaultAuthParams: {\n    scopes: 'openid profile email',\n    responseType: 'code',\n  },\n  allowQueryParamOverrides: true,\n  strictProfileSync: false,\n  groupsClaim: 'groups',\n  session: {\n    cookie: {\n      httpOnly: true,\n      name: 'session',\n      path: '/',\n      sameSite: 'lax',\n      persistent: true,\n    },\n    sliding: false,\n    duration: 24 * 60 * 60,\n    maximumDuration: 7 * 24 * 60 * 60,\n  },\n  state: {\n    cookie: {\n      httpOnly: true,\n      name: 'state',\n      path: '/',\n      sameSite: 'lax',\n    },\n    duration: 15 * 60,\n    maxConcurrent: 5,\n  },\n  idTokenSigningAlg: 'RS256',\n  clientAuthMethod: 'client_secret_basic',\n  filteredIdTokenClaims: [\n    'iss',\n    'exp',\n    'nbf',\n    'aud',\n    'nonce',\n    'iat',\n    'auth_time',\n    'c_hash',\n    'at_hash',\n    's_hash',\n  ],\n  debugger: 'node-auth-core',\n  userAgent: 'node-auth-core',\n};\n","import Joi from 'joi';\nimport type {\n  AuthorizationParams,\n  ClientAuthMethod,\n} from '@monocloud/auth-core';\nimport {\n  CallbackOptions,\n  GetSessionOptions,\n  GetTokensOptions,\n  Indicator,\n  MonoCloudOptionsBase,\n  MonoCloudRoutes,\n  MonoCloudSessionOptionsBase,\n  MonoCloudStateOptions,\n  SignInOptions,\n  SignOutOptions,\n  UserInfoOptions,\n} from '../types';\n\nconst stringRequired = Joi.string().required();\nconst stringOptional = Joi.string().optional();\nconst boolRequired = Joi.boolean().required();\nconst boolOptional = Joi.boolean().optional();\nconst numRequired = Joi.number().required();\nconst numOptional = Joi.number().optional();\nconst objectOptional = Joi.object().optional();\nconst funcOptional = Joi.function().optional();\n\nconst validClientAuthMethods: ClientAuthMethod[] = [\n  'client_secret_basic',\n  'client_secret_post',\n  'client_secret_jwt',\n  'private_key_jwt',\n  'tls_client_auth',\n  'self_signed_tls_client_auth',\n  'spiffe_jwt',\n  'spiffe_x509',\n];\n\nconst cookieSchema = Joi.object({\n  name: stringRequired,\n  path: stringRequired.uri({ relativeOnly: true }),\n  domain: stringOptional,\n  httpOnly: boolRequired,\n  secure: boolRequired.when(Joi.ref('/appUrl'), {\n    is: Joi.string().pattern(/^https:/i),\n    then: Joi.valid(true).messages({\n      'any.only':\n        'Cookie must be set to secure when app url protocol is https.',\n    }),\n    otherwise: Joi.valid(false),\n  }),\n  sameSite: stringRequired.valid('strict', 'lax', 'none'),\n}).required();\n\nconst sessionCookieSchema = cookieSchema.keys({\n  persistent: boolRequired,\n});\n\nconst resourceSchema = stringRequired.custom((value, helpers) => {\n  let valid: boolean;\n  try {\n    const url = new URL(value);\n    valid = url.searchParams.size === 0 && url.hash.length === 0;\n  } catch {\n    valid = false;\n  }\n\n  if (!valid) {\n    return helpers.message({\n      custom: 'Resource must be a valid URL without query or hash parameters',\n    });\n  }\n\n  return value;\n});\n\nexport const resourceValidationSchema = Joi.string()\n  .custom((value, helpers) => {\n    const parts = value\n      .split(/\\s+/)\n      .map((x: string) => x.trim())\n      .filter(Boolean);\n\n    if (parts.length === 0) {\n      return helpers.message({ custom: 'Resource must not be empty' });\n    }\n\n    for (const part of parts) {\n      const { error } = resourceSchema.validate(part);\n      if (error) {\n        return helpers.message({\n          custom: `Invalid resource \"${part}\": ${error.message}`,\n        });\n      }\n    }\n\n    return parts.join(' ');\n  })\n  .messages({\n    'string.base': 'Resource must be a space-separated string of URLs',\n  });\n\nconst sessionSchema: Joi.ObjectSchema<MonoCloudSessionOptionsBase> = Joi.object(\n  {\n    cookie: sessionCookieSchema,\n    sliding: boolRequired,\n    duration: numRequired.min(1),\n    maximumDuration: numRequired.min(1).greater(Joi.ref('duration')),\n    store: objectOptional,\n  }\n).required();\n\nconst stateSchema: Joi.ObjectSchema<MonoCloudStateOptions> = Joi.object({\n  cookie: cookieSchema,\n  duration: numRequired.integer().min(300),\n  maxConcurrent: numRequired.integer().min(1).max(20),\n}).required();\n\nconst scopesSchema = stringRequired\n  .custom((value, helpers) => {\n    const scopes = value\n      .split(/\\s+/)\n      .map((x: string) => x.trim())\n      .filter(Boolean);\n\n    if (scopes.length === 0) {\n      return helpers.message({\n        custom: 'Scopes must be a space-separated string',\n      });\n    }\n\n    if (!scopes.includes('openid')) {\n      return helpers.message({ custom: 'Scope must contain openid' });\n    }\n\n    return scopes.join(' ');\n  })\n  .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nconst authParamSchema: Joi.ObjectSchema<AuthorizationParams> = Joi.object({\n  scopes: scopesSchema,\n  responseType: stringOptional.valid('code').optional(),\n  responseMode: stringOptional.valid('query', 'form_post'),\n  resource: resourceValidationSchema.optional(),\n})\n  .unknown(true)\n  .required();\n\nconst optionalAuthParamSchema: Joi.ObjectSchema<AuthorizationParams> =\n  Joi.object({\n    scopes: scopesSchema,\n    responseType: stringOptional.valid('code').optional(),\n    responseMode: stringOptional.valid('query', 'form_post'),\n  })\n    .unknown(true)\n    .optional();\n\nconst routesSchema: Joi.ObjectSchema<MonoCloudRoutes> = Joi.object({\n  callback: stringRequired.uri({ relativeOnly: true }),\n  backChannelLogout: stringRequired.uri({ relativeOnly: true }),\n  signIn: stringRequired.uri({ relativeOnly: true }),\n  signOut: stringRequired.uri({ relativeOnly: true }),\n  userInfo: stringRequired.uri({ relativeOnly: true }),\n}).required();\n\nexport const scopesValidationSchema = stringRequired\n  .custom((value, helpers) => {\n    const scopes = value\n      .split(/\\s+/)\n      .map((x: string) => x.trim())\n      .filter(Boolean);\n\n    if (scopes.length === 0) {\n      return helpers.message({\n        custom: 'Scopes must be a space-separated string',\n      });\n    }\n\n    return scopes.join(' ');\n  })\n  .messages({ 'string.base': 'Scopes must be a space-separated string' });\n\nexport const indicatorOptionsSchema: Joi.ObjectSchema<Indicator> = Joi.object({\n  resource: resourceValidationSchema,\n  scopes: scopesValidationSchema.optional(),\n});\n\nexport const optionsSchema: Joi.ObjectSchema<MonoCloudOptionsBase> = Joi.object(\n  {\n    clientId: stringRequired,\n    clientSecret: Joi.alternatives().conditional('clientAuthMethod', {\n      is: 'private_key_jwt',\n      then: Joi.object().required().messages({\n        'object.base':\n          \"clientSecret must be a valid JWK when clientAuthMethod is 'private_key_jwt'\",\n      }),\n      otherwise: stringRequired,\n    }),\n    clientAuthMethod: Joi.string().valid(...validClientAuthMethods),\n    trustStoreId: stringOptional,\n    fetcher: funcOptional,\n    metadataResolver: funcOptional,\n    jwksResolver: funcOptional,\n    tenantDomain: stringRequired.uri(),\n    cookieSecret: stringRequired.min(8),\n    appUrl: stringRequired.uri(),\n    routes: routesSchema,\n    clockSkew: numRequired.min(0),\n    clockTolerance: numRequired.min(0),\n    responseTimeout: numRequired.min(1000),\n    usePar: boolRequired,\n    postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n    federatedSignOut: boolRequired,\n    fetchUserInfo: boolRequired,\n    refetchUserInfo: boolRequired,\n    allowQueryParamOverrides: boolRequired,\n    strictProfileSync: boolRequired,\n    defaultAuthParams: authParamSchema,\n    resources: Joi.array<Indicator>().items(indicatorOptionsSchema).optional(),\n    session: sessionSchema,\n    state: stateSchema,\n    idTokenSigningAlg: Joi.string().valid(\n      'RS256',\n      'RS384',\n      'RS512',\n      'PS256',\n      'PS384',\n      'PS512',\n      'ES256',\n      'ES384',\n      'ES512'\n    ),\n    filteredIdTokenClaims: Joi.array<string>().items(stringRequired),\n    groupsClaim: stringRequired,\n    debugger: stringRequired,\n    userAgent: stringRequired,\n    jwksCacheDuration: numOptional,\n    metadataCacheDuration: numOptional,\n    onBackChannelLogout: funcOptional,\n    onSetApplicationState: funcOptional,\n    onSessionCreating: funcOptional,\n  }\n).custom((value, helpers) => {\n  const sessionName = value.session.cookie.name;\n  const stateName = value.state.cookie.name;\n\n  if (stateName === sessionName) {\n    return helpers.message({\n      custom:\n        'The state cookie name must be different from the session cookie name',\n    });\n  }\n\n  if (stateName.startsWith(`${sessionName}.`)) {\n    return helpers.message({\n      custom: `The state cookie name must not start with \"${sessionName}.\" as it would be read as part of the session cookie`,\n    });\n  }\n\n  if (sessionName.startsWith(`${stateName}.`)) {\n    return helpers.message({\n      custom: `The session cookie name must not start with \"${stateName}.\" as it would be discarded as a sign-in transaction`,\n    });\n  }\n\n  return value;\n});\n\nexport const signInOptionsSchema: Joi.ObjectSchema<SignInOptions> = Joi.object({\n  returnUrl: stringOptional.uri({ allowRelative: true }),\n  register: boolOptional,\n  authParams: optionalAuthParamSchema,\n  onError: funcOptional,\n});\n\nexport const callbackOptionsSchema: Joi.ObjectSchema<CallbackOptions> =\n  Joi.object({\n    fetchUserInfo: boolOptional,\n    redirectUri: stringOptional.uri(),\n    onError: funcOptional,\n  });\n\nexport const userInfoOptionsSchema: Joi.ObjectSchema<UserInfoOptions> =\n  Joi.object({\n    refresh: boolOptional,\n    onError: funcOptional,\n  });\n\nexport const signOutOptionsSchema: Joi.ObjectSchema<SignOutOptions> =\n  Joi.object({\n    postLogoutRedirectUri: stringOptional.uri({ allowRelative: true }),\n    idTokenHint: stringOptional,\n    state: stringOptional,\n    federatedSignOut: boolOptional,\n    onError: funcOptional,\n  });\n\nexport const getTokensOptionsSchema: Joi.ObjectSchema<GetTokensOptions> =\n  Joi.object({\n    forceRefresh: boolOptional,\n    refetchUserInfo: boolOptional,\n    resource: resourceValidationSchema.optional(),\n    scopes: scopesValidationSchema.optional(),\n  });\n\nexport const getSessionOptionsSchema: Joi.ObjectSchema<GetSessionOptions> =\n  Joi.object({\n    refetchUserInfo: boolOptional,\n  });\n","/* eslint-disable prefer-destructuring */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport {\n  getBoolean,\n  getNumber,\n  parseClientSecret,\n  removeTrailingSlash,\n} from '@monocloud/auth-core/internal';\nimport {\n  MonoCloudOptions,\n  MonoCloudOptionsBase,\n  SameSiteValues,\n} from '../types';\nimport { DEFAULT_OPTIONS } from './defaults';\nimport { optionsSchema } from './validation';\nimport {\n  ClientAuthMethod,\n  MonoCloudValidationError,\n  SecurityAlgorithms,\n} from '@monocloud/auth-core';\n\nexport const getOptions = (\n  options?: MonoCloudOptions,\n  throwOnError = true\n): MonoCloudOptionsBase => {\n  const MONOCLOUD_AUTH_CLIENT_ID = process.env.MONOCLOUD_AUTH_CLIENT_ID;\n  const MONOCLOUD_AUTH_CLIENT_SECRET = process.env.MONOCLOUD_AUTH_CLIENT_SECRET;\n  const MONOCLOUD_AUTH_CLIENT_AUTH_METHOD =\n    process.env.MONOCLOUD_AUTH_CLIENT_AUTH_METHOD;\n  const MONOCLOUD_AUTH_TRUST_STORE_ID =\n    process.env.MONOCLOUD_AUTH_TRUST_STORE_ID;\n  const MONOCLOUD_AUTH_TENANT_DOMAIN = process.env.MONOCLOUD_AUTH_TENANT_DOMAIN;\n  const MONOCLOUD_AUTH_SCOPES = process.env.MONOCLOUD_AUTH_SCOPES;\n  const MONOCLOUD_AUTH_COOKIE_SECRET = process.env.MONOCLOUD_AUTH_COOKIE_SECRET;\n  const MONOCLOUD_AUTH_APP_URL = process.env.MONOCLOUD_AUTH_APP_URL;\n  const MONOCLOUD_AUTH_CALLBACK_URL = process.env.MONOCLOUD_AUTH_CALLBACK_URL;\n  const MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL =\n    process.env.MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL;\n  const MONOCLOUD_AUTH_SIGNIN_URL = process.env.MONOCLOUD_AUTH_SIGNIN_URL;\n  const MONOCLOUD_AUTH_SIGNOUT_URL = process.env.MONOCLOUD_AUTH_SIGNOUT_URL;\n  const MONOCLOUD_AUTH_USER_INFO_URL = process.env.MONOCLOUD_AUTH_USER_INFO_URL;\n  const MONOCLOUD_AUTH_RESOURCE = process.env.MONOCLOUD_AUTH_RESOURCE;\n  const MONOCLOUD_AUTH_CLOCK_SKEW = process.env.MONOCLOUD_AUTH_CLOCK_SKEW;\n  const MONOCLOUD_AUTH_CLOCK_TOLERANCE =\n    process.env.MONOCLOUD_AUTH_CLOCK_TOLERANCE;\n  const MONOCLOUD_AUTH_RESPONSE_TIMEOUT =\n    process.env.MONOCLOUD_AUTH_RESPONSE_TIMEOUT;\n  const MONOCLOUD_AUTH_USE_PAR = process.env.MONOCLOUD_AUTH_USE_PAR;\n  const MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI =\n    process.env.MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI;\n  const MONOCLOUD_AUTH_FEDERATED_SIGNOUT =\n    process.env.MONOCLOUD_AUTH_FEDERATED_SIGNOUT;\n  const MONOCLOUD_AUTH_FETCH_USER_INFO =\n    process.env.MONOCLOUD_AUTH_FETCH_USER_INFO;\n  const MONOCLOUD_AUTH_REFETCH_USER_INFO =\n    process.env.MONOCLOUD_AUTH_REFETCH_USER_INFO;\n  const MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES =\n    process.env.MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES;\n  const MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC =\n    process.env.MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_NAME =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_NAME;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_PATH =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PATH;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_SECURE =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SECURE;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE;\n  const MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT =\n    process.env.MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT;\n  const MONOCLOUD_AUTH_SESSION_SLIDING =\n    process.env.MONOCLOUD_AUTH_SESSION_SLIDING;\n  const MONOCLOUD_AUTH_SESSION_DURATION =\n    process.env.MONOCLOUD_AUTH_SESSION_DURATION;\n  const MONOCLOUD_AUTH_SESSION_MAX_DURATION =\n    process.env.MONOCLOUD_AUTH_SESSION_MAX_DURATION;\n  const MONOCLOUD_AUTH_STATE_COOKIE_NAME =\n    process.env.MONOCLOUD_AUTH_STATE_COOKIE_NAME;\n  const MONOCLOUD_AUTH_STATE_COOKIE_PATH =\n    process.env.MONOCLOUD_AUTH_STATE_COOKIE_PATH;\n  const MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN =\n    process.env.MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN;\n  const MONOCLOUD_AUTH_STATE_COOKIE_SECURE =\n    process.env.MONOCLOUD_AUTH_STATE_COOKIE_SECURE;\n  const MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE =\n    process.env.MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE;\n  const MONOCLOUD_AUTH_STATE_DURATION =\n    process.env.MONOCLOUD_AUTH_STATE_DURATION;\n  const MONOCLOUD_AUTH_STATE_MAX_CONCURRENT =\n    process.env.MONOCLOUD_AUTH_STATE_MAX_CONCURRENT;\n  const MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG =\n    process.env.MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG;\n  const MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS =\n    process.env.MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS;\n  const MONOCLOUD_AUTH_JWKS_CACHE_DURATION =\n    process.env.MONOCLOUD_AUTH_JWKS_CACHE_DURATION;\n  const MONOCLOUD_AUTH_METADATA_CACHE_DURATION =\n    process.env.MONOCLOUD_AUTH_METADATA_CACHE_DURATION;\n  const MONOCLOUD_AUTH_GROUPS_CLAIM = process.env.MONOCLOUD_AUTH_GROUPS_CLAIM;\n\n  const appUrl = options?.appUrl ?? MONOCLOUD_AUTH_APP_URL!;\n\n  const opt: MonoCloudOptionsBase = {\n    clientId: options?.clientId ?? MONOCLOUD_AUTH_CLIENT_ID!,\n    clientSecret: parseClientSecret(\n      options?.clientSecret ?? MONOCLOUD_AUTH_CLIENT_SECRET\n    ),\n    clientAuthMethod:\n      options?.clientAuthMethod ??\n      (MONOCLOUD_AUTH_CLIENT_AUTH_METHOD as ClientAuthMethod) ??\n      DEFAULT_OPTIONS.clientAuthMethod,\n    trustStoreId: options?.trustStoreId ?? MONOCLOUD_AUTH_TRUST_STORE_ID,\n    fetcher: options?.fetcher,\n    metadataResolver: options?.metadataResolver,\n    jwksResolver: options?.jwksResolver,\n    tenantDomain: options?.tenantDomain ?? MONOCLOUD_AUTH_TENANT_DOMAIN!,\n    defaultAuthParams: {\n      ...(options?.defaultAuthParams ?? {}),\n      scopes:\n        options?.defaultAuthParams?.scopes ??\n        MONOCLOUD_AUTH_SCOPES ??\n        DEFAULT_OPTIONS.defaultAuthParams.scopes,\n      responseType:\n        options?.defaultAuthParams?.responseType ??\n        (DEFAULT_OPTIONS.defaultAuthParams.responseType as any),\n      resource: options?.defaultAuthParams?.resource ?? MONOCLOUD_AUTH_RESOURCE,\n    },\n    resources: options?.resources,\n    cookieSecret: options?.cookieSecret ?? MONOCLOUD_AUTH_COOKIE_SECRET!,\n    appUrl: removeTrailingSlash(appUrl),\n    routes: {\n      callback: removeTrailingSlash(\n        options?.routes?.callback ??\n          MONOCLOUD_AUTH_CALLBACK_URL ??\n          DEFAULT_OPTIONS.routes.callback\n      ),\n      backChannelLogout: removeTrailingSlash(\n        options?.routes?.backChannelLogout ??\n          MONOCLOUD_AUTH_BACK_CHANNEL_LOGOUT_URL ??\n          DEFAULT_OPTIONS.routes.backChannelLogout\n      ),\n      signIn: removeTrailingSlash(\n        options?.routes?.signIn ??\n          MONOCLOUD_AUTH_SIGNIN_URL ??\n          DEFAULT_OPTIONS.routes.signIn\n      ),\n      signOut: removeTrailingSlash(\n        options?.routes?.signOut ??\n          MONOCLOUD_AUTH_SIGNOUT_URL ??\n          DEFAULT_OPTIONS.routes.signOut\n      ),\n      userInfo: removeTrailingSlash(\n        options?.routes?.userInfo ??\n          MONOCLOUD_AUTH_USER_INFO_URL ??\n          DEFAULT_OPTIONS.routes.userInfo\n      ),\n    },\n    clockSkew:\n      options?.clockSkew ??\n      getNumber(MONOCLOUD_AUTH_CLOCK_SKEW) ??\n      DEFAULT_OPTIONS.clockSkew,\n    clockTolerance:\n      options?.clockTolerance ??\n      getNumber(MONOCLOUD_AUTH_CLOCK_TOLERANCE) ??\n      DEFAULT_OPTIONS.clockTolerance,\n    responseTimeout:\n      options?.responseTimeout ??\n      getNumber(MONOCLOUD_AUTH_RESPONSE_TIMEOUT) ??\n      DEFAULT_OPTIONS.responseTimeout,\n    usePar:\n      options?.usePar ??\n      getBoolean(MONOCLOUD_AUTH_USE_PAR) ??\n      DEFAULT_OPTIONS.usePar,\n    postLogoutRedirectUri:\n      options?.postLogoutRedirectUri ?? MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI,\n    federatedSignOut:\n      options?.federatedSignOut ??\n      getBoolean(MONOCLOUD_AUTH_FEDERATED_SIGNOUT) ??\n      DEFAULT_OPTIONS.federatedSignOut,\n    fetchUserInfo:\n      options?.fetchUserInfo ??\n      getBoolean(MONOCLOUD_AUTH_FETCH_USER_INFO) ??\n      DEFAULT_OPTIONS.fetchUserInfo,\n    refetchUserInfo:\n      options?.refetchUserInfo ??\n      getBoolean(MONOCLOUD_AUTH_REFETCH_USER_INFO) ??\n      DEFAULT_OPTIONS.refetchUserInfo,\n    allowQueryParamOverrides:\n      options?.allowQueryParamOverrides ??\n      getBoolean(MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES) ??\n      DEFAULT_OPTIONS.allowQueryParamOverrides,\n    strictProfileSync:\n      options?.strictProfileSync ??\n      getBoolean(MONOCLOUD_AUTH_REFETCH_STRICT_PROFILE_SYNC) ??\n      DEFAULT_OPTIONS.strictProfileSync,\n    session: {\n      cookie: {\n        name:\n          options?.session?.cookie?.name ??\n          MONOCLOUD_AUTH_SESSION_COOKIE_NAME ??\n          DEFAULT_OPTIONS.session.cookie.name,\n        path:\n          options?.session?.cookie?.path ??\n          MONOCLOUD_AUTH_SESSION_COOKIE_PATH ??\n          DEFAULT_OPTIONS.session.cookie.path,\n        domain:\n          options?.session?.cookie?.domain ??\n          MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN,\n        httpOnly:\n          options?.session?.cookie?.httpOnly ??\n          getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY) ??\n          DEFAULT_OPTIONS.session.cookie.httpOnly,\n        secure:\n          options?.session?.cookie?.secure ??\n          getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_SECURE) ??\n          appUrl?.startsWith('https:'),\n        sameSite:\n          options?.session?.cookie?.sameSite ??\n          (MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE as SameSiteValues) ??\n          DEFAULT_OPTIONS.session.cookie.sameSite,\n        persistent:\n          options?.session?.cookie?.persistent ??\n          getBoolean(MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT) ??\n          DEFAULT_OPTIONS.session.cookie.persistent,\n      },\n      sliding:\n        options?.session?.sliding ??\n        getBoolean(MONOCLOUD_AUTH_SESSION_SLIDING) ??\n        DEFAULT_OPTIONS.session.sliding,\n      duration:\n        options?.session?.duration ??\n        getNumber(MONOCLOUD_AUTH_SESSION_DURATION) ??\n        DEFAULT_OPTIONS.session.duration,\n      maximumDuration:\n        options?.session?.maximumDuration ??\n        getNumber(MONOCLOUD_AUTH_SESSION_MAX_DURATION) ??\n        DEFAULT_OPTIONS.session.maximumDuration,\n      store: options?.session?.store,\n    },\n    state: {\n      cookie: {\n        name:\n          options?.state?.cookie?.name ??\n          MONOCLOUD_AUTH_STATE_COOKIE_NAME ??\n          DEFAULT_OPTIONS.state.cookie.name,\n        path:\n          options?.state?.cookie?.path ??\n          MONOCLOUD_AUTH_STATE_COOKIE_PATH ??\n          DEFAULT_OPTIONS.state.cookie.path,\n        domain:\n          options?.state?.cookie?.domain ?? MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN,\n        httpOnly: DEFAULT_OPTIONS.state.cookie.httpOnly,\n        secure:\n          options?.state?.cookie?.secure ??\n          getBoolean(MONOCLOUD_AUTH_STATE_COOKIE_SECURE) ??\n          appUrl?.startsWith('https:'),\n        sameSite:\n          options?.state?.cookie?.sameSite ??\n          (MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE as SameSiteValues) ??\n          DEFAULT_OPTIONS.state.cookie.sameSite,\n      },\n      duration:\n        options?.state?.duration ??\n        getNumber(MONOCLOUD_AUTH_STATE_DURATION) ??\n        DEFAULT_OPTIONS.state.duration,\n      maxConcurrent:\n        options?.state?.maxConcurrent ??\n        getNumber(MONOCLOUD_AUTH_STATE_MAX_CONCURRENT) ??\n        DEFAULT_OPTIONS.state.maxConcurrent,\n    },\n    idTokenSigningAlg:\n      options?.idTokenSigningAlg ??\n      (MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG as SecurityAlgorithms) ??\n      DEFAULT_OPTIONS.idTokenSigningAlg,\n    filteredIdTokenClaims:\n      options?.filteredIdTokenClaims ??\n      MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS?.split(' ')\n        .map(x => x.trim())\n        .filter(x => x.length) ??\n      DEFAULT_OPTIONS.filteredIdTokenClaims,\n    groupsClaim:\n      options?.groupsClaim ??\n      MONOCLOUD_AUTH_GROUPS_CLAIM ??\n      DEFAULT_OPTIONS.groupsClaim,\n    debugger: options?.debugger ?? DEFAULT_OPTIONS.debugger,\n    userAgent: options?.userAgent ?? DEFAULT_OPTIONS.userAgent,\n    jwksCacheDuration:\n      options?.jwksCacheDuration ??\n      getNumber(MONOCLOUD_AUTH_JWKS_CACHE_DURATION),\n    metadataCacheDuration:\n      options?.metadataCacheDuration ??\n      getNumber(MONOCLOUD_AUTH_METADATA_CACHE_DURATION),\n    onBackChannelLogout: options?.onBackChannelLogout,\n    onSetApplicationState: options?.onSetApplicationState,\n    onSessionCreating: options?.onSessionCreating,\n  };\n\n  const { value, error } = optionsSchema.validate(opt, { abortEarly: false });\n\n  const requiredEnv: Record<string, string> = {\n    tenantDomain: 'MONOCLOUD_AUTH_TENANT_DOMAIN',\n    clientId: 'MONOCLOUD_AUTH_CLIENT_ID',\n    clientSecret: 'MONOCLOUD_AUTH_CLIENT_SECRET',\n    appUrl: 'MONOCLOUD_AUTH_APP_URL',\n    cookieSecret: 'MONOCLOUD_AUTH_COOKIE_SECRET',\n  };\n\n  if (error) {\n    if (throwOnError) {\n      throw new MonoCloudValidationError(error.details[0].message);\n    }\n\n    // eslint-disable-next-line no-console\n    console.warn(\n      'WARNING: One or more configuration options were not provided for MonoCloudClient.'\n    );\n    error.details.forEach(detail => {\n      if (detail.context?.key && requiredEnv[detail.context.key]) {\n        // eslint-disable-next-line no-console\n        console.warn(\n          `Missing: ${detail.context.key} - Set ${requiredEnv[detail.context.key]} environment variable in your .env file.`\n        );\n      }\n    });\n  }\n\n  return value;\n};\n","import {\n  ensureLeadingSlash,\n  findToken,\n  getBoolean,\n  isAbsoluteUrl,\n  isPresent,\n  isSameHost,\n  now,\n  parseSpaceSeparated,\n  parseSpaceSeparatedSet,\n  setsEqual,\n} from '@monocloud/auth-core/internal';\nimport {\n  generateNonce,\n  generatePKCE,\n  generateState,\n  isUserInGroup,\n  mergeArrays,\n  parseCallbackParams,\n} from '@monocloud/auth-core/utils';\nimport type {\n  Authenticators,\n  AuthorizationParams,\n  DisplayOptions,\n  LogoutTokenClaims,\n  MonoCloudSession,\n  Prompt,\n} from '@monocloud/auth-core';\nimport {\n  MonoCloudOidcClient,\n  MonoCloudOPError,\n  MonoCloudTokenError,\n  MonoCloudValidationError,\n} from '@monocloud/auth-core';\nimport { MonoCloudSessionService } from './monocloud-session-service';\nimport { MonoCloudStateService } from './monocloud-state-service';\nimport { getOptions } from './options/get-options';\nimport {\n  ApplicationState,\n  BackChannelLogoutOptions,\n  CallbackOptions,\n  GetSessionOptions,\n  GetTokensOptions,\n  MonoCloudOptions,\n  MonoCloudOptionsBase,\n  MonoCloudState,\n  MonoCloudTokens,\n  SignInOptions,\n  SignOutOptions,\n  UserInfoOptions,\n} from './types';\nimport {\n  IMonoCloudCookieRequest,\n  IMonoCloudCookieResponse,\n  MonoCloudRequest,\n  MonoCloudResponse,\n} from './types/internal';\nimport {\n  callbackOptionsSchema,\n  getSessionOptionsSchema,\n  getTokensOptionsSchema,\n  resourceValidationSchema,\n  scopesValidationSchema,\n  signInOptionsSchema,\n  signOutOptionsSchema,\n  userInfoOptionsSchema,\n} from './options/validation';\nimport dbug, { Debugger } from 'debug';\n\n/**\n * @category Classes\n */\nexport class MonoCloudCoreClient {\n  public readonly oidcClient: MonoCloudOidcClient;\n\n  private readonly options: MonoCloudOptionsBase;\n\n  private readonly stateService: MonoCloudStateService;\n\n  private readonly sessionService: MonoCloudSessionService;\n\n  private readonly debug: Debugger;\n\n  private optionsValidated = false;\n\n  constructor(partialOptions?: MonoCloudOptions) {\n    this.options = getOptions(partialOptions, false);\n    this.oidcClient = new MonoCloudOidcClient(\n      this.options.tenantDomain,\n      this.options.clientId,\n      {\n        clientSecret: this.options.clientSecret,\n        idTokenSigningAlgorithm: this.options.idTokenSigningAlg,\n        clientAuthMethod: this.options.clientAuthMethod,\n        trustStoreId: this.options.trustStoreId,\n        metadataResolver: this.options.metadataResolver,\n        jwksResolver: this.options.jwksResolver,\n        fetcher: this.options.fetcher,\n        responseTimeout: this.options.responseTimeout,\n        jwksCacheDuration: this.options.jwksCacheDuration,\n        metadataCacheDuration: this.options.metadataCacheDuration,\n      }\n    );\n    this.debug = dbug(this.options.debugger);\n    this.stateService = new MonoCloudStateService(this.options);\n    this.sessionService = new MonoCloudSessionService(this.options);\n\n    /* v8 ignore next -- @preserve */\n    if (process.env.DEBUG && !this.debug.enabled) {\n      dbug.enable(process.env.DEBUG);\n    }\n\n    this.debug('Debug logging enabled.');\n  }\n\n  /**\n   * Initiates the sign-in flow by redirecting the user to the MonoCloud authorization endpoint.\n   *\n   * This method handles scope and resource merging, state generation (nonce, state, PKCE),\n   * and constructing the final authorization URL.\n   *\n   * @param request - MonoCloud request object.\n   * @param response - MonoCloud response object.\n   * @param signInOptions - Configuration to customize the sign-in behavior.\n   * @returns A promise that resolves when the callback processing and redirection are complete.\n   *\n   * @throws {@link MonoCloudValidationError} When validation of parameters or state fails.\n   */\n  async signIn(\n    request: MonoCloudRequest,\n    response: MonoCloudResponse,\n    signInOptions?: SignInOptions\n  ): Promise<any> {\n    this.debug('Starting sign-in handler');\n    try {\n      this.validateOptions();\n\n      response.setNoCache();\n\n      const { method } = await request.getRawRequest();\n\n      if (method.toLowerCase() !== 'get') {\n        response.methodNotAllowed();\n        return response.done();\n      }\n\n      const indicatorResource = this.options.resources\n        ?.map(x => x.resource)\n        .filter(x => !!x)\n        .reduce((acc, x) => `${acc} ${x}`, '');\n      const indicatorScopes = this.options.resources\n        ?.map(x => x.scopes)\n        .filter(x => !!x)\n        .reduce((acc, x) => `${acc} ${x}`, '');\n\n      const mergedScopes = mergeArrays(\n        parseSpaceSeparated(signInOptions?.authParams?.scopes),\n        parseSpaceSeparated(this.options.defaultAuthParams.scopes),\n        parseSpaceSeparated(indicatorScopes)\n      ) ?? ['openid'];\n\n      const mergedResources = mergeArrays(\n        parseSpaceSeparated(signInOptions?.authParams?.resource),\n        parseSpaceSeparated(this.options.defaultAuthParams.resource),\n        parseSpaceSeparated(indicatorResource)\n      );\n\n      // Merge the sign-in options and the default options\n      const opt = {\n        ...(signInOptions ?? {}),\n        authParams: {\n          ...this.options.defaultAuthParams,\n          ...signInOptions?.authParams,\n          scopes: mergedScopes.join(' '),\n          acrValues: mergeArrays(\n            signInOptions?.authParams?.acrValues,\n            this.options.defaultAuthParams.acrValues\n          ),\n          resource: mergedResources?.join(' '),\n        },\n      };\n\n      let appState: ApplicationState = {};\n\n      // Set the application state if the onSetApplicationState function is set\n      if (this.options.onSetApplicationState) {\n        appState = await this.options.onSetApplicationState(request);\n\n        // Validate the custom sign-in state\n        if (\n          appState === null ||\n          appState === undefined ||\n          typeof appState !== 'object' ||\n          Array.isArray(appState)\n        ) {\n          throw new MonoCloudValidationError(\n            'Invalid Application State. Expected state to be an object'\n          );\n        }\n      }\n\n      const query = this.options.allowQueryParamOverrides\n        ? {\n            returnUrl: request.getQuery('return_url') as string,\n            authenticatorHint: request.getQuery(\n              'authenticator_hint'\n            ) as Authenticators,\n            scope: request.getQuery('scope') as string,\n            resource: request.getQuery('resource') as string,\n            display: request.getQuery('display') as DisplayOptions,\n            uiLocales: request.getQuery('ui_locales') as string,\n            acrValues: request.getQuery('acr_values') as string,\n            loginHint: request.getQuery('login_hint') as string,\n            prompt: request.getQuery('prompt') as Prompt,\n            audience: request.getQuery('audience') as string,\n            idTokenHint: request.getQuery('id_token_hint') as string,\n            maxAge: parseInt(request.getQuery('max_age') as string, 10),\n          }\n        : {};\n\n      // Set the return url if passed down\n      const retUrl = query.returnUrl ?? opt.returnUrl;\n      if (\n        typeof retUrl === 'string' &&\n        retUrl &&\n        (!isAbsoluteUrl(retUrl) || isSameHost(this.options.appUrl, retUrl))\n      ) {\n        opt.returnUrl = retUrl;\n      }\n\n      // Validate the options\n      const { error } = signInOptionsSchema.validate(opt, { abortEarly: true });\n\n      if (error) {\n        throw new MonoCloudValidationError(error.details[0].message);\n      }\n\n      // Generate the state, nonce & code verifier\n      const state = generateState();\n      const nonce = generateNonce();\n      const { codeChallenge, codeVerifier } = await generatePKCE();\n\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      if (!isNaN(query.maxAge!)) {\n        opt.authParams.maxAge = query.maxAge;\n      }\n\n      // Ensure that return to is present, if not then use the base url as the return to\n      const returnUrl = encodeURIComponent(\n        opt.returnUrl ?? this.options.appUrl\n      );\n\n      const redirectUrl = `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n      // Create the Authorization Parameters\n      let params: AuthorizationParams = {\n        redirectUri: redirectUrl,\n        ...opt.authParams,\n        nonce,\n        state,\n        codeChallenge,\n      };\n\n      // Set the Authenticator if passed down\n      const authenticatorHint =\n        query.authenticatorHint ?? opt.authParams.authenticatorHint;\n      if (typeof authenticatorHint === 'string' && authenticatorHint) {\n        params.authenticatorHint = authenticatorHint;\n      }\n\n      const scopes =\n        (typeof query.scope === 'string' ? query.scope : undefined) ??\n        opt.authParams.scopes;\n\n      if (scopes) {\n        const { error: e } = scopesValidationSchema.validate(scopes, {\n          abortEarly: true,\n        });\n\n        if (!e) {\n          params.scopes = scopes;\n        }\n      }\n\n      const resource =\n        (typeof query.resource === 'string' ? query.resource : undefined) ??\n        opt.authParams.resource;\n\n      // Set the resources mode if passed down\n      if (resource) {\n        const { error: e } = resourceValidationSchema.validate(resource, {\n          abortEarly: true,\n        });\n\n        if (!e) {\n          params.resource = resource;\n        }\n      }\n\n      // Set the display if passed down\n      const display = query.display ?? opt.authParams.display;\n      if (typeof display === 'string' && display) {\n        params.display = display as unknown as DisplayOptions;\n      }\n\n      // Set the ui locales if passed down\n      const uiLocales = query.uiLocales ?? opt.authParams.uiLocales;\n      if (typeof uiLocales === 'string' && uiLocales) {\n        params.uiLocales = uiLocales;\n      }\n\n      // Set the acr values if passed down\n      const acrValues = query.acrValues ?? opt.authParams.acrValues;\n      if (typeof acrValues === 'string' && acrValues) {\n        params.acrValues = acrValues\n          .split(' ')\n          .map(x => x.trim())\n          .filter(x => x !== '');\n      }\n\n      // Set the login hint if passed down\n      const loginHint = query.loginHint ?? opt.authParams.loginHint;\n      if (typeof loginHint === 'string' && loginHint) {\n        params.loginHint = loginHint;\n      }\n\n      // Set the audience if passed down\n      const audience = query.audience ?? opt.authParams.audience;\n      if (typeof audience === 'string' && audience) {\n        params.audience = audience;\n      }\n\n      // Set the id token hint if passed down\n      const idTokenHint = query.idTokenHint ?? opt.authParams.idTokenHint;\n      if (typeof idTokenHint === 'string' && idTokenHint) {\n        params.idTokenHint = idTokenHint;\n      }\n\n      // Set the prompt if passed down\n      let prompt: string | undefined;\n      if (typeof query.prompt === 'string') {\n        prompt = query.prompt;\n      } else {\n        prompt = opt.register ? 'create' : opt.authParams.prompt;\n      }\n\n      if (prompt) {\n        params.prompt = prompt as Prompt;\n      }\n\n      /* v8 ignore next -- @preserve */\n      if (!params.scopes || params.scopes.length === 0) {\n        throw new MonoCloudValidationError(\n          'Scopes are required for signing in'\n        );\n      }\n\n      // Generate the monocloud state\n      const monoCloudState: MonoCloudState = {\n        returnUrl,\n        state,\n        nonce,\n        codeVerifier,\n        maxAge: opt.authParams.maxAge,\n        appState: JSON.stringify(appState),\n        resource: this.options.defaultAuthParams.resource,\n        scopes: params.scopes,\n      };\n\n      if (this.options.usePar) {\n        const { request_uri } =\n          await this.oidcClient.pushedAuthorizationRequest(params);\n\n        params = {\n          requestUri: request_uri,\n        };\n      }\n\n      // Create authorize url\n      const authUrl = await this.oidcClient.authorizationUrl(params);\n\n      // Set the state cookie\n      await this.stateService.setState(\n        request,\n        response,\n        monoCloudState,\n        params.responseMode === 'form_post' ? 'none' : undefined\n      );\n      // Redirect to authorize url\n      response.redirect(authUrl);\n    } catch (error) {\n      if (typeof signInOptions?.onError === 'function') {\n        return signInOptions.onError(error as Error);\n      } else {\n        this.handleCatchAll(error as Error, response);\n      }\n    }\n\n    return response.done();\n  }\n\n  /**\n   * Handles the OpenID callback after the user authenticates with MonoCloud.\n   *\n   * Processes the authorization code, validates the state and nonce, exchanges the code for tokens,\n   * initializes the user session, and performs the final redirect to the application's return URL.\n   *\n   * @param request - MonoCloud request object.\n   * @param response - MonoCloud response object.\n   * @param callbackOptions - Optional configuration for the callback handler.\n   * @returns A promise that resolves when the callback processing and redirection are complete.\n   *\n   * @throws {@link MonoCloudValidationError} If the state is mismatched or tokens are invalid.\n   */\n  async callback(\n    request: MonoCloudRequest,\n    response: MonoCloudResponse,\n    callbackOptions?: CallbackOptions\n  ): Promise<any> {\n    this.debug('Starting callback handler');\n\n    try {\n      this.validateOptions();\n\n      response.setNoCache();\n\n      const { method, url, body } = await request.getRawRequest();\n\n      if (method.toLowerCase() !== 'get' && method.toLowerCase() !== 'post') {\n        response.methodNotAllowed();\n        return response.done();\n      }\n\n      // Validate the callback Options\n      if (callbackOptions) {\n        const { error } = callbackOptionsSchema.validate(callbackOptions, {\n          abortEarly: true,\n        });\n\n        if (error) {\n          throw new MonoCloudValidationError(error.details[0].message);\n        }\n      }\n\n      let fullUrl = url;\n\n      // check if the url is a relative url\n      if (!isAbsoluteUrl(url)) {\n        fullUrl = `${this.options.appUrl}${ensureLeadingSlash(url)}`;\n      }\n\n      // Get the search parameters or the body\n      const payload =\n        method.toLowerCase() === 'post'\n          ? new URLSearchParams(body)\n          : new URL(fullUrl).searchParams;\n\n      // Get the parameters returned from the server\n      const callbackParams = parseCallbackParams(payload);\n\n      // Get the state value for the transaction being completed. Each transaction\n      // is stored in its own cookie, so a callback which does not identify one\n      // cannot belong to a sign in started by this client.\n      const monoCloudState = callbackParams.state\n        ? await this.stateService.getState(\n            request,\n            response,\n            callbackParams.state\n          )\n        : undefined;\n\n      // Handle invalid state\n      if (!monoCloudState) {\n        throw new MonoCloudValidationError('Invalid Authentication State');\n      }\n\n      if (callbackParams.state !== monoCloudState.state) {\n        throw new MonoCloudValidationError('Invalid state');\n      }\n\n      if (isPresent(callbackParams.error)) {\n        throw new MonoCloudOPError(\n          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n          callbackParams.error!,\n          callbackParams.errorDescription\n        );\n      }\n\n      // Get the redirect Url to be validated\n      const redirectUri =\n        callbackOptions?.redirectUri ??\n        `${this.options.appUrl}${ensureLeadingSlash(this.options.routes.callback)}`;\n\n      if (!callbackParams.code) {\n        throw new MonoCloudValidationError(\n          'Authorization code not found in callback params'\n        );\n      }\n\n      // Parse the client state\n      const appState: ApplicationState = JSON.parse(monoCloudState.appState);\n\n      const session = await this.oidcClient.authenticate(\n        callbackParams.code,\n        redirectUri,\n        monoCloudState.scopes,\n        monoCloudState.resource,\n        {\n          codeVerifier: monoCloudState.codeVerifier,\n          validateIdToken: true,\n          idTokenClockSkew: this.options.clockSkew,\n          idTokenNonce: monoCloudState.nonce,\n          idTokenMaxAge: monoCloudState.maxAge,\n          idTokenClockTolerance: this.options.clockTolerance,\n          fetchUserInfo:\n            callbackOptions?.fetchUserInfo ?? this.options.fetchUserInfo,\n          filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n          onSessionCreating: async (s, i, u) =>\n            await this.options.onSessionCreating?.(s, i, u, appState),\n        }\n      );\n\n      // Set the user session\n      await this.sessionService.setSession(request, response, session);\n\n      // The session is shared by every tab, so the sign ins still in progress\n      // are discarded along with the one which was just completed.\n      await this.stateService.removeAllStates(request, response);\n\n      // Return to base url if no return url was set\n      if (!monoCloudState.returnUrl) {\n        response.redirect(this.options.appUrl);\n        return response.done();\n      }\n\n      // Return to a valid return to url\n      try {\n        const decodedUrl = decodeURIComponent(monoCloudState.returnUrl);\n\n        if (!isAbsoluteUrl(decodedUrl)) {\n          response.redirect(\n            `${this.options.appUrl}${ensureLeadingSlash(decodedUrl)}`\n          );\n          return response.done();\n        }\n\n        if (isSameHost(this.options.appUrl, decodedUrl)) {\n          response.redirect(decodedUrl);\n          return response.done();\n        }\n      } catch {\n        // do nothing\n      }\n\n      response.redirect(this.options.appUrl);\n    } catch (error) {\n      if (typeof callbackOptions?.onError === 'function') {\n        return callbackOptions.onError(error as Error);\n      } else {\n        this.handleCatchAll(error as Error, response);\n      }\n    }\n\n    return response.done();\n  }\n\n  /**\n   * Retrieves user information, optionally refetching fresh data from the UserInfo endpoint.\n   *\n   * @param request - MonoCloud request object.\n   * @param response - MonoCloud response object.\n   * @param userinfoOptions - Configuration to control refetching and error handling.\n   * @returns A promise that resolves with the user information sent as a JSON response.\n   *\n   * @remarks\n   * If `refresh` is true, the session is updated with fresh claims from the identity provider.\n   */\n  async userInfo(\n    request: MonoCloudRequest,\n    response: MonoCloudResponse,\n    userinfoOptions?: UserInfoOptions\n  ): Promise<any> {\n    this.debug('Starting userinfo handler');\n\n    try {\n      this.validateOptions();\n\n      const { method } = await request.getRawRequest();\n\n      if (method.toLowerCase() !== 'get') {\n        response.methodNotAllowed();\n        return response.done();\n      }\n\n      // Validate the User Info options\n      if (userinfoOptions) {\n        const { error } = userInfoOptionsSchema.validate(userinfoOptions, {\n          abortEarly: true,\n        });\n\n        if (error) {\n          throw new MonoCloudValidationError(error.details[0].message);\n        }\n      }\n\n      const query = this.options.allowQueryParamOverrides\n        ? { refresh: getBoolean(request.getQuery('refresh') as string) }\n        : {};\n\n      const refetchUserInfo =\n        query.refresh ??\n        userinfoOptions?.refresh ??\n        this.options.refetchUserInfo;\n\n      // Get the user session\n      const session = await this.sessionService.getSession(\n        request,\n        response,\n        !refetchUserInfo\n      );\n\n      // Handle no session\n      if (!session) {\n        response.setNoCache();\n        response.noContent();\n        return response.done();\n      }\n\n      const defaultToken = findToken(\n        session.accessTokens,\n        this.options.defaultAuthParams.resource,\n        session.authorizedScopes\n      );\n\n      // If refetch is false then return the session\n      if (!refetchUserInfo || !defaultToken) {\n        response.sendJson(session.user);\n        return response.done();\n      }\n\n      // Get the new session\n      const newSession = await this.oidcClient.refetchUserInfo(\n        defaultToken,\n        session,\n        {\n          onSessionCreating: this.options.onSessionCreating?.bind(this),\n          strictProfileSync: this.options.strictProfileSync,\n        }\n      );\n\n      // Update the session containing the new claims\n      const updated = await this.sessionService.updateSession(\n        request,\n        response,\n        newSession\n      );\n\n      // Handle session was not updated successfully\n      if (!updated) {\n        response.setNoCache();\n        response.noContent();\n        return response.done();\n      }\n\n      // Return the Claims\n      response.sendJson(newSession.user);\n    } catch (error) {\n      if (typeof userinfoOptions?.onError === 'function') {\n        return userinfoOptions.onError(error as Error);\n      } else {\n        this.handleCatchAll(error as Error, response);\n      }\n    }\n\n    return response.done();\n  }\n\n  /**\n   * Initiates the sign-out flow, destroying the local session and optionally performing federated sign-out.\n   *\n   * @param request - MonoCloud request object.\n   * @param response - MonoCloud response object.\n   * @param signOutOptions - Configuration for post-logout behavior and federated sign-out.\n   *\n   * @returns A promise that resolves when the sign-out redirection is initiated.\n   */\n  async signOut(\n    request: MonoCloudRequest,\n    response: MonoCloudResponse,\n    signOutOptions?: SignOutOptions\n  ): Promise<any> {\n    this.debug('Starting sign-out handler');\n\n    try {\n      this.validateOptions();\n\n      response.setNoCache();\n\n      const { method } = await request.getRawRequest();\n\n      if (method.toLowerCase() !== 'get') {\n        response.methodNotAllowed();\n        return response.done();\n      }\n\n      // Validate the sign-out options\n      if (signOutOptions) {\n        const { error } = signOutOptionsSchema.validate(signOutOptions, {\n          abortEarly: true,\n        });\n\n        if (error) {\n          throw new MonoCloudValidationError(error.details[0].message);\n        }\n      }\n\n      const query = this.options.allowQueryParamOverrides\n        ? {\n            postLogoutUrl: request.getQuery('post_logout_url') as string,\n            federated: getBoolean(request.getQuery('federated') as string),\n            idTokenHint: request.getQuery('id_token_hint') as string,\n          }\n        : {};\n\n      // Build the return to url\n      let returnUrl =\n        this.options.postLogoutRedirectUri ??\n        signOutOptions?.postLogoutRedirectUri ??\n        this.options.appUrl;\n\n      // Set the return url if passed down\n      if (query.postLogoutUrl) {\n        const { error } = signOutOptionsSchema.validate({\n          postLogoutRedirectUri: query.postLogoutUrl,\n        });\n\n        if (!error) {\n          returnUrl = query.postLogoutUrl;\n        }\n      }\n\n      // Ensure the return to is an absolute one\n      if (!isAbsoluteUrl(returnUrl)) {\n        returnUrl = `${this.options.appUrl}${ensureLeadingSlash(returnUrl)}`;\n      }\n\n      // Get the current session\n      const session = await this.sessionService.getSession(\n        request,\n        response,\n        false\n      );\n\n      // Redirect to return url if session doesn't exist\n      if (!session) {\n        response.redirect(returnUrl);\n        return response.done();\n      }\n\n      await this.sessionService.removeSession(request, response);\n\n      // Signing out ends the session for every tab, so the sign ins in progress\n      // are discarded as well to keep them from restoring it.\n      await this.stateService.removeAllStates(request, response);\n\n      // Handle Federated Sign Out\n      const isFederatedSignOut =\n        query.federated ??\n        signOutOptions?.federatedSignOut ??\n        this.options.federatedSignOut;\n\n      if (!isFederatedSignOut) {\n        response.redirect(returnUrl);\n        return response.done();\n      }\n\n      // Use a manually supplied id token hint (query or options) over the\n      // one from the current session.\n      const idTokenHint =\n        (typeof query.idTokenHint === 'string' && query.idTokenHint\n          ? query.idTokenHint\n          : undefined) ??\n        signOutOptions?.idTokenHint ??\n        session.idToken;\n\n      // Build the end session Url\n      const url = await this.oidcClient.endSessionUrl({\n        idTokenHint,\n        postLogoutRedirectUri: returnUrl,\n        state: signOutOptions?.state,\n      });\n\n      // Redirect the user to the end session endpoint\n      response.redirect(url);\n    } catch (error) {\n      if (typeof signOutOptions?.onError === 'function') {\n        return signOutOptions.onError(error as Error);\n      } else {\n        this.handleCatchAll(error as Error, response);\n      }\n    }\n\n    return response.done();\n  }\n\n  /**\n   * Handles Back-Channel Logout notifications from the identity provider.\n   *\n   * Validates the Logout Token and triggers the `onBackChannelLogout` callback defined in options.\n   *\n   * @param request - MonoCloud request object.\n   * @param response - MonoCloud response object.\n   * @param backChannelLogoutOptions - Optional configuration for the back-channel logout handler.\n   *\n   * @returns A promise that resolves when the logout notification has been processed.\n   *\n   */\n  async backChannelLogout(\n    request: MonoCloudRequest,\n    response: MonoCloudResponse,\n    backChannelLogoutOptions?: BackChannelLogoutOptions\n  ): Promise<any> {\n    this.debug('Starting back-channel logout handler');\n\n    let invalidLogoutToken = false;\n\n    try {\n      this.validateOptions();\n\n      response.setNoCache();\n\n      if (!this.options.onBackChannelLogout) {\n        response.notFound();\n        return response.done();\n      }\n\n      const { method, body } = await request.getRawRequest();\n\n      if (method.toLowerCase() !== 'post') {\n        response.methodNotAllowed();\n        return response.done();\n      }\n\n      const params = new URLSearchParams(body);\n      const logoutToken = params.get('logout_token');\n\n      if (!logoutToken) {\n        invalidLogoutToken = true;\n        throw new MonoCloudValidationError('Missing Logout Token');\n      }\n\n      let payload: LogoutTokenClaims;\n\n      try {\n        payload = await this.oidcClient.validateLogoutToken(\n          logoutToken,\n          this.options.clockSkew,\n          this.options.clockTolerance\n        );\n      } catch (error) {\n        invalidLogoutToken = error instanceof MonoCloudTokenError;\n        throw error;\n      }\n\n      const { sid, sub } = payload;\n\n      await this.options.onBackChannelLogout(sub, sid);\n\n      response.noContent();\n    } catch (error) {\n      if (typeof backChannelLogoutOptions?.onError === 'function') {\n        return backChannelLogoutOptions.onError(error as Error);\n      } else if (invalidLogoutToken) {\n        // eslint-disable-next-line no-console\n        console.error(error);\n        response.sendJson(\n          {\n            error: 'invalid_request',\n            error_description: 'The logout token is missing or invalid.',\n          },\n          400\n        );\n      } else {\n        this.handleCatchAll(error as Error, response);\n      }\n    }\n\n    return response.done();\n  }\n\n  /**\n   * Checks if the current request has an active and authenticated session.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   *\n   * @returns `true` if a valid session with user data exists, `false` otherwise.\n   *\n   */\n  async isAuthenticated(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse\n  ): Promise<boolean> {\n    // Get the session\n    const session = await this.sessionService.getSession(request, response);\n\n    // Return true if the session exists\n    return !!session?.user;\n  }\n\n  /**\n   * Checks if the current session user belongs to the specified groups.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   * @param groups - List of group names or IDs to check.\n   * @param groupsClaim - Optional claim name that holds groups. Defaults to the configured `groupsClaim` option (`\"groups\"` unless overridden).\n   * @param matchAll - If `true`, requires membership in all groups; otherwise any one group is sufficient.\n   *\n   * @returns `true` if the user satisfies the group condition, `false` otherwise.\n   */\n  async isUserInGroup(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse,\n    groups: string[],\n    groupsClaim?: string,\n    matchAll?: boolean\n  ): Promise<boolean> {\n    const session = await this.sessionService.getSession(request, response);\n\n    if (!session?.user) {\n      return false;\n    }\n\n    return isUserInGroup(\n      session.user,\n      groups,\n      groupsClaim ?? this.options.groupsClaim,\n      matchAll\n    );\n  }\n\n  /**\n   * Retrieves the current user's session data.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   * @param options - Optional configuration to control session retrieval behavior.\n   *\n   * @returns Session or `undefined`.\n   */\n  async getSession(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse,\n    options?: GetSessionOptions\n  ): Promise<MonoCloudSession | undefined> {\n    if (options) {\n      const { error } = getSessionOptionsSchema.validate(options, {\n        abortEarly: true,\n      });\n\n      if (error) {\n        throw new MonoCloudValidationError(error.details[0].message);\n      }\n    }\n\n    const session = await this.sessionService.getSession(request, response);\n\n    if (!options?.refetchUserInfo || !session) {\n      return session;\n    }\n\n    const defaultToken = findToken(\n      session.accessTokens,\n      this.options.defaultAuthParams.resource,\n      session.authorizedScopes\n    );\n\n    if (!defaultToken) {\n      throw new MonoCloudValidationError('Access token not found');\n    }\n\n    const newSession = await this.oidcClient.refetchUserInfo(\n      defaultToken,\n      session,\n      {\n        onSessionCreating: this.options.onSessionCreating?.bind(this),\n        strictProfileSync: this.options.strictProfileSync,\n      }\n    );\n\n    await this.sessionService.updateSession(request, response, newSession);\n\n    return newSession;\n  }\n\n  /**\n   * Updates the current user's session with new data.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   * @param session - The updated session object to persist.\n   */\n  async updateSession(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse,\n    session: MonoCloudSession\n  ): Promise<void> {\n    await this.sessionService.updateSession(request, response, session);\n  }\n\n  /**\n   * Returns a copy of the current client configuration options.\n   *\n   * @returns A copy of the initialized configuration.\n   */\n  getOptions(): MonoCloudOptionsBase {\n    return { ...this.options };\n  }\n\n  /**\n   * Destroys the local user session.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   *\n   * @remarks\n   * This does not perform federated sign-out. For identity provider sign-out, use `signOut` handler.\n   */\n  destroySession(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse\n  ): Promise<void> {\n    return this.sessionService.removeSession(request, response);\n  }\n\n  /**\n   * Retrieves active tokens (Access, ID, Refresh), performing a refresh if they are expired or missing.\n   *\n   * @param request - MonoCloud cookie request object.\n   * @param response - MonoCloud cookie response object.\n   * @param options - Configuration for token retrieval (force refresh, specific scopes/resources).\n   *\n   * @returns Fetched tokens.\n   *\n   * @throws {@link MonoCloudValidationError} If the session does not exist or tokens cannot be found/refreshed.\n   */\n  async getTokens(\n    request: IMonoCloudCookieRequest,\n    response: IMonoCloudCookieResponse,\n    options?: GetTokensOptions\n  ): Promise<MonoCloudTokens> {\n    // Validate the get tokens options\n    if (options) {\n      const { error } = getTokensOptionsSchema.validate(options, {\n        abortEarly: true,\n      });\n\n      if (error) {\n        throw new MonoCloudValidationError(error.details[0].message);\n      }\n    }\n\n    // Get the session\n    const session = await this.sessionService.getSession(request, response);\n\n    if (!session) {\n      throw new MonoCloudValidationError('Session does not exist');\n    }\n\n    let scopes = options?.scopes;\n\n    const resource =\n      options?.resource ?? this.options.defaultAuthParams.resource;\n\n    if (isPresent(options?.resource)) {\n      if (!isPresent(scopes)) {\n        // Check if there is a resource with undefined scope\n        const noScopeResource = this.options.resources?.find(\n          x =>\n            setsEqual(\n              parseSpaceSeparatedSet(x.resource),\n              parseSpaceSeparatedSet(resource)\n            ) && !x.scopes\n        );\n\n        // Search for the same resource with scopes defined\n        if (!noScopeResource) {\n          scopes = this.options.resources?.find(x =>\n            setsEqual(\n              parseSpaceSeparatedSet(x.resource),\n              parseSpaceSeparatedSet(resource)\n            )\n          )?.scopes;\n        }\n      }\n    }\n\n    const findTokenScopes =\n      !isPresent(options?.resource) && !isPresent(scopes)\n        ? session.authorizedScopes\n        : scopes;\n\n    let token = findToken(session.accessTokens, resource, findTokenScopes);\n\n    const tokenExpired = !!token && token.accessTokenExpiration - 30 < now();\n\n    let { idToken } = session;\n    let { refreshToken } = session;\n\n    if (options?.forceRefresh || !token || tokenExpired) {\n      if (!refreshToken && token && tokenExpired) {\n        throw new MonoCloudTokenError(\n          'No refresh token available to refresh the expired access token'\n        );\n      }\n\n      const updatedSession = await this.oidcClient.refreshSession(session, {\n        fetchUserInfo: options?.refetchUserInfo ?? this.options.refetchUserInfo,\n        validateIdToken: true,\n        idTokenClockSkew: this.options.clockSkew,\n        idTokenClockTolerance: this.options.clockTolerance,\n        refreshGrantOptions: {\n          resource,\n          scopes,\n        },\n        filteredIdTokenClaims: this.options.filteredIdTokenClaims,\n        onSessionCreating: this.options.onSessionCreating?.bind(this),\n        strictProfileSync: this.options.strictProfileSync,\n      });\n\n      await this.sessionService.updateSession(\n        request,\n        response,\n        updatedSession\n      );\n\n      token = findToken(\n        updatedSession?.accessTokens,\n        resource,\n        findTokenScopes\n      );\n\n      idToken = updatedSession.idToken;\n      refreshToken = updatedSession.refreshToken;\n    }\n\n    // Just in case. At this point, the access token should be present\n    /* v8 ignore next -- @preserve */\n    if (!token) {\n      throw new MonoCloudValidationError('Access token not found');\n    }\n\n    return {\n      ...token,\n      idToken,\n      refreshToken,\n      isExpired: token.accessTokenExpiration - 30 < now(),\n    };\n  }\n\n  private handleCatchAll(error: Error, res: MonoCloudResponse): void {\n    // eslint-disable-next-line no-console\n    console.error(error);\n    res.internalServerError();\n  }\n\n  private validateOptions(): void {\n    if (!this.optionsValidated) {\n      this.optionsValidated = true;\n      getOptions(this.options);\n    }\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAM,kBAAkB;AAExB,IAAa,0BAAb,MAAqC;CACnC,YAAY,SAAgD;EAA/B,KAAA,UAAA;CAAgC;CAE7D,MAAM,WACJ,KACA,KACA,SACiB;EAEjB,MAAM,MAAM,OAAO,WAAW;EAG9B,MAAM,OAAA,GAAA,8BAAA,IAAA,CAAU;EAChB,MAAM,MAAM;EAMZ,MAAM,cAAkC;GACtC;GACA,UAAU;IAAE,GAAG;IAAK,GAAG;IAAK,GALlB,KAAK,UAAU,KAAK,GAKG;GAAE;EACrC;EAGA,MAAM,KAAK,YAAY,KAAK,KAAK,aAAa,OAAO;EAGrD,OAAO;CACT;CAEA,MAAM,WACJ,KACA,KACA,eAAe,MACwB;EAEvC,MAAM,cAAc,MAAM,KAAK,cAAc,GAAG;EAGhD,IAAI,CAAC,aAAa;GAChB,MAAM,KAAK,iBAAiB,KAAK,GAAG;GACpC;EACF;EAMA,IAAI,CAAC,MAHiB,KAAK,gBAAgB,KAAK,KAAK,WAAW,GAI9D;EAIF,MAAM,OAAA,GAAA,8BAAA,IAAA,CAAU;EAChB,MAAM,MAAM,KAAK,UAAU,YAAY,SAAS,GAAG,GAAG;EAGtD,IAAI,CAAC,KAAK,QAAQ,QAAQ,OAAO;GAC/B,MAAM,UAA4B,EAAE,MAAM,CAAC,EAAmB;GAG9D,IAAI,CAAC,YAAY,SACf;GAIF,OAAO,OAAO,SAAS,KAAK,MAAM,KAAK,UAAU,YAAY,OAAO,CAAC,CAAC;GAGtE,IAAI,gBAAgB,QAAQ,YAAY,SAAS,GAC/C,MAAM,KAAK,YACT,KACA,KACA;IACE,GAAG;IACH,UAAU;KAAE,GAAG,YAAY,SAAS;KAAG,GAAG;KAAK,GAAG;IAAI;GACxD,GACA,OACF;GAIF,OAAO;EACT;EAGA,MAAM,aAAa,MAAM,KAAK,QAAQ,QAAQ,MAAM,IAAI,YAAY,GAAG;EAGvE,IAAI,CAAC,YAAY;GACf,MAAM,KAAK,iBAAiB,KAAK,GAAG;GACpC;EACF;EAGA,MAAM,UAA4B,EAAE,MAAM,CAAC,EAAmB;EAC9D,OAAO,OAAO,SAAS,KAAK,MAAM,KAAK,UAAU,UAAU,CAAC,CAAC;EAG7D,IAAI,gBAAgB,QAAQ,YAAY,SAAS,GAC/C,MAAM,KAAK,YACT,KACA,KACA;GACE,GAAG;GACH,UAAU;IAAE,GAAG,YAAY,SAAS;IAAG,GAAG;IAAK,GAAG;GAAI;EACxD,GACA,OACF;EAIF,OAAO;CACT;CAEA,MAAM,cACJ,KACA,KACA,SACkB;EAElB,MAAM,cAAc,MAAM,KAAK,cAAc,GAAG;EAGhD,IAAI,CAAC,aAAa;GAChB,MAAM,KAAK,iBAAiB,KAAK,GAAG;GACpC,OAAO;EACT;EAMA,IAAI,CAAC,MAHiB,KAAK,gBAAgB,KAAK,KAAK,WAAW,GAI9D,OAAO;EAIT,MAAM,OAAA,GAAA,8BAAA,IAAA,CAAU;EAChB,MAAM,MAAM,KAAK,UAAU,YAAY,SAAS,GAAG,GAAG;EAGtD,MAAM,KAAK,YACT,KACA,KACA;GACE,GAAG;GACH,UAAU;IAAE,GAAG,YAAY,SAAS;IAAG,GAAG;IAAK,GAAG;GAAI;EACxD,GACA,OACF;EAEA,OAAO;CACT;CAEA,MAAM,cACJ,KACA,KACe;EAEf,MAAM,cAAc,MAAM,KAAK,cAAc,GAAG;EAGhD,IAAI,CAAC,aAAa;GAChB,MAAM,KAAK,iBAAiB,KAAK,GAAG;GACpC;EACF;EAGA,IAAI,KAAK,QAAQ,QAAQ,OAGnB;;OAAA,YAAY,KACd,MAAM,KAAK,QAAQ,QAAQ,MAAM,OAAO,YAAY,GAAG;EAAA;EAI3D,MAAM,KAAK,iBAAiB,KAAK,GAAG;CACtC;CAEA,MAAc,gBACZ,KACA,KACA,aACkB;EAElB,MAAM,WAAA,GAAA,8BAAA,IAAA,CAAc;EAEpB,IAAI,UAAU;EAGd,IAAI,YAAY,SAAS,KAAK,YAAY,SAAS,IAAI,SACrD,UAAU;EAIZ,IACE,KAAK,QAAQ,QAAQ,WACrB,YAAY,SAAS,IAAI,KAAK,QAAQ,QAAQ,WAAW,SAEzD,UAAU;EAIZ,IACE,YAAY,SAAS,IAAI,KAAK,QAAQ,QAAQ,kBAC9C,SAEA,UAAU;EAIZ,IAAI,SACF,OAAO;EAIT,IAAI,KAAK,QAAQ,QAAQ,OACvB,MAAM,KAAK,QAAQ,QAAQ,MAAM,OAAO,YAAY,GAAG;EAGzD,MAAM,KAAK,iBAAiB,KAAK,GAAG;EAEpC,OAAO;CACT;CAEA,MAAc,YACZ,KACA,KACA,aACA,SACe;EACf,MAAM,UAAU,IAAI,KAAK,MAAM,KAAK,iBAAiB,GAAG,EAAA,EAAI,QAAQ,CAAC,CAAC;EAGtE,IAAI,CAAC,KAAK,QAAQ,QAAQ,OAGxB,YAAY,UAAU;EAIxB,IAAI,KAAK,QAAQ,QAAQ,OAAO;GAE9B,MAAM,aAAa,MAAM,KAAK,cAAc,GAAG;GAG/C,IAAI,YAAY,KACd,MAAM,KAAK,QAAQ,QAAQ,MAAM,OAAO,WAAW,GAAG;GAKxD,YAAY,UAAU,KAAA;GAGtB,MAAM,KAAK,QAAQ,QAAQ,MAAM,IAC/B,YAAY,KACZ,SACA,YAAY,QACd;EACF;EAGA,MAAM,gBAAgB,OAAA,GAAA,2BAAA,QAAA,CACpB,KAAK,UAAU,WAAW,GAC1B,KAAK,QAAQ,YACf;EAEA,MAAM,eAAe,YAAY,SAAS,oBACtC,IAAI,KAAK,YAAY,SAAS,IAAI,GAAI,IACtC,KAAA;EAEJ,MAAM,gBAAgB,KAAK,iBAAiB,YAAY;EACxD,MAAM,YACJ,mBAAA,GAAA,OAAA,UAAA,CACU,GAAG,KAAK,QAAQ,QAAQ,OAAO,KAAK,KAAK,IAAI,aAAa,CAAC,CAClE;EAGL,MAAM,SAAS,KAAK,KAAK,cAAc,SAAS,SAAS;EAEzD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,GAAG;GAClC,MAAM,iBAAiB,cAAc,MACnC,IAAI,YACH,IAAI,KAAK,SACZ;GAEA,MAAM,aACJ,WAAW,IACP,KAAK,QAAQ,QAAQ,OAAO,OAC5B,GAAG,KAAK,QAAQ,QAAQ,OAAO,KAAK,GAAG;GAE7C,MAAM,IAAI,UACR,YACA,gBACA,KAAK,iBAAiB,YAAY,CACpC;GAEA,QAAQ,OAAO,UAAU;EAC3B;EAGA,KAAK,MAAMA,YAAU,SACnB,MAAM,IAAI,UAAUA,UAAQ,IAAI,KAAK,iCAAiB,IAAI,KAAK,CAAC,CAAC,CAAC;CAEtE;CAEA,MAAc,cACZ,KACyC;EAEzC,MAAM,aAAa,MAAM,KAAK,iBAAiB,GAAG;EAGlD,IAAI,CAAC,YAAY,OACf;EAIF,MAAM,OAAO,OAAA,GAAA,2BAAA,QAAA,CAAc,WAAW,OAAO,KAAK,QAAQ,YAAY;EAGtE,IAAI,CAAC,MACH;EAIF,OAAO,KAAK,MAAM,IAAI;CACxB;CAEA,MAAc,iBACZ,KACwD;EAExD,MAAM,UAAU,MAAM,IAAI,cAAc;EAGxC,IAAI,CAAC,QAAQ,MACX;EAIF,MAAM,MAAM,QAAQ,IAAI,KAAK,QAAQ,QAAQ,OAAO,IAAI;EAExD,IAAI,KACF,OAAO;GAAE,MAAM,CAAC,KAAK,QAAQ,QAAQ,OAAO,IAAI;GAAG,OAAO;EAAI;EAIhE,MAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ,CAAC,CAAC,CAC/C,QAAQ,CAACA,cACRA,SAAO,WAAW,GAAG,KAAK,QAAQ,QAAQ,OAAO,KAAK,EAAE,CAC1D,CAAC,CACA,KAAK,CAACA,UAAQ,YAAY;GAEzB,KAAK,SAASA,SAAO,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,KAAK,EAAE;GAChD;EACF,EAAE,CAAC,CACF,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;EAG/B,MAAM,cAAc,aAAa,KAAK,EAAE,YAAY,KAAK,CAAC,CAAC,KAAK,EAAE;EAGlE,IAAI,CAAC,aACH;EAIF,OAAO;GACL,MAAM,aAAa,KAChB,EAAE,UAAU,GAAG,KAAK,QAAQ,QAAQ,OAAO,KAAK,GAAG,KACtD;GACA,OAAO;EACT;CACF;CAEA,UAAkB,KAAa,KAAiC;EAE9D,IAAI,CAAC,KAAK,QAAQ,QAAQ,OAAO,YAC/B;EAIF,IAAI,CAAC,KAAK,QAAQ,QAAQ,SACxB,OAAO,KAAK,MAAM,MAAM,KAAK,QAAQ,QAAQ,QAAQ;EAIvD,OAAO,KAAK,MACV,KAAK,IACH,MAAM,KAAK,QAAQ,QAAQ,UAC3B,MAAM,KAAK,QAAQ,QAAQ,eAC7B,CACF;CACF;CAEA,iBAAyB,KAA2B;EAClD,OAAO;GACL,QAAQ,KAAK,QAAQ,QAAQ,OAAO;GACpC,UAAU,KAAK,QAAQ,QAAQ,OAAO;GACtC,UAAU,KAAK,QAAQ,QAAQ,OAAO;GACtC,QAAQ,KAAK,QAAQ,QAAQ,OAAO;GACpC,MAAM,KAAK,QAAQ,QAAQ,OAAO;GAClC,SAAS;EACX;CACF;CAEA,MAAc,iBACZ,KACA,KACe;EAGf,MAAM,WAAU,MAFQ,KAAK,iBAAiB,GAAG,EAAA,EAEtB,MAAM,QAAO,MACtC,EAAE,WAAW,KAAK,QAAQ,QAAQ,OAAO,IAAI,CAC/C;EAEA,KAAK,MAAMA,YAAU,WAAW,CAAC,GAC/B,MAAM,IAAI,UAAUA,UAAQ,IAAI,KAAK,iCAAiB,IAAI,KAAK,CAAC,CAAC,CAAC;CAEtE;AACF;;;AC7aA,IAAa,wBAAb,MAAmC;CACjC,YAAY,SAAgD;EAA/B,KAAA,UAAA;CAAgC;CAE7D,MAAM,SACJ,KACA,KACA,OACA,kBACe;EACf,MAAM,aAAa,MAAM,KAAK,cAAc,MAAM,KAAK;EAEvD,MAAM,KAAK,mBAAmB,KAAK,KAAK,UAAU;EAElD,MAAM,IAAI,UACR,YACA,OAAA,GAAA,2BAAA,iBAAA,CACE,OACA,KAAK,QAAQ,cACb,KAAK,QAAQ,MAAM,QACrB,GACA,KAAK,iBAAiB,gBAAgB,CACxC;CACF;CAEA,MAAM,SACJ,KACA,KACA,OACqC;EACrC,MAAM,aAAa,MAAM,KAAK,cAAc,KAAK;EACjD,MAAM,SAAS,MAAM,IAAI,UAAU,UAAU;EAG7C,IAAI,CAAC,QACH;EAGF,IAAI;EAEJ,IAAI;GAEF,kBAAkB,OAAA,GAAA,2BAAA,iBAAA,CAChB,QACA,KAAK,QAAQ,YACf;EACF,QAAQ;GACN,MAAM,KAAK,aAAa,KAAK,UAAU;GACvC;EACF;EAGA,MAAM,KAAK,aAAa,KAAK,UAAU;EAGvC,OAAO;CACT;CAEA,MAAM,gBACJ,KACA,KACe;EACf,KAAK,MAAM,CAAC,SAAS,MAAM,KAAK,gBAAgB,GAAG,GACjD,MAAM,KAAK,aAAa,KAAK,IAAI;CAErC;CAEA,MAAc,cAAc,OAAgC;EAC1D,OAAO,GAAG,KAAK,QAAQ,MAAM,OAAO,KAAK,GAAG,OAAA,GAAA,8BAAA,OAAA,CAAa,KAAK;CAChE;CAEA,MAAc,gBACZ,KAC8B;EAC9B,MAAM,EAAE,SAAS,KAAK,QAAQ,MAAM;EAEpC,MAAM,UAAU,MAAM,IAAI,cAAc;EAExC,OAAO,IAAI,IACT,CAAC,GAAG,OAAO,CAAC,CAAC,QACV,CAAC,gBACA,eAAe,QACd,WAAW,WAAW,GAAG,KAAK,EAAE,KAC/B,WAAW,KAAK,WAAW,MAAM,KAAK,SAAS,CAAC,CAAC,CACvD,CACF;CACF;CAEA,MAAc,mBACZ,KACA,KACA,YACe;EACf,MAAM,UAAU,MAAM,KAAK,gBAAgB,GAAG;EAG9C,QAAQ,OAAO,UAAU;EAEzB,MAAM,KAAK,YAAY,KAAK,SAAS,KAAK,QAAQ,MAAM,gBAAgB,CAAC;CAC3E;;;;CAKA,MAAc,YACZ,KACA,SACA,UACe;EACf,MAAM,QAAQ,CAAC,GAAG,QAAQ,KAAK,CAAC;EAEhC,MAAM,UAAU,KAAK,IAAI,MAAM,SAAS,UAAU,CAAC;EAEnD,KAAK,MAAM,QAAQ,MAAM,MAAM,GAAG,OAAO,GACvC,MAAM,KAAK,aAAa,KAAK,IAAI;EAGnC,KAAK,MAAM,QAAQ,MAAM,MAAM,OAAO,GAEpC,IAAI,CAAE,MAAM,KAAK,SAAS,QAAQ,IAAI,IAAI,CAAE,GAC1C,MAAM,KAAK,aAAa,KAAK,IAAI;CAGvC;CAEA,MAAc,SAAS,OAAiC;EACtD,IAAI;GACF,OAAA,GAAA,2BAAA,iBAAA,CAAuB,OAAO,KAAK,QAAQ,YAAY;GACvD,OAAO;EACT,QAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAc,aACZ,KACA,MACe;EACf,MAAM,IAAI,UAAU,MAAM,IAAI;GAC5B,GAAG,KAAK,iBAAiB;GACzB,QAAQ,KAAA;GACR,yBAAS,IAAI,KAAK,CAAC;EACrB,CAAC;CACH;CAEA,iBAAyB,UAA0C;EACjE,OAAO;GACL,QAAQ,KAAK,QAAQ,MAAM,OAAO;GAClC,UAAU,KAAK,QAAQ,MAAM,OAAO;GACpC,UAAU,YAAY,KAAK,QAAQ,MAAM,OAAO;GAChD,QAAQ,KAAK,QAAQ,MAAM,OAAO;GAClC,MAAM,KAAK,QAAQ,MAAM,OAAO;GAChC,QAAQ,KAAK,QAAQ,MAAM;EAC7B;CACF;AACF;;;ACnKA,MAAa,kBAAkB;CAC7B,QAAQ;EACN,UAAU;EACV,mBAAmB;EACnB,QAAQ;EACR,SAAS;EACT,UAAU;CACZ;CACA,WAAW;CACX,gBAAgB;CAChB,iBAAiB;CACjB,QAAQ;CACR,eAAe;CACf,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;EACjB,QAAQ;EACR,cAAc;CAChB;CACA,0BAA0B;CAC1B,mBAAmB;CACnB,aAAa;CACb,SAAS;EACP,QAAQ;GACN,UAAU;GACV,MAAM;GACN,MAAM;GACN,UAAU;GACV,YAAY;EACd;EACA,SAAS;EACT,UAAU,OAAU;EACpB,iBAAiB,QAAc;CACjC;CACA,OAAO;EACL,QAAQ;GACN,UAAU;GACV,MAAM;GACN,MAAM;GACN,UAAU;EACZ;EACA,UAAU;EACV,eAAe;CACjB;CACA,mBAAmB;CACnB,kBAAkB;CAClB,uBAAuB;EACrB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CACA,UAAU;CACV,WAAW;AACb;;;ACzCA,MAAM,iBAAiBC,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS;AAC7C,MAAM,iBAAiBA,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS;AAC7C,MAAM,eAAeA,IAAAA,QAAI,QAAQ,CAAC,CAAC,SAAS;AAC5C,MAAM,eAAeA,IAAAA,QAAI,QAAQ,CAAC,CAAC,SAAS;AAC5C,MAAM,cAAcA,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS;AAC1C,MAAM,cAAcA,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS;AAC1C,MAAM,iBAAiBA,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS;AAC7C,MAAM,eAAeA,IAAAA,QAAI,SAAS,CAAC,CAAC,SAAS;AAE7C,MAAM,yBAA6C;CACjD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,eAAeA,IAAAA,QAAI,OAAO;CAC9B,MAAM;CACN,MAAM,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;CAC/C,QAAQ;CACR,UAAU;CACV,QAAQ,aAAa,KAAKA,IAAAA,QAAI,IAAI,SAAS,GAAG;EAC5C,IAAIA,IAAAA,QAAI,OAAO,CAAC,CAAC,QAAQ,UAAU;EACnC,MAAMA,IAAAA,QAAI,MAAM,IAAI,CAAC,CAAC,SAAS,EAC7B,YACE,+DACJ,CAAC;EACD,WAAWA,IAAAA,QAAI,MAAM,KAAK;CAC5B,CAAC;CACD,UAAU,eAAe,MAAM,UAAU,OAAO,MAAM;AACxD,CAAC,CAAC,CAAC,SAAS;AAEZ,MAAM,sBAAsB,aAAa,KAAK,EAC5C,YAAY,aACd,CAAC;AAED,MAAM,iBAAiB,eAAe,QAAQ,OAAO,YAAY;CAC/D,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,QAAQ,IAAI,aAAa,SAAS,KAAK,IAAI,KAAK,WAAW;CAC7D,QAAQ;EACN,QAAQ;CACV;CAEA,IAAI,CAAC,OACH,OAAO,QAAQ,QAAQ,EACrB,QAAQ,gEACV,CAAC;CAGH,OAAO;AACT,CAAC;AAED,MAAa,2BAA2BA,IAAAA,QAAI,OAAO,CAAC,CACjD,QAAQ,OAAO,YAAY;CAC1B,MAAM,QAAQ,MACX,MAAM,KAAK,CAAC,CACZ,KAAK,MAAc,EAAE,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;CAEjB,IAAI,MAAM,WAAW,GACnB,OAAO,QAAQ,QAAQ,EAAE,QAAQ,6BAA6B,CAAC;CAGjE,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,EAAE,UAAU,eAAe,SAAS,IAAI;EAC9C,IAAI,OACF,OAAO,QAAQ,QAAQ,EACrB,QAAQ,qBAAqB,KAAK,KAAK,MAAM,UAC/C,CAAC;CAEL;CAEA,OAAO,MAAM,KAAK,GAAG;AACvB,CAAC,CAAC,CACD,SAAS,EACR,eAAe,oDACjB,CAAC;AAEH,MAAM,gBAA+DA,IAAAA,QAAI,OACvE;CACE,QAAQ;CACR,SAAS;CACT,UAAU,YAAY,IAAI,CAAC;CAC3B,iBAAiB,YAAY,IAAI,CAAC,CAAC,CAAC,QAAQA,IAAAA,QAAI,IAAI,UAAU,CAAC;CAC/D,OAAO;AACT,CACF,CAAC,CAAC,SAAS;AAEX,MAAM,cAAuDA,IAAAA,QAAI,OAAO;CACtE,QAAQ;CACR,UAAU,YAAY,QAAQ,CAAC,CAAC,IAAI,GAAG;CACvC,eAAe,YAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE;AACpD,CAAC,CAAC,CAAC,SAAS;AAEZ,MAAM,eAAe,eAClB,QAAQ,OAAO,YAAY;CAC1B,MAAM,SAAS,MACZ,MAAM,KAAK,CAAC,CACZ,KAAK,MAAc,EAAE,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;CAEjB,IAAI,OAAO,WAAW,GACpB,OAAO,QAAQ,QAAQ,EACrB,QAAQ,0CACV,CAAC;CAGH,IAAI,CAAC,OAAO,SAAS,QAAQ,GAC3B,OAAO,QAAQ,QAAQ,EAAE,QAAQ,4BAA4B,CAAC;CAGhE,OAAO,OAAO,KAAK,GAAG;AACxB,CAAC,CAAC,CACD,SAAS,EAAE,eAAe,0CAA0C,CAAC;AAExE,MAAM,kBAAyDA,IAAAA,QAAI,OAAO;CACxE,QAAQ;CACR,cAAc,eAAe,MAAM,MAAM,CAAC,CAAC,SAAS;CACpD,cAAc,eAAe,MAAM,SAAS,WAAW;CACvD,UAAU,yBAAyB,SAAS;AAC9C,CAAC,CAAC,CACC,QAAQ,IAAI,CAAC,CACb,SAAS;AAEZ,MAAM,0BACJA,IAAAA,QAAI,OAAO;CACT,QAAQ;CACR,cAAc,eAAe,MAAM,MAAM,CAAC,CAAC,SAAS;CACpD,cAAc,eAAe,MAAM,SAAS,WAAW;AACzD,CAAC,CAAC,CACC,QAAQ,IAAI,CAAC,CACb,SAAS;AAEd,MAAM,eAAkDA,IAAAA,QAAI,OAAO;CACjE,UAAU,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;CACnD,mBAAmB,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;CAC5D,QAAQ,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;CACjD,SAAS,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;CAClD,UAAU,eAAe,IAAI,EAAE,cAAc,KAAK,CAAC;AACrD,CAAC,CAAC,CAAC,SAAS;AAEZ,MAAa,yBAAyB,eACnC,QAAQ,OAAO,YAAY;CAC1B,MAAM,SAAS,MACZ,MAAM,KAAK,CAAC,CACZ,KAAK,MAAc,EAAE,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;CAEjB,IAAI,OAAO,WAAW,GACpB,OAAO,QAAQ,QAAQ,EACrB,QAAQ,0CACV,CAAC;CAGH,OAAO,OAAO,KAAK,GAAG;AACxB,CAAC,CAAC,CACD,SAAS,EAAE,eAAe,0CAA0C,CAAC;AAExE,MAAa,yBAAsDA,IAAAA,QAAI,OAAO;CAC5E,UAAU;CACV,QAAQ,uBAAuB,SAAS;AAC1C,CAAC;AAED,MAAa,gBAAwDA,IAAAA,QAAI,OACvE;CACE,UAAU;CACV,cAAcA,IAAAA,QAAI,aAAa,CAAC,CAAC,YAAY,oBAAoB;EAC/D,IAAI;EACJ,MAAMA,IAAAA,QAAI,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EACrC,eACE,8EACJ,CAAC;EACD,WAAW;CACb,CAAC;CACD,kBAAkBA,IAAAA,QAAI,OAAO,CAAC,CAAC,MAAM,GAAG,sBAAsB;CAC9D,cAAc;CACd,SAAS;CACT,kBAAkB;CAClB,cAAc;CACd,cAAc,eAAe,IAAI;CACjC,cAAc,eAAe,IAAI,CAAC;CAClC,QAAQ,eAAe,IAAI;CAC3B,QAAQ;CACR,WAAW,YAAY,IAAI,CAAC;CAC5B,gBAAgB,YAAY,IAAI,CAAC;CACjC,iBAAiB,YAAY,IAAI,GAAI;CACrC,QAAQ;CACR,uBAAuB,eAAe,IAAI,EAAE,eAAe,KAAK,CAAC;CACjE,kBAAkB;CAClB,eAAe;CACf,iBAAiB;CACjB,0BAA0B;CAC1B,mBAAmB;CACnB,mBAAmB;CACnB,WAAWA,IAAAA,QAAI,MAAiB,CAAC,CAAC,MAAM,sBAAsB,CAAC,CAAC,SAAS;CACzE,SAAS;CACT,OAAO;CACP,mBAAmBA,IAAAA,QAAI,OAAO,CAAC,CAAC,MAC9B,SACA,SACA,SACA,SACA,SACA,SACA,SACA,SACA,OACF;CACA,uBAAuBA,IAAAA,QAAI,MAAc,CAAC,CAAC,MAAM,cAAc;CAC/D,aAAa;CACb,UAAU;CACV,WAAW;CACX,mBAAmB;CACnB,uBAAuB;CACvB,qBAAqB;CACrB,uBAAuB;CACvB,mBAAmB;AACrB,CACF,CAAC,CAAC,QAAQ,OAAO,YAAY;CAC3B,MAAM,cAAc,MAAM,QAAQ,OAAO;CACzC,MAAM,YAAY,MAAM,MAAM,OAAO;CAErC,IAAI,cAAc,aAChB,OAAO,QAAQ,QAAQ,EACrB,QACE,uEACJ,CAAC;CAGH,IAAI,UAAU,WAAW,GAAG,YAAY,EAAE,GACxC,OAAO,QAAQ,QAAQ,EACrB,QAAQ,8CAA8C,YAAY,sDACpE,CAAC;CAGH,IAAI,YAAY,WAAW,GAAG,UAAU,EAAE,GACxC,OAAO,QAAQ,QAAQ,EACrB,QAAQ,gDAAgD,UAAU,sDACpE,CAAC;CAGH,OAAO;AACT,CAAC;AAED,MAAa,sBAAuDA,IAAAA,QAAI,OAAO;CAC7E,WAAW,eAAe,IAAI,EAAE,eAAe,KAAK,CAAC;CACrD,UAAU;CACV,YAAY;CACZ,SAAS;AACX,CAAC;AAED,MAAa,wBACXA,IAAAA,QAAI,OAAO;CACT,eAAe;CACf,aAAa,eAAe,IAAI;CAChC,SAAS;AACX,CAAC;AAEH,MAAa,wBACXA,IAAAA,QAAI,OAAO;CACT,SAAS;CACT,SAAS;AACX,CAAC;AAEH,MAAa,uBACXA,IAAAA,QAAI,OAAO;CACT,uBAAuB,eAAe,IAAI,EAAE,eAAe,KAAK,CAAC;CACjE,aAAa;CACb,OAAO;CACP,kBAAkB;CAClB,SAAS;AACX,CAAC;AAEH,MAAa,yBACXA,IAAAA,QAAI,OAAO;CACT,cAAc;CACd,iBAAiB;CACjB,UAAU,yBAAyB,SAAS;CAC5C,QAAQ,uBAAuB,SAAS;AAC1C,CAAC;AAEH,MAAa,0BACXA,IAAAA,QAAI,OAAO,EACT,iBAAiB,aACnB,CAAC;;;AChSH,MAAa,cACX,SACA,eAAe,SACU;CACzB,MAAM,2BAA2B,QAAQ,IAAI;CAC7C,MAAM,+BAA+B,QAAQ,IAAI;CACjD,MAAM,oCACJ,QAAQ,IAAI;CACd,MAAM,gCACJ,QAAQ,IAAI;CACd,MAAM,+BAA+B,QAAQ,IAAI;CACjD,MAAM,wBAAwB,QAAQ,IAAI;CAC1C,MAAM,+BAA+B,QAAQ,IAAI;CACjD,MAAM,yBAAyB,QAAQ,IAAI;CAC3C,MAAM,8BAA8B,QAAQ,IAAI;CAChD,MAAM,yCACJ,QAAQ,IAAI;CACd,MAAM,4BAA4B,QAAQ,IAAI;CAC9C,MAAM,6BAA6B,QAAQ,IAAI;CAC/C,MAAM,+BAA+B,QAAQ,IAAI;CACjD,MAAM,0BAA0B,QAAQ,IAAI;CAC5C,MAAM,4BAA4B,QAAQ,IAAI;CAC9C,MAAM,iCACJ,QAAQ,IAAI;CACd,MAAM,kCACJ,QAAQ,IAAI;CACd,MAAM,yBAAyB,QAAQ,IAAI;CAC3C,MAAM,0CACJ,QAAQ,IAAI;CACd,MAAM,mCACJ,QAAQ,IAAI;CACd,MAAM,iCACJ,QAAQ,IAAI;CACd,MAAM,mCACJ,QAAQ,IAAI;CACd,MAAM,6CACJ,QAAQ,IAAI;CACd,MAAM,6CACJ,QAAQ,IAAI;CACd,MAAM,qCACJ,QAAQ,IAAI;CACd,MAAM,qCACJ,QAAQ,IAAI;CACd,MAAM,uCACJ,QAAQ,IAAI;CACd,MAAM,0CACJ,QAAQ,IAAI;CACd,MAAM,uCACJ,QAAQ,IAAI;CACd,MAAM,0CACJ,QAAQ,IAAI;CACd,MAAM,2CACJ,QAAQ,IAAI;CACd,MAAM,iCACJ,QAAQ,IAAI;CACd,MAAM,kCACJ,QAAQ,IAAI;CACd,MAAM,sCACJ,QAAQ,IAAI;CACd,MAAM,mCACJ,QAAQ,IAAI;CACd,MAAM,mCACJ,QAAQ,IAAI;CACd,MAAM,qCACJ,QAAQ,IAAI;CACd,MAAM,qCACJ,QAAQ,IAAI;CACd,MAAM,wCACJ,QAAQ,IAAI;CACd,MAAM,gCACJ,QAAQ,IAAI;CACd,MAAM,sCACJ,QAAQ,IAAI;CACd,MAAM,sCACJ,QAAQ,IAAI;CACd,MAAM,0CACJ,QAAQ,IAAI;CACd,MAAM,qCACJ,QAAQ,IAAI;CACd,MAAM,yCACJ,QAAQ,IAAI;CACd,MAAM,8BAA8B,QAAQ,IAAI;CAEhD,MAAM,SAAS,SAAS,UAAU;CAElC,MAAM,MAA4B;EAChC,UAAU,SAAS,YAAY;EAC/B,eAAA,GAAA,8BAAA,kBAAA,CACE,SAAS,gBAAgB,4BAC3B;EACA,kBACE,SAAS,oBACR,qCACD,gBAAgB;EAClB,cAAc,SAAS,gBAAgB;EACvC,SAAS,SAAS;EAClB,kBAAkB,SAAS;EAC3B,cAAc,SAAS;EACvB,cAAc,SAAS,gBAAgB;EACvC,mBAAmB;GACjB,GAAI,SAAS,qBAAqB,CAAC;GACnC,QACE,SAAS,mBAAmB,UAC5B,yBACA,gBAAgB,kBAAkB;GACpC,cACE,SAAS,mBAAmB,gBAC3B,gBAAgB,kBAAkB;GACrC,UAAU,SAAS,mBAAmB,YAAY;EACpD;EACA,WAAW,SAAS;EACpB,cAAc,SAAS,gBAAgB;EACvC,SAAA,GAAA,8BAAA,oBAAA,CAA4B,MAAM;EAClC,QAAQ;GACN,WAAA,GAAA,8BAAA,oBAAA,CACE,SAAS,QAAQ,YACf,+BACA,gBAAgB,OAAO,QAC3B;GACA,oBAAA,GAAA,8BAAA,oBAAA,CACE,SAAS,QAAQ,qBACf,0CACA,gBAAgB,OAAO,iBAC3B;GACA,SAAA,GAAA,8BAAA,oBAAA,CACE,SAAS,QAAQ,UACf,6BACA,gBAAgB,OAAO,MAC3B;GACA,UAAA,GAAA,8BAAA,oBAAA,CACE,SAAS,QAAQ,WACf,8BACA,gBAAgB,OAAO,OAC3B;GACA,WAAA,GAAA,8BAAA,oBAAA,CACE,SAAS,QAAQ,YACf,gCACA,gBAAgB,OAAO,QAC3B;EACF;EACA,WACE,SAAS,cAAA,GAAA,8BAAA,UAAA,CACC,yBAAyB,KACnC,gBAAgB;EAClB,gBACE,SAAS,mBAAA,GAAA,8BAAA,UAAA,CACC,8BAA8B,KACxC,gBAAgB;EAClB,iBACE,SAAS,oBAAA,GAAA,8BAAA,UAAA,CACC,+BAA+B,KACzC,gBAAgB;EAClB,QACE,SAAS,WAAA,GAAA,8BAAA,WAAA,CACE,sBAAsB,KACjC,gBAAgB;EAClB,uBACE,SAAS,yBAAyB;EACpC,kBACE,SAAS,qBAAA,GAAA,8BAAA,WAAA,CACE,gCAAgC,KAC3C,gBAAgB;EAClB,eACE,SAAS,kBAAA,GAAA,8BAAA,WAAA,CACE,8BAA8B,KACzC,gBAAgB;EAClB,iBACE,SAAS,oBAAA,GAAA,8BAAA,WAAA,CACE,gCAAgC,KAC3C,gBAAgB;EAClB,0BACE,SAAS,6BAAA,GAAA,8BAAA,WAAA,CACE,0CAA0C,KACrD,gBAAgB;EAClB,mBACE,SAAS,sBAAA,GAAA,8BAAA,WAAA,CACE,0CAA0C,KACrD,gBAAgB;EAClB,SAAS;GACP,QAAQ;IACN,MACE,SAAS,SAAS,QAAQ,QAC1B,sCACA,gBAAgB,QAAQ,OAAO;IACjC,MACE,SAAS,SAAS,QAAQ,QAC1B,sCACA,gBAAgB,QAAQ,OAAO;IACjC,QACE,SAAS,SAAS,QAAQ,UAC1B;IACF,UACE,SAAS,SAAS,QAAQ,aAAA,GAAA,8BAAA,WAAA,CACf,uCAAuC,KAClD,gBAAgB,QAAQ,OAAO;IACjC,QACE,SAAS,SAAS,QAAQ,WAAA,GAAA,8BAAA,WAAA,CACf,oCAAoC,KAC/C,QAAQ,WAAW,QAAQ;IAC7B,UACE,SAAS,SAAS,QAAQ,YACzB,2CACD,gBAAgB,QAAQ,OAAO;IACjC,YACE,SAAS,SAAS,QAAQ,eAAA,GAAA,8BAAA,WAAA,CACf,wCAAwC,KACnD,gBAAgB,QAAQ,OAAO;GACnC;GACA,SACE,SAAS,SAAS,YAAA,GAAA,8BAAA,WAAA,CACP,8BAA8B,KACzC,gBAAgB,QAAQ;GAC1B,UACE,SAAS,SAAS,aAAA,GAAA,8BAAA,UAAA,CACR,+BAA+B,KACzC,gBAAgB,QAAQ;GAC1B,iBACE,SAAS,SAAS,oBAAA,GAAA,8BAAA,UAAA,CACR,mCAAmC,KAC7C,gBAAgB,QAAQ;GAC1B,OAAO,SAAS,SAAS;EAC3B;EACA,OAAO;GACL,QAAQ;IACN,MACE,SAAS,OAAO,QAAQ,QACxB,oCACA,gBAAgB,MAAM,OAAO;IAC/B,MACE,SAAS,OAAO,QAAQ,QACxB,oCACA,gBAAgB,MAAM,OAAO;IAC/B,QACE,SAAS,OAAO,QAAQ,UAAU;IACpC,UAAU,gBAAgB,MAAM,OAAO;IACvC,QACE,SAAS,OAAO,QAAQ,WAAA,GAAA,8BAAA,WAAA,CACb,kCAAkC,KAC7C,QAAQ,WAAW,QAAQ;IAC7B,UACE,SAAS,OAAO,QAAQ,YACvB,yCACD,gBAAgB,MAAM,OAAO;GACjC;GACA,UACE,SAAS,OAAO,aAAA,GAAA,8BAAA,UAAA,CACN,6BAA6B,KACvC,gBAAgB,MAAM;GACxB,eACE,SAAS,OAAO,kBAAA,GAAA,8BAAA,UAAA,CACN,mCAAmC,KAC7C,gBAAgB,MAAM;EAC1B;EACA,mBACE,SAAS,qBACR,uCACD,gBAAgB;EAClB,uBACE,SAAS,yBACT,yCAAyC,MAAM,GAAG,CAAC,CAChD,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAClB,QAAO,MAAK,EAAE,MAAM,KACvB,gBAAgB;EAClB,aACE,SAAS,eACT,+BACA,gBAAgB;EAClB,UAAU,SAAS,YAAY,gBAAgB;EAC/C,WAAW,SAAS,aAAa,gBAAgB;EACjD,mBACE,SAAS,sBAAA,GAAA,8BAAA,UAAA,CACC,kCAAkC;EAC9C,uBACE,SAAS,0BAAA,GAAA,8BAAA,UAAA,CACC,sCAAsC;EAClD,qBAAqB,SAAS;EAC9B,uBAAuB,SAAS;EAChC,mBAAmB,SAAS;CAC9B;CAEA,MAAM,EAAE,OAAO,UAAU,cAAc,SAAS,KAAK,EAAE,YAAY,MAAM,CAAC;CAE1E,MAAM,cAAsC;EAC1C,cAAc;EACd,UAAU;EACV,cAAc;EACd,QAAQ;EACR,cAAc;CAChB;CAEA,IAAI,OAAO;EACT,IAAI,cACF,MAAM,IAAIC,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;EAI7D,QAAQ,KACN,mFACF;EACA,MAAM,QAAQ,SAAQ,WAAU;GAC9B,IAAI,OAAO,SAAS,OAAO,YAAY,OAAO,QAAQ,MAEpD,QAAQ,KACN,YAAY,OAAO,QAAQ,IAAI,SAAS,YAAY,OAAO,QAAQ,KAAK,yCAC1E;EAEJ,CAAC;CACH;CAEA,OAAO;AACT;;;;;;ACnQA,IAAa,sBAAb,MAAiC;CAa/B,YAAY,gBAAmC;EAFpB,KAAA,mBAAA;EAGzB,KAAK,UAAU,WAAW,gBAAgB,KAAK;EAC/C,KAAK,aAAa,IAAIC,qBAAAA,oBACpB,KAAK,QAAQ,cACb,KAAK,QAAQ,UACb;GACE,cAAc,KAAK,QAAQ;GAC3B,yBAAyB,KAAK,QAAQ;GACtC,kBAAkB,KAAK,QAAQ;GAC/B,cAAc,KAAK,QAAQ;GAC3B,kBAAkB,KAAK,QAAQ;GAC/B,cAAc,KAAK,QAAQ;GAC3B,SAAS,KAAK,QAAQ;GACtB,iBAAiB,KAAK,QAAQ;GAC9B,mBAAmB,KAAK,QAAQ;GAChC,uBAAuB,KAAK,QAAQ;EACtC,CACF;EACA,KAAK,SAAA,GAAA,MAAA,QAAA,CAAa,KAAK,QAAQ,QAAQ;EACvC,KAAK,eAAe,IAAI,sBAAsB,KAAK,OAAO;EAC1D,KAAK,iBAAiB,IAAI,wBAAwB,KAAK,OAAO;;EAG9D,IAAI,QAAQ,IAAI,SAAS,CAAC,KAAK,MAAM,SACnC,MAAA,QAAK,OAAO,QAAQ,IAAI,KAAK;EAG/B,KAAK,MAAM,wBAAwB;CACrC;;;;;;;;;;;;;;CAeA,MAAM,OACJ,SACA,UACA,eACc;EACd,KAAK,MAAM,0BAA0B;EACrC,IAAI;GACF,KAAK,gBAAgB;GAErB,SAAS,WAAW;GAEpB,MAAM,EAAE,WAAW,MAAM,QAAQ,cAAc;GAE/C,IAAI,OAAO,YAAY,MAAM,OAAO;IAClC,SAAS,iBAAiB;IAC1B,OAAO,SAAS,KAAK;GACvB;GAEA,MAAM,oBAAoB,KAAK,QAAQ,WACnC,KAAI,MAAK,EAAE,QAAQ,CAAC,CACrB,QAAO,MAAK,CAAC,CAAC,CAAC,CAAC,CAChB,QAAQ,KAAK,MAAM,GAAG,IAAI,GAAG,KAAK,EAAE;GACvC,MAAM,kBAAkB,KAAK,QAAQ,WACjC,KAAI,MAAK,EAAE,MAAM,CAAC,CACnB,QAAO,MAAK,CAAC,CAAC,CAAC,CAAC,CAChB,QAAQ,KAAK,MAAM,GAAG,IAAI,GAAG,KAAK,EAAE;GAEvC,MAAM,gBAAA,GAAA,2BAAA,YAAA,EAAA,GAAA,8BAAA,oBAAA,CACgB,eAAe,YAAY,MAAM,IAAA,GAAA,8BAAA,oBAAA,CACjC,KAAK,QAAQ,kBAAkB,MAAM,IAAA,GAAA,8BAAA,oBAAA,CACrC,eAAe,CACrC,KAAK,CAAC,QAAQ;GAEd,MAAM,mBAAA,GAAA,2BAAA,YAAA,EAAA,GAAA,8BAAA,oBAAA,CACgB,eAAe,YAAY,QAAQ,IAAA,GAAA,8BAAA,oBAAA,CACnC,KAAK,QAAQ,kBAAkB,QAAQ,IAAA,GAAA,8BAAA,oBAAA,CACvC,iBAAiB,CACvC;GAGA,MAAM,MAAM;IACV,GAAI,iBAAiB,CAAC;IACtB,YAAY;KACV,GAAG,KAAK,QAAQ;KAChB,GAAG,eAAe;KAClB,QAAQ,aAAa,KAAK,GAAG;KAC7B,YAAA,GAAA,2BAAA,YAAA,CACE,eAAe,YAAY,WAC3B,KAAK,QAAQ,kBAAkB,SACjC;KACA,UAAU,iBAAiB,KAAK,GAAG;IACrC;GACF;GAEA,IAAI,WAA6B,CAAC;GAGlC,IAAI,KAAK,QAAQ,uBAAuB;IACtC,WAAW,MAAM,KAAK,QAAQ,sBAAsB,OAAO;IAG3D,IACE,aAAa,QACb,aAAa,KAAA,KACb,OAAO,aAAa,YACpB,MAAM,QAAQ,QAAQ,GAEtB,MAAM,IAAIC,qBAAAA,yBACR,2DACF;GAEJ;GAEA,MAAM,QAAQ,KAAK,QAAQ,2BACvB;IACE,WAAW,QAAQ,SAAS,YAAY;IACxC,mBAAmB,QAAQ,SACzB,oBACF;IACA,OAAO,QAAQ,SAAS,OAAO;IAC/B,UAAU,QAAQ,SAAS,UAAU;IACrC,SAAS,QAAQ,SAAS,SAAS;IACnC,WAAW,QAAQ,SAAS,YAAY;IACxC,WAAW,QAAQ,SAAS,YAAY;IACxC,WAAW,QAAQ,SAAS,YAAY;IACxC,QAAQ,QAAQ,SAAS,QAAQ;IACjC,UAAU,QAAQ,SAAS,UAAU;IACrC,aAAa,QAAQ,SAAS,eAAe;IAC7C,QAAQ,SAAS,QAAQ,SAAS,SAAS,GAAa,EAAE;GAC5D,IACA,CAAC;GAGL,MAAM,SAAS,MAAM,aAAa,IAAI;GACtC,IACE,OAAO,WAAW,YAClB,WACC,EAAA,GAAA,8BAAA,cAAA,CAAe,MAAM,MAAA,GAAA,8BAAA,WAAA,CAAgB,KAAK,QAAQ,QAAQ,MAAM,IAEjE,IAAI,YAAY;GAIlB,MAAM,EAAE,UAAU,oBAAoB,SAAS,KAAK,EAAE,YAAY,KAAK,CAAC;GAExE,IAAI,OACF,MAAM,IAAIA,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;GAI7D,MAAM,SAAA,GAAA,2BAAA,cAAA,CAAsB;GAC5B,MAAM,SAAA,GAAA,2BAAA,cAAA,CAAsB;GAC5B,MAAM,EAAE,eAAe,iBAAiB,OAAA,GAAA,2BAAA,aAAA,CAAmB;GAG3D,IAAI,CAAC,MAAM,MAAM,MAAO,GACtB,IAAI,WAAW,SAAS,MAAM;GAIhC,MAAM,YAAY,mBAChB,IAAI,aAAa,KAAK,QAAQ,MAChC;GAKA,IAAI,SAA8B;IAChC,aAAa,GAJQ,KAAK,QAAQ,UAAA,GAAA,8BAAA,mBAAA,CAA4B,KAAK,QAAQ,OAAO,QAAQ;IAK1F,GAAG,IAAI;IACP;IACA;IACA;GACF;GAGA,MAAM,oBACJ,MAAM,qBAAqB,IAAI,WAAW;GAC5C,IAAI,OAAO,sBAAsB,YAAY,mBAC3C,OAAO,oBAAoB;GAG7B,MAAM,UACH,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA,MACjD,IAAI,WAAW;GAEjB,IAAI,QAAQ;IACV,MAAM,EAAE,OAAO,MAAM,uBAAuB,SAAS,QAAQ,EAC3D,YAAY,KACd,CAAC;IAED,IAAI,CAAC,GACH,OAAO,SAAS;GAEpB;GAEA,MAAM,YACH,OAAO,MAAM,aAAa,WAAW,MAAM,WAAW,KAAA,MACvD,IAAI,WAAW;GAGjB,IAAI,UAAU;IACZ,MAAM,EAAE,OAAO,MAAM,yBAAyB,SAAS,UAAU,EAC/D,YAAY,KACd,CAAC;IAED,IAAI,CAAC,GACH,OAAO,WAAW;GAEtB;GAGA,MAAM,UAAU,MAAM,WAAW,IAAI,WAAW;GAChD,IAAI,OAAO,YAAY,YAAY,SACjC,OAAO,UAAU;GAInB,MAAM,YAAY,MAAM,aAAa,IAAI,WAAW;GACpD,IAAI,OAAO,cAAc,YAAY,WACnC,OAAO,YAAY;GAIrB,MAAM,YAAY,MAAM,aAAa,IAAI,WAAW;GACpD,IAAI,OAAO,cAAc,YAAY,WACnC,OAAO,YAAY,UAChB,MAAM,GAAG,CAAC,CACV,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAClB,QAAO,MAAK,MAAM,EAAE;GAIzB,MAAM,YAAY,MAAM,aAAa,IAAI,WAAW;GACpD,IAAI,OAAO,cAAc,YAAY,WACnC,OAAO,YAAY;GAIrB,MAAM,WAAW,MAAM,YAAY,IAAI,WAAW;GAClD,IAAI,OAAO,aAAa,YAAY,UAClC,OAAO,WAAW;GAIpB,MAAM,cAAc,MAAM,eAAe,IAAI,WAAW;GACxD,IAAI,OAAO,gBAAgB,YAAY,aACrC,OAAO,cAAc;GAIvB,IAAI;GACJ,IAAI,OAAO,MAAM,WAAW,UAC1B,SAAS,MAAM;QAEf,SAAS,IAAI,WAAW,WAAW,IAAI,WAAW;GAGpD,IAAI,QACF,OAAO,SAAS;;GAIlB,IAAI,CAAC,OAAO,UAAU,OAAO,OAAO,WAAW,GAC7C,MAAM,IAAIA,qBAAAA,yBACR,oCACF;GAIF,MAAM,iBAAiC;IACrC;IACA;IACA;IACA;IACA,QAAQ,IAAI,WAAW;IACvB,UAAU,KAAK,UAAU,QAAQ;IACjC,UAAU,KAAK,QAAQ,kBAAkB;IACzC,QAAQ,OAAO;GACjB;GAEA,IAAI,KAAK,QAAQ,QAAQ;IACvB,MAAM,EAAE,gBACN,MAAM,KAAK,WAAW,2BAA2B,MAAM;IAEzD,SAAS,EACP,YAAY,YACd;GACF;GAGA,MAAM,UAAU,MAAM,KAAK,WAAW,iBAAiB,MAAM;GAG7D,MAAM,KAAK,aAAa,SACtB,SACA,UACA,gBACA,OAAO,iBAAiB,cAAc,SAAS,KAAA,CACjD;GAEA,SAAS,SAAS,OAAO;EAC3B,SAAS,OAAO;GACd,IAAI,OAAO,eAAe,YAAY,YACpC,OAAO,cAAc,QAAQ,KAAc;QAE3C,KAAK,eAAe,OAAgB,QAAQ;EAEhD;EAEA,OAAO,SAAS,KAAK;CACvB;;;;;;;;;;;;;;CAeA,MAAM,SACJ,SACA,UACA,iBACc;EACd,KAAK,MAAM,2BAA2B;EAEtC,IAAI;GACF,KAAK,gBAAgB;GAErB,SAAS,WAAW;GAEpB,MAAM,EAAE,QAAQ,KAAK,SAAS,MAAM,QAAQ,cAAc;GAE1D,IAAI,OAAO,YAAY,MAAM,SAAS,OAAO,YAAY,MAAM,QAAQ;IACrE,SAAS,iBAAiB;IAC1B,OAAO,SAAS,KAAK;GACvB;GAGA,IAAI,iBAAiB;IACnB,MAAM,EAAE,UAAU,sBAAsB,SAAS,iBAAiB,EAChE,YAAY,KACd,CAAC;IAED,IAAI,OACF,MAAM,IAAIA,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;GAE/D;GAEA,IAAI,UAAU;GAGd,IAAI,EAAA,GAAA,8BAAA,cAAA,CAAe,GAAG,GACpB,UAAU,GAAG,KAAK,QAAQ,UAAA,GAAA,8BAAA,mBAAA,CAA4B,GAAG;GAU3D,MAAM,kBAAA,GAAA,2BAAA,oBAAA,CALJ,OAAO,YAAY,MAAM,SACrB,IAAI,gBAAgB,IAAI,IACxB,IAAI,IAAI,OAAO,CAAC,CAAC,YAG2B;GAKlD,MAAM,iBAAiB,eAAe,QAClC,MAAM,KAAK,aAAa,SACtB,SACA,UACA,eAAe,KACjB,IACA,KAAA;GAGJ,IAAI,CAAC,gBACH,MAAM,IAAIA,qBAAAA,yBAAyB,8BAA8B;GAGnE,IAAI,eAAe,UAAU,eAAe,OAC1C,MAAM,IAAIA,qBAAAA,yBAAyB,eAAe;GAGpD,KAAA,GAAA,8BAAA,UAAA,CAAc,eAAe,KAAK,GAChC,MAAM,IAAIC,qBAAAA,iBAER,eAAe,OACf,eAAe,gBACjB;GAIF,MAAM,cACJ,iBAAiB,eACjB,GAAG,KAAK,QAAQ,UAAA,GAAA,8BAAA,mBAAA,CAA4B,KAAK,QAAQ,OAAO,QAAQ;GAE1E,IAAI,CAAC,eAAe,MAClB,MAAM,IAAID,qBAAAA,yBACR,iDACF;GAIF,MAAM,WAA6B,KAAK,MAAM,eAAe,QAAQ;GAErE,MAAM,UAAU,MAAM,KAAK,WAAW,aACpC,eAAe,MACf,aACA,eAAe,QACf,eAAe,UACf;IACE,cAAc,eAAe;IAC7B,iBAAiB;IACjB,kBAAkB,KAAK,QAAQ;IAC/B,cAAc,eAAe;IAC7B,eAAe,eAAe;IAC9B,uBAAuB,KAAK,QAAQ;IACpC,eACE,iBAAiB,iBAAiB,KAAK,QAAQ;IACjD,uBAAuB,KAAK,QAAQ;IACpC,mBAAmB,OAAO,GAAG,GAAG,MAC9B,MAAM,KAAK,QAAQ,oBAAoB,GAAG,GAAG,GAAG,QAAQ;GAC5D,CACF;GAGA,MAAM,KAAK,eAAe,WAAW,SAAS,UAAU,OAAO;GAI/D,MAAM,KAAK,aAAa,gBAAgB,SAAS,QAAQ;GAGzD,IAAI,CAAC,eAAe,WAAW;IAC7B,SAAS,SAAS,KAAK,QAAQ,MAAM;IACrC,OAAO,SAAS,KAAK;GACvB;GAGA,IAAI;IACF,MAAM,aAAa,mBAAmB,eAAe,SAAS;IAE9D,IAAI,EAAA,GAAA,8BAAA,cAAA,CAAe,UAAU,GAAG;KAC9B,SAAS,SACP,GAAG,KAAK,QAAQ,UAAA,GAAA,8BAAA,mBAAA,CAA4B,UAAU,GACxD;KACA,OAAO,SAAS,KAAK;IACvB;IAEA,KAAA,GAAA,8BAAA,WAAA,CAAe,KAAK,QAAQ,QAAQ,UAAU,GAAG;KAC/C,SAAS,SAAS,UAAU;KAC5B,OAAO,SAAS,KAAK;IACvB;GACF,QAAQ,CAER;GAEA,SAAS,SAAS,KAAK,QAAQ,MAAM;EACvC,SAAS,OAAO;GACd,IAAI,OAAO,iBAAiB,YAAY,YACtC,OAAO,gBAAgB,QAAQ,KAAc;QAE7C,KAAK,eAAe,OAAgB,QAAQ;EAEhD;EAEA,OAAO,SAAS,KAAK;CACvB;;;;;;;;;;;;CAaA,MAAM,SACJ,SACA,UACA,iBACc;EACd,KAAK,MAAM,2BAA2B;EAEtC,IAAI;GACF,KAAK,gBAAgB;GAErB,MAAM,EAAE,WAAW,MAAM,QAAQ,cAAc;GAE/C,IAAI,OAAO,YAAY,MAAM,OAAO;IAClC,SAAS,iBAAiB;IAC1B,OAAO,SAAS,KAAK;GACvB;GAGA,IAAI,iBAAiB;IACnB,MAAM,EAAE,UAAU,sBAAsB,SAAS,iBAAiB,EAChE,YAAY,KACd,CAAC;IAED,IAAI,OACF,MAAM,IAAIA,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;GAE/D;GAMA,MAAM,mBAJQ,KAAK,QAAQ,2BACvB,EAAE,UAAA,GAAA,8BAAA,WAAA,CAAoB,QAAQ,SAAS,SAAS,CAAW,EAAE,IAC7D,CAAC,EAAA,CAGG,WACN,iBAAiB,WACjB,KAAK,QAAQ;GAGf,MAAM,UAAU,MAAM,KAAK,eAAe,WACxC,SACA,UACA,CAAC,eACH;GAGA,IAAI,CAAC,SAAS;IACZ,SAAS,WAAW;IACpB,SAAS,UAAU;IACnB,OAAO,SAAS,KAAK;GACvB;GAEA,MAAM,gBAAA,GAAA,8BAAA,UAAA,CACJ,QAAQ,cACR,KAAK,QAAQ,kBAAkB,UAC/B,QAAQ,gBACV;GAGA,IAAI,CAAC,mBAAmB,CAAC,cAAc;IACrC,SAAS,SAAS,QAAQ,IAAI;IAC9B,OAAO,SAAS,KAAK;GACvB;GAGA,MAAM,aAAa,MAAM,KAAK,WAAW,gBACvC,cACA,SACA;IACE,mBAAmB,KAAK,QAAQ,mBAAmB,KAAK,IAAI;IAC5D,mBAAmB,KAAK,QAAQ;GAClC,CACF;GAUA,IAAI,CAAC,MAPiB,KAAK,eAAe,cACxC,SACA,UACA,UACF,GAGc;IACZ,SAAS,WAAW;IACpB,SAAS,UAAU;IACnB,OAAO,SAAS,KAAK;GACvB;GAGA,SAAS,SAAS,WAAW,IAAI;EACnC,SAAS,OAAO;GACd,IAAI,OAAO,iBAAiB,YAAY,YACtC,OAAO,gBAAgB,QAAQ,KAAc;QAE7C,KAAK,eAAe,OAAgB,QAAQ;EAEhD;EAEA,OAAO,SAAS,KAAK;CACvB;;;;;;;;;;CAWA,MAAM,QACJ,SACA,UACA,gBACc;EACd,KAAK,MAAM,2BAA2B;EAEtC,IAAI;GACF,KAAK,gBAAgB;GAErB,SAAS,WAAW;GAEpB,MAAM,EAAE,WAAW,MAAM,QAAQ,cAAc;GAE/C,IAAI,OAAO,YAAY,MAAM,OAAO;IAClC,SAAS,iBAAiB;IAC1B,OAAO,SAAS,KAAK;GACvB;GAGA,IAAI,gBAAgB;IAClB,MAAM,EAAE,UAAU,qBAAqB,SAAS,gBAAgB,EAC9D,YAAY,KACd,CAAC;IAED,IAAI,OACF,MAAM,IAAIA,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;GAE/D;GAEA,MAAM,QAAQ,KAAK,QAAQ,2BACvB;IACE,eAAe,QAAQ,SAAS,iBAAiB;IACjD,YAAA,GAAA,8BAAA,WAAA,CAAsB,QAAQ,SAAS,WAAW,CAAW;IAC7D,aAAa,QAAQ,SAAS,eAAe;GAC/C,IACA,CAAC;GAGL,IAAI,YACF,KAAK,QAAQ,yBACb,gBAAgB,yBAChB,KAAK,QAAQ;GAGf,IAAI,MAAM,eAAe;IACvB,MAAM,EAAE,UAAU,qBAAqB,SAAS,EAC9C,uBAAuB,MAAM,cAC/B,CAAC;IAED,IAAI,CAAC,OACH,YAAY,MAAM;GAEtB;GAGA,IAAI,EAAA,GAAA,8BAAA,cAAA,CAAe,SAAS,GAC1B,YAAY,GAAG,KAAK,QAAQ,UAAA,GAAA,8BAAA,mBAAA,CAA4B,SAAS;GAInE,MAAM,UAAU,MAAM,KAAK,eAAe,WACxC,SACA,UACA,KACF;GAGA,IAAI,CAAC,SAAS;IACZ,SAAS,SAAS,SAAS;IAC3B,OAAO,SAAS,KAAK;GACvB;GAEA,MAAM,KAAK,eAAe,cAAc,SAAS,QAAQ;GAIzD,MAAM,KAAK,aAAa,gBAAgB,SAAS,QAAQ;GAQzD,IAAI,EAJF,MAAM,aACN,gBAAgB,oBAChB,KAAK,QAAQ,mBAEU;IACvB,SAAS,SAAS,SAAS;IAC3B,OAAO,SAAS,KAAK;GACvB;GAIA,MAAM,eACH,OAAO,MAAM,gBAAgB,YAAY,MAAM,cAC5C,MAAM,cACN,KAAA,MACJ,gBAAgB,eAChB,QAAQ;GAGV,MAAM,MAAM,MAAM,KAAK,WAAW,cAAc;IAC9C;IACA,uBAAuB;IACvB,OAAO,gBAAgB;GACzB,CAAC;GAGD,SAAS,SAAS,GAAG;EACvB,SAAS,OAAO;GACd,IAAI,OAAO,gBAAgB,YAAY,YACrC,OAAO,eAAe,QAAQ,KAAc;QAE5C,KAAK,eAAe,OAAgB,QAAQ;EAEhD;EAEA,OAAO,SAAS,KAAK;CACvB;;;;;;;;;;;;;CAcA,MAAM,kBACJ,SACA,UACA,0BACc;EACd,KAAK,MAAM,sCAAsC;EAEjD,IAAI,qBAAqB;EAEzB,IAAI;GACF,KAAK,gBAAgB;GAErB,SAAS,WAAW;GAEpB,IAAI,CAAC,KAAK,QAAQ,qBAAqB;IACrC,SAAS,SAAS;IAClB,OAAO,SAAS,KAAK;GACvB;GAEA,MAAM,EAAE,QAAQ,SAAS,MAAM,QAAQ,cAAc;GAErD,IAAI,OAAO,YAAY,MAAM,QAAQ;IACnC,SAAS,iBAAiB;IAC1B,OAAO,SAAS,KAAK;GACvB;GAGA,MAAM,cAAc,IADD,gBAAgB,IACV,CAAC,CAAC,IAAI,cAAc;GAE7C,IAAI,CAAC,aAAa;IAChB,qBAAqB;IACrB,MAAM,IAAIA,qBAAAA,yBAAyB,sBAAsB;GAC3D;GAEA,IAAI;GAEJ,IAAI;IACF,UAAU,MAAM,KAAK,WAAW,oBAC9B,aACA,KAAK,QAAQ,WACb,KAAK,QAAQ,cACf;GACF,SAAS,OAAO;IACd,qBAAqB,iBAAiBE,qBAAAA;IACtC,MAAM;GACR;GAEA,MAAM,EAAE,KAAK,QAAQ;GAErB,MAAM,KAAK,QAAQ,oBAAoB,KAAK,GAAG;GAE/C,SAAS,UAAU;EACrB,SAAS,OAAO;GACd,IAAI,OAAO,0BAA0B,YAAY,YAC/C,OAAO,yBAAyB,QAAQ,KAAc;QACjD,IAAI,oBAAoB;IAE7B,QAAQ,MAAM,KAAK;IACnB,SAAS,SACP;KACE,OAAO;KACP,mBAAmB;IACrB,GACA,GACF;GACF,OACE,KAAK,eAAe,OAAgB,QAAQ;EAEhD;EAEA,OAAO,SAAS,KAAK;CACvB;;;;;;;;;;CAWA,MAAM,gBACJ,SACA,UACkB;EAKlB,OAAO,CAAC,EAAC,MAHa,KAAK,eAAe,WAAW,SAAS,QAAQ,EAAA,EAGpD;CACpB;;;;;;;;;;;;CAaA,MAAM,cACJ,SACA,UACA,QACA,aACA,UACkB;EAClB,MAAM,UAAU,MAAM,KAAK,eAAe,WAAW,SAAS,QAAQ;EAEtE,IAAI,CAAC,SAAS,MACZ,OAAO;EAGT,QAAA,GAAA,2BAAA,cAAA,CACE,QAAQ,MACR,QACA,eAAe,KAAK,QAAQ,aAC5B,QACF;CACF;;;;;;;;;;CAWA,MAAM,WACJ,SACA,UACA,SACuC;EACvC,IAAI,SAAS;GACX,MAAM,EAAE,UAAU,wBAAwB,SAAS,SAAS,EAC1D,YAAY,KACd,CAAC;GAED,IAAI,OACF,MAAM,IAAIF,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;EAE/D;EAEA,MAAM,UAAU,MAAM,KAAK,eAAe,WAAW,SAAS,QAAQ;EAEtE,IAAI,CAAC,SAAS,mBAAmB,CAAC,SAChC,OAAO;EAGT,MAAM,gBAAA,GAAA,8BAAA,UAAA,CACJ,QAAQ,cACR,KAAK,QAAQ,kBAAkB,UAC/B,QAAQ,gBACV;EAEA,IAAI,CAAC,cACH,MAAM,IAAIA,qBAAAA,yBAAyB,wBAAwB;EAG7D,MAAM,aAAa,MAAM,KAAK,WAAW,gBACvC,cACA,SACA;GACE,mBAAmB,KAAK,QAAQ,mBAAmB,KAAK,IAAI;GAC5D,mBAAmB,KAAK,QAAQ;EAClC,CACF;EAEA,MAAM,KAAK,eAAe,cAAc,SAAS,UAAU,UAAU;EAErE,OAAO;CACT;;;;;;;;CASA,MAAM,cACJ,SACA,UACA,SACe;EACf,MAAM,KAAK,eAAe,cAAc,SAAS,UAAU,OAAO;CACpE;;;;;;CAOA,aAAmC;EACjC,OAAO,EAAE,GAAG,KAAK,QAAQ;CAC3B;;;;;;;;;;CAWA,eACE,SACA,UACe;EACf,OAAO,KAAK,eAAe,cAAc,SAAS,QAAQ;CAC5D;;;;;;;;;;;;CAaA,MAAM,UACJ,SACA,UACA,SAC0B;EAE1B,IAAI,SAAS;GACX,MAAM,EAAE,UAAU,uBAAuB,SAAS,SAAS,EACzD,YAAY,KACd,CAAC;GAED,IAAI,OACF,MAAM,IAAIA,qBAAAA,yBAAyB,MAAM,QAAQ,EAAE,CAAC,OAAO;EAE/D;EAGA,MAAM,UAAU,MAAM,KAAK,eAAe,WAAW,SAAS,QAAQ;EAEtE,IAAI,CAAC,SACH,MAAM,IAAIA,qBAAAA,yBAAyB,wBAAwB;EAG7D,IAAI,SAAS,SAAS;EAEtB,MAAM,WACJ,SAAS,YAAY,KAAK,QAAQ,kBAAkB;EAEtD,KAAA,GAAA,8BAAA,UAAA,CAAc,SAAS,QAAQ,GACzB;OAAA,EAAA,GAAA,8BAAA,UAAA,CAAW,MAAM,GAWf;QAAA,CAToB,KAAK,QAAQ,WAAW,MAC9C,OAAA,GAAA,8BAAA,UAAA,EAAA,GAAA,8BAAA,uBAAA,CAE2B,EAAE,QAAQ,IAAA,GAAA,8BAAA,uBAAA,CACV,QAAQ,CACjC,KAAK,CAAC,EAAE,MACZ,GAIE,SAAS,KAAK,QAAQ,WAAW,MAAK,OAAA,GAAA,8BAAA,UAAA,EAAA,GAAA,8BAAA,uBAAA,CAEX,EAAE,QAAQ,IAAA,GAAA,8BAAA,uBAAA,CACV,QAAQ,CACjC,CACF,CAAC,EAAE;GAAA;EACL;EAIJ,MAAM,kBACJ,EAAA,GAAA,8BAAA,UAAA,CAAW,SAAS,QAAQ,KAAK,EAAA,GAAA,8BAAA,UAAA,CAAW,MAAM,IAC9C,QAAQ,mBACR;EAEN,IAAI,SAAA,GAAA,8BAAA,UAAA,CAAkB,QAAQ,cAAc,UAAU,eAAe;EAErE,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,wBAAwB,MAAA,GAAA,8BAAA,IAAA,CAAS;EAEvE,IAAI,EAAE,YAAY;EAClB,IAAI,EAAE,iBAAiB;EAEvB,IAAI,SAAS,gBAAgB,CAAC,SAAS,cAAc;GACnD,IAAI,CAAC,gBAAgB,SAAS,cAC5B,MAAM,IAAIE,qBAAAA,oBACR,gEACF;GAGF,MAAM,iBAAiB,MAAM,KAAK,WAAW,eAAe,SAAS;IACnE,eAAe,SAAS,mBAAmB,KAAK,QAAQ;IACxD,iBAAiB;IACjB,kBAAkB,KAAK,QAAQ;IAC/B,uBAAuB,KAAK,QAAQ;IACpC,qBAAqB;KACnB;KACA;IACF;IACA,uBAAuB,KAAK,QAAQ;IACpC,mBAAmB,KAAK,QAAQ,mBAAmB,KAAK,IAAI;IAC5D,mBAAmB,KAAK,QAAQ;GAClC,CAAC;GAED,MAAM,KAAK,eAAe,cACxB,SACA,UACA,cACF;GAEA,SAAA,GAAA,8BAAA,UAAA,CACE,gBAAgB,cAChB,UACA,eACF;GAEA,UAAU,eAAe;GACzB,eAAe,eAAe;EAChC;;EAIA,IAAI,CAAC,OACH,MAAM,IAAIF,qBAAAA,yBAAyB,wBAAwB;EAG7D,OAAO;GACL,GAAG;GACH;GACA;GACA,WAAW,MAAM,wBAAwB,MAAA,GAAA,8BAAA,IAAA,CAAS;EACpD;CACF;CAEA,eAAuB,OAAc,KAA8B;EAEjE,QAAQ,MAAM,KAAK;EACnB,IAAI,oBAAoB;CAC1B;CAEA,kBAAgC;EAC9B,IAAI,CAAC,KAAK,kBAAkB;GAC1B,KAAK,mBAAmB;GACxB,WAAW,KAAK,OAAO;EACzB;CACF;AACF"}