{"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/checkout.ts","../src/utils.ts","../src/portal.ts","../src/cancel-subscription.ts","../src/retrieve-subscription.ts","../src/search-transactions.ts","../src/has-active-subscription.ts","../src/webhook.ts","../src/hooks.ts","../src/creem-server.ts"],"sourcesContent":["import { BetterAuthPlugin, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { getSchema } from \"./schema.js\";\nimport { createCheckoutEndpoint } from \"./checkout.js\";\nimport { createPortalEndpoint } from \"./portal.js\";\nimport { createCancelSubscriptionEndpoint } from \"./cancel-subscription.js\";\nimport { createRetrieveSubscriptionEndpoint } from \"./retrieve-subscription.js\";\nimport { createSearchTransactionsEndpoint } from \"./search-transactions.js\";\nimport { createHasAccessGrantedEndpoint } from \"./has-active-subscription.js\";\nimport { createWebhookEndpoint } from \"./webhook.js\";\nimport { CreemOptions } from \"./types.js\";\n\n// Export plugin configuration types\nexport type {\n  CreemOptions,\n  GrantAccessContext,\n  RevokeAccessContext,\n  GrantAccessReason,\n  RevokeAccessReason,\n  FlatCheckoutCompleted,\n  FlatRefundCreated,\n  FlatDisputeCreated,\n  FlatSubscriptionEvent,\n} from \"./types.js\";\n\n// Export checkout types\nexport type {\n  CreateCheckoutInput,\n  CreateCheckoutResponse,\n  CheckoutCustomer,\n  CustomFieldInput,\n  TextFieldConfig,\n  CheckboxFieldConfig,\n} from \"./checkout-types.js\";\n\n// Export portal types\nexport type { CreatePortalInput, CreatePortalResponse } from \"./portal-types.js\";\n\n// Export subscription types\nexport type {\n  CancelSubscriptionInput,\n  CancelSubscriptionResponse,\n} from \"./cancel-subscription-types.js\";\n\nexport type { RetrieveSubscriptionInput, SubscriptionData } from \"./retrieve-subscription-types.js\";\n\n// Export transaction types\nexport type {\n  SearchTransactionsInput,\n  SearchTransactionsResponse,\n  TransactionData,\n} from \"./search-transactions-types.js\";\n\n// Export discount types\nexport type {\n  DiscountEntity,\n  DiscountStatus,\n  DiscountType,\n  DiscountDuration,\n} from \"@creem_io/webhook-types\";\n\n// Export access check types\nexport type { HasAccessGrantedResponse } from \"./has-active-subscription-types.js\";\n\n// Export server utilities and types\nexport type { CreemServerConfig } from \"./creem-server.js\";\nexport {\n  createCreemClient,\n  isActiveSubscription,\n  formatCreemDate,\n  getDaysUntilRenewal,\n  validateWebhookSignature,\n  createCheckout,\n  createPortal,\n  cancelSubscription,\n  retrieveSubscription,\n  searchTransactions,\n  checkSubscriptionAccess,\n  getActiveSubscriptions,\n} from \"./creem-server.js\";\n\n/**\n * Creem Better-Auth plugin for payment and subscription management.\n *\n * Provides endpoints for:\n * - `createCheckout` - Create a checkout session for a product\n * - `createPortal` - Create a customer portal session\n * - `cancelSubscription` - Cancel an active subscription\n * - `retrieveSubscription` - Get subscription details\n * - `searchTransactions` - Search transaction history\n * - `hasAccessGranted` - Check if user has an active subscription\n *\n * @param options - Plugin configuration options\n * @returns BetterAuth plugin configuration\n *\n * @example\n * ```typescript\n * import { creem } from \"@creem_io/better-auth\";\n *\n * export const auth = betterAuth({\n *   plugins: [\n *     creem({\n *       apiKey: process.env.CREEM_API_KEY!,\n *       testMode: true,\n *       defaultSuccessUrl: \"/success\",\n *       onGrantAccess: async ({ customer, product, metadata }) => {\n *         // Grant user access to your platform\n *       },\n *       onRevokeAccess: async ({ customer, product, metadata }) => {\n *         // Revoke user access\n *       }\n *     })\n *   ]\n * });\n * ```\n */\nexport const creem = (options: CreemOptions) => {\n  const serverURL = options.testMode ? \"https://test-api.creem.io\" : \"https://api.creem.io\";\n\n  const creem = new Creem({\n    apiKey: options.apiKey,\n    serverURL,\n  });\n\n  if (!options.apiKey) {\n    logger.warn(\n      \"[creem] API key is not set. The plugin will initialize, but API functionality will not work until an API key is provided.\",\n    );\n  }\n\n  logger.debug(\n    `[creem] Plugin initialized (${options.testMode ? \"test\" : \"production\"} mode, persistence: ${options.persistSubscriptions !== false}, webhook: ${!!options.webhookSecret})`,\n  );\n\n  return {\n    id: \"creem\",\n    endpoints: {\n      createCheckout: createCheckoutEndpoint(creem, options),\n      createPortal: createPortalEndpoint(creem, options),\n      cancelSubscription: createCancelSubscriptionEndpoint(creem, options),\n      retrieveSubscription: createRetrieveSubscriptionEndpoint(creem, options),\n      searchTransactions: createSearchTransactionsEndpoint(creem, options),\n      hasAccessGranted: createHasAccessGrantedEndpoint(options),\n      ...(options.webhookSecret && {\n        creemWebhook: createWebhookEndpoint(options),\n      }),\n    },\n    schema: getSchema(options),\n  } satisfies BetterAuthPlugin;\n};\n","import type { BetterAuthPluginDBSchema } from \"@better-auth/core/db\";\nimport { mergeSchema } from \"better-auth/db\";\nimport { CreemOptions } from \"./types.js\";\n\nexport const subscriptions = {\n  creem_subscription: {\n    fields: {\n      productId: {\n        type: \"string\",\n        required: true,\n      },\n      referenceId: {\n        type: \"string\",\n        required: true,\n      },\n      creemCustomerId: {\n        type: \"string\",\n        required: false,\n      },\n      creemSubscriptionId: {\n        type: \"string\",\n        required: false,\n      },\n      creemOrderId: {\n        type: \"string\",\n        required: false,\n      },\n      status: {\n        type: \"string\",\n        defaultValue: \"pending\",\n      },\n      periodStart: {\n        type: \"date\",\n        required: false,\n      },\n      periodEnd: {\n        type: \"date\",\n        required: false,\n      },\n      cancelAtPeriodEnd: {\n        type: \"boolean\",\n        required: false,\n        defaultValue: false,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const user = {\n  user: {\n    fields: {\n      creemCustomerId: {\n        type: \"string\",\n        required: false,\n      },\n      /**\n       * Tracks whether this user has ever used a trial period.\n       * Used for automatic trial abuse prevention - users can only\n       * receive one trial across all subscription plans.\n       *\n       * This field is:\n       * - Optional (required: false) for backward compatibility with existing users\n       * - Defaults to false for new users\n       * - Set to true when user enters a trialing subscription state\n       *\n       * @since 1.1.0\n       */\n      hadTrial: {\n        type: \"boolean\",\n        required: false,\n        defaultValue: false,\n      },\n    },\n  },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const getSchema = (options: CreemOptions) => {\n  // Default persistSubscriptions to true if not specified\n  const shouldPersist = options.persistSubscriptions !== false;\n\n  // Only include schema if persistSubscriptions is enabled\n  const baseSchema = shouldPersist\n    ? {\n        ...subscriptions,\n        ...user,\n      }\n    : {};\n\n  return mergeSchema(baseSchema, options.schema);\n};\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { z } from \"zod\";\nimport type { CreemOptions } from \"./types.js\";\nimport { resolveSuccessUrl } from \"./utils.js\";\nimport type { CreateCheckoutInput, CreateCheckoutResponse } from \"./checkout-types.js\";\n\nconst CustomFieldInputSchema = z.object({\n  type: z.enum([\"text\", \"checkbox\"]),\n  key: z.string().max(200),\n  label: z.string().max(50),\n  optional: z.boolean().optional(),\n  text: z.object({ maxLength: z.number().optional(), minLength: z.number().optional() }).optional(),\n  checkbox: z.object({ label: z.string().optional() }).optional(),\n});\n\nexport const CheckoutParams = z.object({\n  productId: z.string(),\n  requestId: z.string().optional(),\n  units: z.number().positive().optional(),\n  discountCode: z.string().optional(),\n  customer: z\n    .object({\n      email: z.string().email().optional(),\n    })\n    .optional(),\n  customFields: z.array(CustomFieldInputSchema).max(3).optional(),\n  customField: z.array(CustomFieldInputSchema).max(3).optional(),\n  successUrl: z.string().optional(),\n  metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport type CheckoutParams = z.infer<typeof CheckoutParams>;\n\n// Re-export types for convenience\nexport type { CreateCheckoutInput, CreateCheckoutResponse };\n\n/**\n * Check if a user has already used a trial period.\n * Used for automatic trial abuse prevention.\n *\n * @returns true if user has used a trial, false otherwise (or if check fails)\n */\nasync function checkUserHadTrial(\n  ctx: GenericEndpointContext,\n  userId: string,\n  options: CreemOptions,\n): Promise<boolean> {\n  // Skip check if persistence is disabled\n  const shouldPersist = options.persistSubscriptions !== false;\n  if (!shouldPersist) {\n    return false;\n  }\n\n  try {\n    const user = await ctx.context.adapter.findOne<{\n      id: string;\n      hadTrial?: boolean;\n    }>({\n      model: \"user\",\n      where: [{ field: \"id\", value: userId }],\n    });\n\n    return user?.hadTrial === true;\n  } catch (error) {\n    // If check fails, allow the checkout to proceed (fail open)\n    // The trial abuse prevention is a convenience feature, not a security feature\n    logger.warn(`[creem] Failed to check hadTrial status for user ${userId}`);\n    return false;\n  }\n}\n\nconst createCheckoutHandler = (creem: Creem, options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    const body = ctx.body as CheckoutParams;\n\n    if (!options.apiKey) {\n      return ctx.json(\n        {\n          error:\n            \"Creem API key is not configured. Please set the apiKey option when initializing the Creem plugin.\",\n        },\n        { status: 500 },\n      );\n    }\n\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      logger.debug(\n        `[creem] Checkout: user=${session?.user?.id || \"anonymous\"}, product=${body.productId}`,\n      );\n\n      // Check if user has already used a trial (trial abuse prevention)\n      let userHadTrial = false;\n      if (session?.user?.id) {\n        userHadTrial = await checkUserHadTrial(ctx, session.user.id, options);\n        if (userHadTrial) {\n          logger.info(\n            `[creem] User ${session.user.id} has already used a trial - skipTrial flag will be set`,\n          );\n        }\n      }\n\n      const customFields = body.customFields ?? body.customField;\n\n      const checkout = await creem.checkouts.create({\n        productId: body.productId,\n        requestId: body.requestId,\n        units: body.units,\n        discountCode: body.discountCode,\n        customer: body.customer?.email\n          ? {\n              email: body.customer.email,\n            }\n          : session?.user?.email\n            ? {\n                email: session.user.email,\n              }\n            : undefined,\n        customFields,\n        successUrl: resolveSuccessUrl(body.successUrl || options.defaultSuccessUrl, ctx),\n        metadata: {\n          ...(body.metadata || {}),\n          ...(session?.user?.id && {\n            referenceId: session.user.id,\n          }),\n          // Trial abuse prevention: signal to Creem that this user has already had a trial\n          // Creem will use this to skip the trial period for returning users\n          ...(userHadTrial && {\n            skipTrial: true,\n          }),\n        },\n      });\n\n      logger.debug(`[creem] Checkout created: ${checkout.checkoutUrl}`);\n\n      return ctx.json({\n        url: checkout.checkoutUrl,\n        redirect: true,\n      });\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to create checkout: ${message}`);\n      return ctx.json({ error: \"Failed to create checkout\" }, { status: 500 });\n    }\n  };\n};\n\n/**\n * Creates the checkout endpoint for the Creem plugin.\n *\n * This endpoint handles creating Creem checkout sessions for authenticated users.\n * It automatically includes the user's session information and redirects to the checkout URL.\n *\n * @param creem - The Creem client instance\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint POST /creem/create-checkout\n *\n * @example\n * Client-side usage:\n * ```typescript\n * const { data, error } = await authClient.creem.createCheckout({\n *   productId: \"prod_abc123\",\n *   units: 1,\n *   successUrl: \"/thank-you\"\n * });\n *\n * if (data?.url) {\n *   window.location.href = data.url;\n * }\n * ```\n */\nexport const createCheckoutEndpoint = (creem: Creem, options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/create-checkout\",\n    {\n      method: \"POST\",\n      body: CheckoutParams,\n    },\n    createCheckoutHandler(creem, options),\n  );\n};\n","import type { GenericEndpointContext } from \"better-auth\";\nimport { generateSignature, parseWebhookEvent } from \"@creem_io/webhook-types\";\n\nexport { generateSignature, parseWebhookEvent };\n\n/**\n * Converts a relative URL to an absolute URL using the request context\n * If the URL is already absolute, returns it as-is\n */\nexport function resolveSuccessUrl(\n  url: string | undefined,\n  ctx: GenericEndpointContext,\n): string | undefined {\n  if (!url) return undefined;\n\n  // Check if URL is already absolute (contains protocol)\n  try {\n    new URL(url);\n    return url; // Already absolute URL\n  } catch {\n    // URL is relative, convert to absolute\n    const headers = ctx.request?.headers;\n    const host = headers?.get(\"host\") || headers?.get(\"x-forwarded-host\");\n    const protocol = headers?.get(\"x-forwarded-proto\") || headers?.get(\"x-forwarded-protocol\");\n\n    if (!host) {\n      return url; // Return as-is if we can't resolve\n    }\n\n    const baseUrl = `${protocol || \"https\"}://${host}`;\n    return new URL(url, baseUrl).toString();\n  }\n}\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { z } from \"zod\";\nimport type { CreemOptions } from \"./types.js\";\nimport type { CreatePortalInput, CreatePortalResponse } from \"./portal-types.js\";\n\nexport const PortalParams = z.object({\n  customerId: z.string().optional(),\n});\n\nexport type PortalParams = z.infer<typeof PortalParams>;\n\n// Re-export types for convenience\nexport type { CreatePortalInput, CreatePortalResponse };\n\nconst createPortalHandler = (creem: Creem, options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    const body = (ctx.body || {}) as PortalParams;\n\n    if (!options.apiKey) {\n      return ctx.json(\n        {\n          error:\n            \"Creem API key is not configured. Please set the apiKey option when initializing the Creem plugin.\",\n        },\n        { status: 500 },\n      );\n    }\n\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      if (!session?.user?.id) {\n        return ctx.json({ error: \"User must be logged in\" }, { status: 400 });\n      }\n\n      if (!session?.user.creemCustomerId) {\n        return ctx.json({ error: \"User must have a Creem customer ID\" }, { status: 400 });\n      }\n\n      logger.debug(`[creem] Portal: customer=${body.customerId || session.user.creemCustomerId}`);\n\n      const portal = await creem.customers.generateBillingLinks({\n        customerId: body.customerId || session.user.creemCustomerId,\n      });\n\n      logger.debug(`[creem] Portal created: ${portal.customerPortalLink}`);\n\n      return ctx.json({\n        url: portal.customerPortalLink,\n        redirect: true,\n      });\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to create portal: ${message}`);\n      return ctx.json({ error: \"Failed to create portal\" }, { status: 500 });\n    }\n  };\n};\n\n/**\n * Creates the customer portal endpoint for the Creem plugin.\n *\n * This endpoint generates a Creem customer portal URL where users can\n * manage their subscriptions, view invoices, and update payment methods.\n *\n * @param creem - The Creem client instance\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint POST /creem/create-portal\n *\n * @example\n * Client-side usage:\n * ```typescript\n * // Use default customer ID from session\n * const { data, error } = await authClient.creem.createPortal();\n *\n * // Or specify a custom customer ID\n * const { data, error } = await authClient.creem.createPortal({\n *   customerId: \"cust_abc123\"\n * });\n *\n * if (data?.url) {\n *   window.location.href = data.url;\n * }\n * ```\n */\nexport const createPortalEndpoint = (creem: Creem, options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/create-portal\",\n    {\n      method: \"POST\",\n      body: PortalParams,\n    },\n    createPortalHandler(creem, options),\n  );\n};\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { z } from \"zod\";\nimport type { CreemOptions, SubscriptionRecord } from \"./types.js\";\nimport type {\n  CancelSubscriptionInput,\n  CancelSubscriptionResponse,\n} from \"./cancel-subscription-types.js\";\n\nexport const CancelSubscriptionParams = z.object({\n  id: z.string().optional(),\n});\n\nexport type CancelSubscriptionParams = z.infer<typeof CancelSubscriptionParams>;\n\n// Re-export types for convenience\nexport type { CancelSubscriptionInput, CancelSubscriptionResponse };\n\nconst createCancelSubscriptionHandler = (creem: Creem, options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    const body = ctx.body as CancelSubscriptionParams;\n\n    if (!options.apiKey) {\n      return ctx.json(\n        {\n          error:\n            \"Creem API key is not configured. Please set the apiKey option when initializing the Creem plugin.\",\n        },\n        { status: 500 },\n      );\n    }\n\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      if (!session?.user?.id) {\n        return ctx.json({ error: \"User must be logged in\" }, { status: 400 });\n      }\n\n      let subscriptionId = body.id;\n\n      // Check if database persistence is enabled\n      const shouldPersist = options.persistSubscriptions !== false;\n\n      if (shouldPersist) {\n        // If database persistence is enabled, fetch the user's subscription from the database\n        const userId = session.user.id;\n\n        logger.debug(`[creem] Cancel: looking up subscriptions for user ${userId}`);\n\n        // Find all subscriptions for this user\n        const subscriptions = await ctx.context.adapter.findMany<SubscriptionRecord>({\n          model: \"creem_subscription\",\n          where: [{ field: \"referenceId\", value: userId }],\n        });\n\n        if (subscriptions && subscriptions.length > 0) {\n          // Find an active subscription (active, trialing, or any non-expired subscription)\n          const activeSubscription = subscriptions.find(\n            (sub) =>\n              sub.status === \"active\" ||\n              sub.status === \"trialing\" ||\n              sub.status === \"unpaid\" ||\n              sub.status === \"past_due\",\n          );\n\n          if (activeSubscription && activeSubscription.creemSubscriptionId) {\n            // Use the subscription ID from the database\n            subscriptionId = activeSubscription.creemSubscriptionId;\n          } else if (!subscriptionId) {\n            // If no active subscription and no ID provided, return error\n            return ctx.json(\n              { error: \"No active subscription found for this user\" },\n              { status: 404 },\n            );\n          }\n        } else if (!subscriptionId) {\n          // No subscriptions in database and no ID provided\n          return ctx.json({ error: \"No subscription found for this user\" }, { status: 404 });\n        }\n      } else if (!subscriptionId) {\n        // If persistence is disabled and no ID provided, return error\n        return ctx.json(\n          {\n            error: \"Subscription ID is required when database persistence is disabled\",\n          },\n          { status: 400 },\n        );\n      }\n\n      logger.debug(`[creem] Cancelling subscription: ${subscriptionId}`);\n\n      await creem.subscriptions.cancel(subscriptionId, {});\n\n      return ctx.json({\n        success: true,\n        message: \"Subscription cancelled successfully\",\n      });\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to cancel subscription: ${message}`);\n      return ctx.json({ error: \"Failed to cancel subscription\" }, { status: 500 });\n    }\n  };\n};\n\n/**\n * Creates the cancel subscription endpoint for the Creem plugin.\n *\n * This endpoint cancels an active subscription. The subscription will be\n * canceled immediately or at the end of the current billing period,\n * depending on your Creem settings.\n *\n * **Behavior:**\n * - If database persistence is enabled (persistSubscriptions: true), the endpoint\n *   will automatically find the authenticated user's active subscription and cancel it.\n *   The `id` parameter is optional in this case.\n * - If database persistence is disabled, the `id` parameter is required.\n *\n * @param creem - The Creem client instance\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint POST /creem/cancel-subscription\n *\n * @example\n * Client-side usage with database persistence enabled (id is optional):\n * ```typescript\n * // Cancels the authenticated user's active subscription\n * const { data, error } = await authClient.creem.cancelSubscription({});\n *\n * if (data?.success) {\n *   console.log(data.message); // \"Subscription cancelled successfully\"\n * }\n * ```\n *\n * @example\n * Client-side usage with explicit subscription ID:\n * ```typescript\n * const { data, error } = await authClient.creem.cancelSubscription({\n *   id: \"sub_abc123\"\n * });\n *\n * if (data?.success) {\n *   console.log(data.message); // \"Subscription cancelled successfully\"\n * }\n * ```\n */\nexport const createCancelSubscriptionEndpoint = (creem: Creem, options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/cancel-subscription\",\n    {\n      method: \"POST\",\n      body: CancelSubscriptionParams,\n    },\n    createCancelSubscriptionHandler(creem, options),\n  );\n};\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { z } from \"zod\";\nimport type { CreemOptions, SubscriptionRecord } from \"./types.js\";\nimport type { RetrieveSubscriptionInput, SubscriptionData } from \"./retrieve-subscription-types.js\";\n\nexport const RetrieveSubscriptionParams = z.object({\n  id: z.string().optional(),\n});\n\nexport type RetrieveSubscriptionParams = z.infer<typeof RetrieveSubscriptionParams>;\n\n// Re-export types for convenience\nexport type { RetrieveSubscriptionInput, SubscriptionData };\n\nconst createRetrieveSubscriptionHandler = (creem: Creem, options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    const body = ctx.body as RetrieveSubscriptionParams;\n\n    if (!options.apiKey) {\n      return ctx.json(\n        {\n          error:\n            \"Creem API key is not configured. Please set the apiKey option when initializing the Creem plugin.\",\n        },\n        { status: 500 },\n      );\n    }\n\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      if (!session?.user?.id) {\n        return ctx.json({ error: \"User must be logged in\" }, { status: 400 });\n      }\n\n      let subscriptionId = body.id;\n\n      // Check if database persistence is enabled\n      const shouldPersist = options.persistSubscriptions !== false;\n\n      if (shouldPersist) {\n        // If database persistence is enabled, fetch the user's subscription from the database\n        const userId = session.user.id;\n\n        logger.debug(`[creem] Retrieve: looking up subscriptions for user ${userId}`);\n\n        // Find all subscriptions for this user\n        const subscriptions = await ctx.context.adapter.findMany<SubscriptionRecord>({\n          model: \"creem_subscription\",\n          where: [{ field: \"referenceId\", value: userId }],\n        });\n\n        if (subscriptions && subscriptions.length > 0) {\n          // Get the first subscription for this user\n          const userSubscription = subscriptions[0];\n\n          if (userSubscription && userSubscription.creemSubscriptionId) {\n            // Use the subscription ID from the database\n            subscriptionId = userSubscription.creemSubscriptionId;\n          } else if (!subscriptionId) {\n            // If subscription doesn't have a Creem ID and no ID provided, return error\n            return ctx.json({ error: \"No subscription found for this user\" }, { status: 404 });\n          }\n        } else if (!subscriptionId) {\n          // No subscriptions in database and no ID provided\n          return ctx.json({ error: \"No subscription found for this user\" }, { status: 404 });\n        }\n      } else if (!subscriptionId) {\n        // If persistence is disabled and no ID provided, return error\n        return ctx.json(\n          {\n            error: \"Subscription ID is required when database persistence is disabled\",\n          },\n          { status: 400 },\n        );\n      }\n\n      logger.debug(`[creem] Retrieving subscription: ${subscriptionId}`);\n\n      const subscription = await creem.subscriptions.get(subscriptionId);\n\n      return ctx.json(subscription);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to retrieve subscription: ${message}`);\n      return ctx.json({ error: \"Failed to retrieve subscription\" }, { status: 500 });\n    }\n  };\n};\n\n/**\n * Creates the retrieve subscription endpoint for the Creem plugin.\n *\n * This endpoint retrieves detailed information about a subscription,\n * including its status, product details, customer information, and billing dates.\n *\n * **Behavior:**\n * - If database persistence is enabled (persistSubscriptions: true), the endpoint\n *   will automatically find the authenticated user's subscription and retrieve it.\n *   The `id` parameter is optional in this case.\n * - If database persistence is disabled, the `id` parameter is required.\n *\n * @param creem - The Creem client instance\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint POST /creem/retrieve-subscription\n *\n * @example\n * Client-side usage with database persistence enabled (id is optional):\n * ```typescript\n * // Retrieves the authenticated user's subscription\n * const { data, error } = await authClient.creem.retrieveSubscription({});\n *\n * if (data) {\n *   console.log(`Status: ${data.status}`);\n *   console.log(`Product: ${data.product.name}`);\n *   console.log(`Period ends: ${data.currentPeriodEndDate}`);\n * }\n * ```\n *\n * @example\n * Client-side usage with explicit subscription ID:\n * ```typescript\n * const { data, error } = await authClient.creem.retrieveSubscription({\n *   id: \"sub_abc123\"\n * });\n *\n * if (data) {\n *   console.log(`Status: ${data.status}`);\n *   console.log(`Product: ${data.product.name}`);\n *   console.log(`Period ends: ${data.currentPeriodEndDate}`);\n * }\n * ```\n */\nexport const createRetrieveSubscriptionEndpoint = (creem: Creem, options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/retrieve-subscription\",\n    {\n      method: \"POST\",\n      body: RetrieveSubscriptionParams,\n    },\n    createRetrieveSubscriptionHandler(creem, options),\n  );\n};\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { Creem } from \"creem\";\nimport { z } from \"zod\";\nimport type { CreemOptions } from \"./types.js\";\nimport type {\n  SearchTransactionsInput,\n  SearchTransactionsResponse,\n  TransactionData,\n} from \"./search-transactions-types.js\";\n\nexport const SearchTransactionsParams = z.object({\n  customerId: z.string().optional(),\n  pageNumber: z.number().min(1).optional(),\n  pageSize: z.number().positive().optional(),\n  productId: z.string().optional(),\n  orderId: z.string().optional(),\n});\n\nexport type SearchTransactionsParams = z.infer<typeof SearchTransactionsParams>;\n\n// Re-export types for convenience\nexport type { SearchTransactionsInput, SearchTransactionsResponse, TransactionData };\n\nconst createSearchTransactionsHandler = (creem: Creem, options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    const body = ctx.body as SearchTransactionsParams;\n\n    if (!options.apiKey) {\n      return ctx.json(\n        {\n          error:\n            \"Creem API key is not configured. Please set the apiKey option when initializing the Creem plugin.\",\n        },\n        { status: 500 },\n      );\n    }\n\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      if (!session?.user?.id) {\n        return ctx.json({ error: \"User must be logged in\" }, { status: 400 });\n      }\n\n      // Use the user's Creem customer ID if no customerId is provided\n      const customerId = body.customerId || session.user.creemCustomerId;\n\n      if (!customerId) {\n        return ctx.json({ error: \"User must have a Creem customer ID\" }, { status: 400 });\n      }\n\n      logger.debug(`[creem] Searching transactions for customer: ${customerId}`);\n\n      const transactions = await creem.transactions.search(\n        customerId,\n        body.orderId,\n        body.productId,\n        body.pageNumber,\n        body.pageSize,\n      );\n\n      return ctx.json(transactions);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to search transactions: ${message}`);\n      return ctx.json({ error: \"Failed to search transactions\" }, { status: 500 });\n    }\n  };\n};\n\n/**\n * Creates the search transactions endpoint for the Creem plugin.\n *\n * This endpoint searches for transactions based on various filters like\n * customer ID, product ID, or order ID. Supports pagination for large result sets.\n *\n * @param creem - The Creem client instance\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint POST /creem/search-transactions\n *\n * @example\n * Client-side usage:\n * ```typescript\n * // Get all transactions for the current user\n * const { data, error } = await authClient.creem.searchTransactions();\n *\n * // Search with filters\n * const { data, error } = await authClient.creem.searchTransactions({\n *   customerId: \"cust_abc123\",\n *   productId: \"prod_xyz789\",\n *   pageNumber: 2,\n *   pageSize: 50\n * });\n *\n * if (data?.items) {\n *   data.items.forEach(tx => {\n *     console.log(`${tx.type}: ${tx.amount} ${tx.currency}`);\n *   });\n * }\n * ```\n */\nexport const createSearchTransactionsEndpoint = (creem: Creem, options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/search-transactions\",\n    {\n      method: \"POST\",\n      body: SearchTransactionsParams,\n    },\n    createSearchTransactionsHandler(creem, options),\n  );\n};\n","import { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport { z } from \"zod\";\nimport type { CreemOptions, SubscriptionRecord } from \"./types.js\";\n\n// No input needed - uses session to get user ID\nexport const HasAccessGrantedParams = z.object({}).optional();\n\nexport type HasAccessGrantedParams = z.infer<typeof HasAccessGrantedParams>;\n\nconst createHasAccessGrantedHandler = (options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    try {\n      const session = await getSessionFromCtx(ctx);\n\n      if (!session?.user?.id) {\n        return ctx.json(\n          {\n            hasAccessGranted: undefined,\n            message: \"User must be logged in to check subscription status\",\n          },\n          { status: 401 },\n        );\n      }\n\n      // Check if persistSubscriptions is disabled\n      const shouldPersist = options.persistSubscriptions !== false;\n\n      if (!shouldPersist) {\n        return ctx.json(\n          {\n            hasAccessGranted: undefined,\n            message:\n              \"Database persistence is disabled. Enable 'persistSubscriptions' option or implement custom subscription checking.\",\n          },\n          { status: 400 },\n        );\n      }\n\n      const userId = session.user.id;\n\n      // Find all subscriptions for this user\n      const subscriptions = await ctx.context.adapter.findMany<SubscriptionRecord>({\n        model: \"creem_subscription\",\n        where: [{ field: \"referenceId\", value: userId }],\n      });\n\n      logger.debug(\n        `[creem] Access check: user=${userId}, found ${subscriptions?.length || 0} subscriptions`,\n      );\n\n      if (!subscriptions || subscriptions.length === 0) {\n        return ctx.json({\n          hasAccessGranted: false,\n          message: \"No subscriptions found for this user\",\n        });\n      }\n\n      // Get current UTC time\n      const now = new Date();\n\n      // Check each subscription\n      for (const subscription of subscriptions) {\n        const status = subscription.status.toLowerCase();\n\n        // Active, trialing, or paid = always has access\n        // Note: \"paid\" comes from the subscription.paid webhook event type, not the SDK status field\n        if (status === \"active\" || status === \"trialing\" || status === \"paid\") {\n          logger.debug(`[creem] Access granted: subscription ${subscription.id} status=${status}`);\n          return ctx.json({\n            hasAccessGranted: true,\n            subscription: {\n              id: subscription.id,\n              status: subscription.status,\n              productId: subscription.productId,\n              periodEnd: subscription.periodEnd,\n            },\n          });\n        }\n\n        // For canceled, past_due, or unpaid - check if period hasn't ended yet\n        if (status === \"canceled\" || status === \"past_due\" || status === \"unpaid\") {\n          if (subscription.periodEnd) {\n            const periodEnd = new Date(subscription.periodEnd);\n\n            // If period hasn't ended yet, user still has access\n            if (periodEnd > now) {\n              logger.debug(\n                `[creem] Access granted: subscription ${subscription.id} ${status} until ${periodEnd.toISOString()}`,\n              );\n              return ctx.json({\n                hasAccessGranted: true,\n                subscription: {\n                  id: subscription.id,\n                  status: subscription.status,\n                  productId: subscription.productId,\n                  periodEnd: subscription.periodEnd,\n                },\n                message: `Subscription is ${status} but access granted until ${periodEnd.toISOString()}`,\n              });\n            }\n          }\n        }\n      }\n\n      logger.debug(\"[creem] Access denied: no active subscriptions\");\n      // No active subscriptions found\n      return ctx.json({\n        hasAccessGranted: false,\n        message: \"No active subscriptions found\",\n        subscriptions: subscriptions.map((s) => ({\n          id: s.id,\n          status: s.status,\n          productId: s.productId,\n          periodEnd: s.periodEnd,\n        })),\n      });\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to check subscription status: ${errorMessage}`);\n      return ctx.json(\n        {\n          hasAccessGranted: undefined,\n          message: \"Failed to check subscription status\",\n        },\n        { status: 500 },\n      );\n    }\n  };\n};\n\n/**\n * Creates the access check endpoint for the Creem plugin.\n *\n * This endpoint checks whether the authenticated user has an active subscription\n * by querying the local database for subscription records.\n *\n * @param options - Plugin configuration options\n * @returns BetterAuth endpoint configuration\n *\n * @endpoint GET /creem/has-access-granted\n */\nexport const createHasAccessGrantedEndpoint = (options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/has-access-granted\",\n    {\n      method: \"GET\",\n    },\n    createHasAccessGrantedHandler(options),\n  );\n};\n","import { createAuthEndpoint } from \"better-auth/api\";\nimport { type GenericEndpointContext, logger } from \"better-auth\";\nimport type { CreemOptions } from \"./types.js\";\nimport { generateSignature, parseWebhookEvent } from \"./utils.js\";\nimport {\n  onCheckoutCompleted,\n  onSubscriptionActive,\n  onSubscriptionTrialing,\n  onSubscriptionCanceled,\n  onSubscriptionPaid,\n  onSubscriptionExpired,\n  onSubscriptionUnpaid,\n  onSubscriptionUpdate,\n  onSubscriptionPastDue,\n  onSubscriptionPaused,\n} from \"./hooks.js\";\n\nconst createWebhookHandler = (options: CreemOptions) => {\n  return async (ctx: GenericEndpointContext) => {\n    try {\n      if (!ctx.request) {\n        return ctx.json({ error: \"Request is required\" }, { status: 400 });\n      }\n\n      const buf = await ctx.request.text();\n\n      const signature = ctx.request.headers.get(\"creem-signature\");\n\n      if (!options.webhookSecret) {\n        logger.error(\"[creem] Webhook secret is not configured\");\n        return ctx.json({ error: \"Webhook secret is not configured\" }, { status: 400 });\n      }\n\n      const computedSignature = await generateSignature(buf, options.webhookSecret);\n      if (computedSignature !== signature) {\n        return ctx.json({ error: \"Invalid signature\" }, { status: 400 });\n      }\n\n      logger.debug(\"[creem] Webhook signature verified\");\n\n      const event = parseWebhookEvent(buf);\n\n      logger.debug(`[creem] Webhook event received: ${event.eventType} (id: ${event.id})`);\n\n      // TypeScript now knows the exact event type in each case\n      // The parsed event from Creem webhooks always has expanded objects\n      // We flatten the structure for easier destructuring in callbacks\n      //\n      // All user-facing callbacks are awaited so async work (DB writes, API calls)\n      // completes before the response returns. Without await, serverless runtimes\n      // (Cloudflare Workers, Vercel Edge) terminate the worker and silently drop\n      // the pending Promise.\n      switch (event.eventType) {\n        case \"checkout.completed\":\n          await onCheckoutCompleted(ctx, event, options);\n          await options.onCheckoutCompleted?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"refund.created\":\n          await options.onRefundCreated?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"dispute.created\":\n          await options.onDisputeCreated?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.active\":\n          await onSubscriptionActive(ctx, event, options);\n          await options.onGrantAccess?.({\n            reason: \"subscription_active\",\n            ...event.object,\n          });\n          await options.onSubscriptionActive?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.trialing\":\n          await onSubscriptionTrialing(ctx, event, options);\n          await options.onGrantAccess?.({\n            reason: \"subscription_trialing\",\n            ...event.object,\n          });\n          await options.onSubscriptionTrialing?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n\n          break;\n        case \"subscription.canceled\":\n          await onSubscriptionCanceled(ctx, event, options);\n          await options.onSubscriptionCanceled?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.paid\":\n          await onSubscriptionPaid(ctx, event, options);\n          await options.onGrantAccess?.({\n            reason: \"subscription_paid\",\n            ...event.object,\n          });\n          await options.onSubscriptionPaid?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.expired\":\n          await onSubscriptionExpired(ctx, event, options);\n          await options.onRevokeAccess?.({\n            reason: \"subscription_expired\",\n            ...event.object,\n          });\n          await options.onSubscriptionExpired?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.unpaid\":\n          await onSubscriptionUnpaid(ctx, event, options);\n          await options.onSubscriptionUnpaid?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.update\":\n          await onSubscriptionUpdate(ctx, event, options);\n          await options.onSubscriptionUpdate?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.past_due\":\n          await onSubscriptionPastDue(ctx, event, options);\n          await options.onSubscriptionPastDue?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        case \"subscription.paused\":\n          await onSubscriptionPaused(ctx, event, options);\n          await options.onRevokeAccess?.({\n            reason: \"subscription_paused\",\n            ...event.object,\n          });\n          await options.onSubscriptionPaused?.({\n            webhookEventType: event.eventType,\n            webhookId: event.id,\n            webhookCreatedAt: event.created_at,\n            ...event.object,\n          });\n          break;\n\n        default:\n          logger.warn(`[creem] Unknown event type received: ${(event as any).eventType}`);\n          return ctx.json({ error: \"Unknown event type\" }, { status: 400 });\n      }\n\n      return ctx.json({ message: \"Webhook received\" });\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to process webhook: ${message}`);\n      return ctx.json({ error: \"Failed to process webhook\" }, { status: 500 });\n    }\n  };\n};\n\nexport const createWebhookEndpoint = (options: CreemOptions) => {\n  return createAuthEndpoint(\n    \"/creem/webhook\",\n    {\n      method: \"POST\",\n      requireRequest: true,\n      requireHeaders: true,\n      disableBody: true,\n    },\n    createWebhookHandler(options),\n  );\n};\n","import { type GenericEndpointContext, logger } from \"better-auth\";\nimport type {\n  NormalizedCheckoutCompletedEvent,\n  NormalizedSubscriptionActiveEvent,\n  NormalizedSubscriptionTrialingEvent,\n  NormalizedSubscriptionCanceledEvent,\n  NormalizedSubscriptionPaidEvent,\n  NormalizedSubscriptionExpiredEvent,\n  NormalizedSubscriptionUnpaidEvent,\n  NormalizedSubscriptionUpdateEvent,\n  NormalizedSubscriptionPastDueEvent,\n  NormalizedSubscriptionPausedEvent,\n  NormalizedSubscriptionEntity,\n  SubscriptionStatus,\n} from \"@creem_io/webhook-types\";\nimport type { CreemOptions, SubscriptionRecord } from \"./types.js\";\n\n/**\n * Handle checkout.completed event\n * - Updates user with creemCustomerId (for first-time checkout)\n * - Creates or updates subscription record\n */\nexport async function onCheckoutCompleted(\n  ctx: GenericEndpointContext,\n  event: NormalizedCheckoutCompletedEvent,\n  options: CreemOptions,\n) {\n  // Skip database operations if persistSubscriptions is disabled\n  const shouldPersist = options.persistSubscriptions !== false;\n\n  if (!shouldPersist) {\n    logger.info(\"[creem] Persistence disabled, skipping checkout.completed DB operations\");\n    return;\n  }\n\n  try {\n    const checkout = event.object;\n\n    // Customer is always expanded in webhook events\n    const customerId = checkout.customer?.id;\n\n    if (!customerId) {\n      logger.warn(\"[creem] No customer ID in checkout.completed event\");\n      return;\n    }\n\n    // Extract referenceId from metadata\n    const referenceId = checkout.metadata?.referenceId as string;\n\n    if (!referenceId) {\n      logger.warn(\"[creem] No referenceId in checkout.completed event\");\n      return;\n    }\n\n    logger.debug(\n      `[creem] checkout.completed: customerId=${customerId}, referenceId=${referenceId}, hasSubscription=${!!checkout.subscription}`,\n    );\n\n    // Update user with creemCustomerId (if user exists)\n    try {\n      const user = await ctx.context.adapter.findOne<{\n        id: string;\n        creemCustomerId?: string;\n      }>({\n        model: \"user\",\n        where: [{ field: \"id\", value: referenceId }],\n      });\n\n      if (user && !user.creemCustomerId) {\n        await ctx.context.adapter.update({\n          model: \"user\",\n          where: [{ field: \"id\", value: referenceId }],\n          update: {\n            creemCustomerId: customerId,\n          },\n        });\n        logger.info(`[creem] Updated user ${referenceId} with creemCustomerId: ${customerId}`);\n      }\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to update user with creemCustomerId: ${message}`);\n    }\n\n    // Handle subscription if this is a recurring product\n    if (checkout.subscription && checkout.order) {\n      const subscriptionData = checkout.subscription;\n      const orderId = typeof checkout.order === \"object\" ? checkout.order.id : checkout.order;\n      const productId = checkout.product.id;\n\n      if (subscriptionData.id) {\n        const subscriptionUpdate = {\n          productId: productId || \"\",\n          referenceId,\n          creemCustomerId: customerId,\n          creemSubscriptionId: subscriptionData.id,\n          creemOrderId: orderId,\n          status: subscriptionData.status,\n          periodStart: subscriptionData.current_period_start_date\n            ? new Date(subscriptionData.current_period_start_date)\n            : undefined,\n          periodEnd: subscriptionData.current_period_end_date\n            ? new Date(subscriptionData.current_period_end_date)\n            : undefined,\n        };\n\n        // Try to find existing subscription by creemSubscriptionId or referenceId + productId\n        const existingSubscription = await ctx.context.adapter.findOne<SubscriptionRecord>({\n          model: \"creem_subscription\",\n          where: [{ field: \"creemSubscriptionId\", value: subscriptionData.id }],\n        });\n\n        if (existingSubscription) {\n          // Update existing subscription\n          await ctx.context.adapter.update({\n            model: \"creem_subscription\",\n            where: [{ field: \"id\", value: existingSubscription.id }],\n            update: subscriptionUpdate,\n          });\n          logger.info(`[creem] Updated subscription ${existingSubscription.id} from checkout`);\n        } else {\n          // Create new subscription\n          const newSubscription = await ctx.context.adapter.create<SubscriptionRecord>({\n            model: \"creem_subscription\",\n            data: subscriptionUpdate,\n          });\n          logger.info(`[creem] Created subscription ${newSubscription.id} from checkout`);\n        }\n      }\n    }\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    logger.error(`[creem] Webhook failed (checkout.completed): ${message}`);\n  }\n}\n\n/**\n * Handle subscription.active event\n * Updates subscription status to active\n */\nexport async function onSubscriptionActive(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionActiveEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"active\", options);\n}\n\n/**\n * Handle subscription.trialing event\n * Updates subscription status to trialing and marks user as having used a trial\n * for trial abuse prevention.\n */\nexport async function onSubscriptionTrialing(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionTrialingEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"trialing\", options);\n\n  // Mark user as having used a trial (for trial abuse prevention)\n  await markUserAsHadTrial(ctx, event.object, options);\n}\n\n/**\n * Mark a user as having used a trial period.\n * This is used for automatic trial abuse prevention - once a user has had\n * a trial, they cannot receive another trial on any subscription plan.\n *\n * This function is idempotent - calling it multiple times for the same user\n * will not cause issues.\n */\nasync function markUserAsHadTrial(\n  ctx: GenericEndpointContext,\n  subscriptionData: NormalizedSubscriptionEntity,\n  options: CreemOptions,\n) {\n  // Skip if persistence is disabled\n  const shouldPersist = options.persistSubscriptions !== false;\n  if (!shouldPersist) {\n    return;\n  }\n\n  const referenceId = subscriptionData.metadata?.referenceId as string;\n  if (!referenceId) {\n    logger.warn(\"[creem] Cannot mark user as hadTrial - no referenceId in subscription metadata\");\n    return;\n  }\n\n  try {\n    // Find the user\n    const user = await ctx.context.adapter.findOne<{\n      id: string;\n      hadTrial?: boolean;\n    }>({\n      model: \"user\",\n      where: [{ field: \"id\", value: referenceId }],\n    });\n\n    if (!user) {\n      logger.warn(\n        `[creem] User not found for referenceId: ${referenceId}, cannot mark as hadTrial`,\n      );\n      return;\n    }\n\n    // Only update if not already marked (idempotent)\n    if (!user.hadTrial) {\n      await ctx.context.adapter.update({\n        model: \"user\",\n        where: [{ field: \"id\", value: referenceId }],\n        update: {\n          hadTrial: true,\n        },\n      });\n      logger.info(`[creem] Marked user ${referenceId} as hadTrial=true`);\n    }\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    logger.error(`[creem] Failed to mark user as hadTrial: ${message}`);\n  }\n}\n\n/**\n * Handle subscription.canceled event\n * Updates subscription status to canceled\n */\nexport async function onSubscriptionCanceled(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionCanceledEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"canceled\", options);\n}\n\n/**\n * Handle subscription.paid event\n * Updates subscription with latest payment information\n */\nexport async function onSubscriptionPaid(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionPaidEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, event.object.status, options);\n}\n\n/**\n * Handle subscription.expired event\n * Updates subscription status to expired\n */\nexport async function onSubscriptionExpired(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionExpiredEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"expired\", options);\n}\n\n/**\n * Handle subscription.unpaid event\n * Updates subscription status to unpaid\n */\nexport async function onSubscriptionUnpaid(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionUnpaidEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"unpaid\", options);\n}\n\n/**\n * Handle subscription.update event\n * Updates subscription with latest information\n */\nexport async function onSubscriptionUpdate(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionUpdateEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, event.object.status, options);\n}\n\n/**\n * Handle subscription.past_due event\n * Updates subscription status to past_due\n */\nexport async function onSubscriptionPastDue(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionPastDueEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"past_due\", options);\n}\n\n/**\n * Handle subscription.paused event\n * Updates subscription status to paused\n */\nexport async function onSubscriptionPaused(\n  ctx: GenericEndpointContext,\n  event: NormalizedSubscriptionPausedEvent,\n  options: CreemOptions,\n) {\n  await updateSubscriptionFromEvent(ctx, event.object, \"paused\", options);\n}\n\n/**\n * Helper function to update subscription from Creem webhook event\n */\nasync function updateSubscriptionFromEvent(\n  ctx: GenericEndpointContext,\n  subscriptionData: NormalizedSubscriptionEntity,\n  status: SubscriptionStatus,\n  options: CreemOptions,\n) {\n  // Skip database operations if persistSubscriptions is disabled\n  const shouldPersist = options.persistSubscriptions !== false;\n\n  if (!shouldPersist) {\n    logger.info(\"[creem] Persistence disabled, skipping subscription DB operations\");\n    return;\n  }\n\n  const referenceId = subscriptionData.metadata?.referenceId;\n\n  if (!referenceId) {\n    logger.warn(\"[creem] No referenceId in subscription event metadata\");\n    return;\n  }\n\n  try {\n    // Customer and product are always expanded in webhook events\n    const customerId = subscriptionData.customer.id;\n    const productId = subscriptionData.product.id;\n\n    logger.debug(`[creem] Subscription lookup: trying creemSubscriptionId=${subscriptionData.id}`);\n\n    // Find subscription by creemSubscriptionId\n    let subscription = await ctx.context.adapter.findOne<SubscriptionRecord>({\n      model: \"creem_subscription\",\n      where: [{ field: \"creemSubscriptionId\", value: subscriptionData.id }],\n    });\n\n    // If not found by creemSubscriptionId, try to find by creemCustomerId and productId\n    if (!subscription && customerId) {\n      logger.debug(`[creem] Subscription lookup: fallback to customerId=${customerId}`);\n      const subscriptions = await ctx.context.adapter.findMany<SubscriptionRecord>({\n        model: \"creem_subscription\",\n        where: [{ field: \"creemCustomerId\", value: customerId }],\n      });\n\n      // Find the subscription for this specific product\n      subscription =\n        subscriptions.find((sub: SubscriptionRecord) => sub.productId === productId) ||\n        subscriptions[0];\n    }\n\n    if (!subscription) {\n      logger.warn(`[creem] Subscription not found for creemSubscriptionId: ${subscriptionData.id}`);\n      return;\n    }\n\n    // Prepare update data\n    const updateData: Partial<SubscriptionRecord> = {\n      status,\n      creemSubscriptionId: subscriptionData.id,\n      creemCustomerId: customerId,\n      periodStart: subscriptionData.current_period_start_date\n        ? new Date(subscriptionData.current_period_start_date)\n        : subscription.periodStart,\n      periodEnd: subscriptionData.current_period_end_date\n        ? new Date(subscriptionData.current_period_end_date)\n        : subscription.periodEnd,\n    };\n\n    // Update subscription\n    await ctx.context.adapter.update({\n      model: \"creem_subscription\",\n      where: [{ field: \"id\", value: subscription.id }],\n      update: updateData,\n    });\n\n    logger.info(`[creem] Updated subscription ${subscription.id} to status: ${status}`);\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    logger.error(`[creem] Webhook failed (subscription update): ${message}`);\n  }\n}\n","import { Creem } from \"creem\";\nimport { logger } from \"better-auth\";\nimport type { CreemOptions } from \"./types.js\";\nimport type { CreateCheckoutInput, CreateCheckoutResponse } from \"./checkout-types.js\";\nimport type { CreatePortalResponse } from \"./portal-types.js\";\nimport type { SubscriptionData } from \"./retrieve-subscription-types.js\";\nimport type { SearchTransactionsResponse } from \"./search-transactions-types.js\";\nimport { generateSignature } from \"./utils.js\";\n\n/**\n * Configuration for server-side Creem operations.\n */\nexport interface CreemServerConfig {\n  /** Creem API key */\n  apiKey: string;\n  /** Whether to use test mode */\n  testMode?: boolean;\n}\n\n/**\n * Initialize a Creem client for server-side operations.\n * Use this for direct API calls outside of Better Auth endpoints.\n *\n * @param config - Configuration options\n * @returns Configured Creem client instance\n *\n * @example\n * ```typescript\n * import { createCreemClient } from \"@creem_io/better-auth/server\";\n *\n * const creem = createCreemClient({\n *   apiKey: process.env.CREEM_API_KEY!,\n *   testMode: true\n * });\n *\n * // Use directly in Server Actions or API routes\n * const subscription = await creem.subscriptions.get(\"sub_123\");\n * ```\n */\nexport function createCreemClient(config: CreemServerConfig): Creem {\n  const serverURL = config.testMode ? \"https://test-api.creem.io\" : \"https://api.creem.io\";\n\n  return new Creem({ apiKey: config.apiKey, serverURL });\n}\n\n/**\n * Check if a subscription status indicates active access.\n *\n * @param status - The subscription status from Creem\n * @returns True if subscription grants access\n *\n * @example\n * ```typescript\n * import { isActiveSubscription } from \"@creem_io/better-auth/server\";\n *\n * if (isActiveSubscription(subscription.status)) {\n *   // User has active access\n * }\n * ```\n */\nexport function isActiveSubscription(status: string): boolean {\n  return [\"active\", \"trialing\", \"paid\"].includes(status.toLowerCase());\n}\n\n/**\n * Format Creem Unix timestamp to JavaScript Date.\n *\n * @param timestamp - Unix timestamp from Creem (seconds)\n * @returns JavaScript Date object\n *\n * @example\n * ```typescript\n * import { formatCreemDate } from \"@creem_io/better-auth/server\";\n *\n * const renewalDate = formatCreemDate(subscription.next_billing_date);\n * console.log(renewalDate.toLocaleDateString());\n * ```\n */\nexport function formatCreemDate(timestamp: number): Date {\n  return new Date(timestamp * 1000);\n}\n\n/**\n * Calculate days until subscription renewal.\n *\n * @param periodEndTimestamp - Unix timestamp of period end\n * @returns Number of days until renewal (negative if overdue)\n *\n * @example\n * ```typescript\n * import { getDaysUntilRenewal } from \"@creem_io/better-auth/server\";\n *\n * const days = getDaysUntilRenewal(subscription.current_period_end_date);\n * if (days > 0) {\n *   console.log(`Renews in ${days} days`);\n * } else {\n *   console.log(`Overdue by ${Math.abs(days)} days`);\n * }\n * ```\n */\nexport function getDaysUntilRenewal(periodEndTimestamp: number): number {\n  const renewalDate = formatCreemDate(periodEndTimestamp);\n  const now = new Date();\n  const diffTime = renewalDate.getTime() - now.getTime();\n  return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n/**\n * Validate webhook signature from Creem.\n * Use this to verify webhook authenticity in custom webhook handlers.\n *\n * @param payload - Raw webhook payload string\n * @param signature - Signature from 'creem-signature' header\n * @param secret - Your webhook secret\n * @returns True if signature is valid\n *\n * @example\n * ```typescript\n * import { validateWebhookSignature } from \"@creem_io/better-auth/server\";\n *\n * export async function POST(req: Request) {\n *   const payload = await req.text();\n *   const signature = req.headers.get('creem-signature');\n *\n *   if (!await validateWebhookSignature(payload, signature, process.env.CREEM_WEBHOOK_SECRET!)) {\n *     return new Response('Invalid signature', { status: 401 });\n *   }\n *\n *   const event = JSON.parse(payload);\n *   // Process webhook\n * }\n * ```\n */\nexport async function validateWebhookSignature(\n  payload: string,\n  signature: string | null,\n  secret: string,\n): Promise<boolean> {\n  if (!signature) return false;\n  const computedSignature = await generateSignature(payload, secret);\n  return computedSignature === signature;\n}\n\n/**\n * Create a checkout session directly (without using Better Auth endpoints).\n * Useful in Server Components, Server Actions, or custom API routes.\n *\n * @param config - Creem configuration\n * @param input - Checkout parameters\n * @returns Checkout URL and redirect flag\n *\n * @example\n * ```typescript\n * import { createCheckout } from \"@creem_io/better-auth/server\";\n *\n * // Server Action\n * export async function startCheckout(productId: string) {\n *   const { url } = await createCheckout(\n *     {\n *       apiKey: process.env.CREEM_API_KEY!,\n *       testMode: true\n *     },\n *     {\n *       productId,\n *       customer: { email: user.email },\n *       successUrl: \"/success\",\n *       metadata: { userId: user.id }\n *     }\n *   );\n *\n *   redirect(url);\n * }\n * ```\n *\n * @example\n * // With trial abuse prevention (check user.hadTrial from your database)\n * ```typescript\n * const { url } = await createCheckout(\n *   config,\n *   {\n *     productId,\n *     customer: { email: user.email },\n *     successUrl: \"/success\",\n *     skipTrial: user.hadTrial, // Pass true if user has already used a trial\n *   }\n * );\n * ```\n */\nexport async function createCheckout(\n  config: CreemServerConfig,\n  input: Omit<CreateCheckoutInput, \"customer\"> & {\n    customer: { email?: string; id?: string };\n    /**\n     * If true, tells Creem to skip the trial period for this checkout.\n     * Use this for trial abuse prevention - pass true if the user has\n     * already used a trial (check user.hadTrial from your database).\n     *\n     * @since 1.1.0\n     */\n    skipTrial?: boolean;\n  },\n): Promise<CreateCheckoutResponse> {\n  if (!config.apiKey) {\n    throw new Error(\n      \"Creem API key is not configured. Please provide an apiKey in the CreemServerConfig.\",\n    );\n  }\n\n  const creem = createCreemClient(config);\n\n  const checkout = await creem.checkouts.create({\n    productId: input.productId,\n    requestId: input.requestId,\n    units: input.units,\n    discountCode: input.discountCode,\n    customer: input.customer,\n    customFields: input.customFields ?? input.customField,\n    successUrl: input.successUrl,\n    metadata: {\n      ...(input.metadata || {}),\n      // Trial abuse prevention: signal to Creem that this user has already had a trial\n      ...(input.skipTrial && { skipTrial: true }),\n    },\n  });\n\n  return {\n    url:\n      checkout.checkoutUrl ??\n      (() => {\n        throw new Error(\"Creem API returned no checkout URL\");\n      })(),\n    redirect: true,\n  };\n}\n\n/**\n * Create a customer portal session directly.\n * Useful in Server Components, Server Actions, or custom API routes.\n *\n * @param config - Creem configuration\n * @param customerId - Creem customer ID\n * @returns Portal URL and redirect flag\n *\n * @example\n * ```typescript\n * import { createPortal } from \"@creem_io/better-auth/server\";\n *\n * // Server Component\n * export default async function BillingPage() {\n *   const session = await getSession();\n *\n *   async function openPortal() {\n *     'use server';\n *     const { url } = await createPortal(\n *       {\n *         apiKey: process.env.CREEM_API_KEY!,\n *         testMode: true\n *       },\n *       session.user.creemCustomerId\n *     );\n *     redirect(url);\n *   }\n *\n *   return <form action={openPortal}>...</form>;\n * }\n * ```\n */\nexport async function createPortal(\n  config: CreemServerConfig,\n  customerId: string,\n): Promise<CreatePortalResponse> {\n  if (!config.apiKey) {\n    throw new Error(\n      \"Creem API key is not configured. Please provide an apiKey in the CreemServerConfig.\",\n    );\n  }\n\n  const creem = createCreemClient(config);\n\n  const portal = await creem.customers.generateBillingLinks({\n    customerId,\n  });\n\n  return {\n    url: portal.customerPortalLink,\n    redirect: true,\n  };\n}\n\n/**\n * Cancel a subscription directly.\n * Useful in Server Actions or custom API routes.\n *\n * @param config - Creem configuration\n * @param subscriptionId - Subscription ID to cancel\n * @returns Success status and message\n *\n * @example\n * ```typescript\n * import { cancelSubscription } from \"@creem_io/better-auth/server\";\n *\n * // Server Action\n * export async function handleCancelSubscription(subId: string) {\n *   const result = await cancelSubscription(\n *     {\n *       apiKey: process.env.CREEM_API_KEY!,\n *       testMode: true\n *     },\n *     subId\n *   );\n *\n *   if (result.success) {\n *     revalidatePath('/billing');\n *   }\n * }\n * ```\n */\nexport async function cancelSubscription(\n  config: CreemServerConfig,\n  subscriptionId: string,\n): Promise<{ success: boolean; message: string }> {\n  if (!config.apiKey) {\n    throw new Error(\n      \"Creem API key is not configured. Please provide an apiKey in the CreemServerConfig.\",\n    );\n  }\n\n  const creem = createCreemClient(config);\n\n  await creem.subscriptions.cancel(subscriptionId, {});\n\n  return {\n    success: true,\n    message: \"Subscription cancelled successfully\",\n  };\n}\n\n/**\n * Retrieve subscription details directly.\n * Useful in Server Components, Server Actions, or custom API routes.\n *\n * @param config - Creem configuration\n * @param subscriptionId - Subscription ID to retrieve\n * @returns Subscription data\n *\n * @example\n * ```typescript\n * import { retrieveSubscription } from \"@creem_io/better-auth/server\";\n *\n * // Server Component\n * export default async function SubscriptionPage({ params }) {\n *   const subscription = await retrieveSubscription(\n *     {\n *       apiKey: process.env.CREEM_API_KEY!,\n *       testMode: true\n *     },\n *     params.subscriptionId\n *   );\n *\n *   return (\n *     <div>\n *       <h1>{subscription.product.name}</h1>\n *       <p>Status: {subscription.status}</p>\n *     </div>\n *   );\n * }\n * ```\n */\nexport async function retrieveSubscription(\n  config: CreemServerConfig,\n  subscriptionId: string,\n): Promise<SubscriptionData> {\n  if (!config.apiKey) {\n    throw new Error(\n      \"Creem API key is not configured. Please provide an apiKey in the CreemServerConfig.\",\n    );\n  }\n\n  const creem = createCreemClient(config);\n\n  const subscription = await creem.subscriptions.get(subscriptionId);\n\n  return subscription as unknown as SubscriptionData;\n}\n\n/**\n * Search transactions directly.\n * Useful in Server Components, Server Actions, or custom API routes.\n *\n * @param config - Creem configuration\n * @param filters - Search filters\n * @returns Transaction search results\n *\n * @example\n * ```typescript\n * import { searchTransactions } from \"@creem_io/better-auth/server\";\n *\n * // Server Component\n * export default async function TransactionsPage() {\n *   const { items, pagination } = await searchTransactions(\n *     {\n *       apiKey: process.env.CREEM_API_KEY!,\n *       testMode: true\n *     },\n *     {\n *       customerId: user.creemCustomerId,\n *       pageSize: 50\n *     }\n *   );\n *\n *   return <TransactionList transactions={items} />;\n * }\n * ```\n */\nexport async function searchTransactions(\n  config: CreemServerConfig,\n  filters?: {\n    customerId?: string;\n    productId?: string;\n    orderId?: string;\n    pageNumber?: number;\n    pageSize?: number;\n  },\n): Promise<SearchTransactionsResponse> {\n  if (!config.apiKey) {\n    throw new Error(\n      \"Creem API key is not configured. Please provide an apiKey in the CreemServerConfig.\",\n    );\n  }\n\n  const creem = createCreemClient(config);\n\n  const response = await creem.transactions.search(\n    filters?.customerId,\n    filters?.orderId,\n    filters?.productId,\n    filters?.pageNumber,\n    filters?.pageSize,\n  );\n\n  return response as unknown as SearchTransactionsResponse;\n}\n\n/**\n * Check if user has active subscription with access.\n * Works in both database-enabled and database-free modes.\n *\n * **Database Mode:** Queries local subscription table for fast access checks.\n * **API Mode:** Queries Creem API directly (requires API call).\n *\n * @param config - Creem configuration\n * @param options - Check options\n * @returns Access status information\n *\n * @example\n * ```typescript\n * // Database mode (when persistSubscriptions: true)\n * import { checkSubscriptionAccess } from \"@creem_io/better-auth/server\";\n * import { auth } from \"@/lib/auth\";\n *\n * const status = await checkSubscriptionAccess(\n *   {\n *     apiKey: process.env.CREEM_API_KEY!,\n *     testMode: true\n *   },\n *   {\n *     database: auth.options.database, // Pass database adapter\n *     userId: session.user.id\n *   }\n * );\n *\n * // API mode (when persistSubscriptions: false or no database)\n * const status = await checkSubscriptionAccess(\n *   {\n *     apiKey: process.env.CREEM_API_KEY!,\n *     testMode: true\n *   },\n *   {\n *     customerId: session.user.creemCustomerId\n *   }\n * );\n *\n * if (!status.hasAccess) {\n *   redirect('/subscribe');\n * }\n * ```\n */\nexport async function checkSubscriptionAccess(\n  config: CreemServerConfig,\n  options:\n    | { database: any; userId: string; customerId?: never }\n    | { customerId: string; database?: never; userId?: never },\n): Promise<{\n  hasAccess: boolean;\n  status?: string;\n  subscriptionId?: string;\n  expiresAt?: Date;\n  productName?: string;\n}> {\n  // Database mode\n  // TODO: This uses a raw query builder API (select/from/where) that may not match\n  // all Better Auth database adapters. For reliable access checks, prefer the\n  // `hasAccessGranted` Better Auth endpoint which uses the adapter correctly.\n  if (options.database && options.userId) {\n    try {\n      const subscriptions = await options.database\n        .select()\n        .from(\"creem_subscription\")\n        .where(\"referenceId\", \"=\", options.userId);\n\n      const activeSubscription = subscriptions.find(\n        (sub: any) => sub.status === \"active\" || sub.status === \"trialing\" || sub.status === \"paid\",\n      );\n\n      if (activeSubscription) {\n        return {\n          hasAccess: true,\n          status: activeSubscription.status,\n          subscriptionId: activeSubscription.creemSubscriptionId,\n          expiresAt: activeSubscription.periodEnd\n            ? new Date(activeSubscription.periodEnd)\n            : undefined,\n        };\n      }\n\n      return { hasAccess: false };\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to check subscription access (database mode): ${message}`);\n      // Fall through to API check\n    }\n  }\n\n  // API mode\n  if (options.customerId) {\n    // API mode not yet supported — use database mode for access checks\n    return { hasAccess: false };\n  }\n\n  return { hasAccess: false };\n}\n\n/**\n * Get all active subscriptions for a user or customer.\n * Works in both database-enabled and database-free modes.\n *\n * @param config - Creem configuration\n * @param options - Query options\n * @returns List of active subscriptions\n *\n * @example\n * ```typescript\n * import { getActiveSubscriptions } from \"@creem_io/better-auth/server\";\n *\n * // Database mode\n * const subscriptions = await getActiveSubscriptions(\n *   config,\n *   { database: auth.options.database, userId: user.id }\n * );\n *\n * // API mode\n * const subscriptions = await getActiveSubscriptions(\n *   config,\n *   { customerId: user.creemCustomerId }\n * );\n * ```\n */\nexport async function getActiveSubscriptions(\n  config: CreemServerConfig,\n  options:\n    | { database: any; userId: string; customerId?: never }\n    | { customerId: string; database?: never; userId?: never },\n): Promise<\n  Array<{\n    id: string;\n    status: string;\n    productId: string;\n    productName?: string;\n    periodEnd?: Date;\n  }>\n> {\n  // Database mode\n  // TODO: Same raw query builder caveat as checkSubscriptionAccess above.\n  if (options.database && options.userId) {\n    try {\n      const subscriptions = await options.database\n        .select()\n        .from(\"creem_subscription\")\n        .where(\"referenceId\", \"=\", options.userId);\n\n      return subscriptions\n        .filter(\n          (sub: any) =>\n            sub.status === \"active\" || sub.status === \"trialing\" || sub.status === \"paid\",\n        )\n        .map((sub: any) => ({\n          id: sub.creemSubscriptionId,\n          status: sub.status,\n          productId: sub.productId,\n          periodEnd: sub.periodEnd ? new Date(sub.periodEnd) : undefined,\n        }));\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      logger.error(`[creem] Failed to get active subscriptions (database mode): ${message}`);\n      return [];\n    }\n  }\n\n  // API mode\n  if (options.customerId) {\n    // API mode not yet supported — use database mode for subscription queries\n    return [];\n  }\n\n  return [];\n}\n"],"mappings":";AAAA,SAA2B,UAAAA,gBAAc;AACzC,SAAS,SAAAC,cAAa;;;ACAtB,SAAS,mBAAmB;AAGrB,IAAM,gBAAgB;AAAA,EAC3B,oBAAoB;AAAA,IAClB,QAAQ;AAAA,MACN,WAAW;AAAA,QACT,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,aAAa;AAAA,QACX,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,qBAAqB;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,cAAc;AAAA,QACZ,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,cAAc;AAAA,MAChB;AAAA,MACA,aAAa;AAAA,QACX,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,WAAW;AAAA,QACT,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA,MACA,mBAAmB;AAAA,QACjB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,OAAO;AAAA,EAClB,MAAM;AAAA,IACJ,QAAQ;AAAA,MACN,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,UAAU;AAAA,MACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAaA,UAAU;AAAA,QACR,MAAM;AAAA,QACN,UAAU;AAAA,QACV,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,YAAY,CAAC,YAA0B;AAElD,QAAM,gBAAgB,QAAQ,yBAAyB;AAGvD,QAAM,aAAa,gBACf;AAAA,IACE,GAAG;AAAA,IACH,GAAG;AAAA,EACL,IACA,CAAC;AAEL,SAAO,YAAY,YAAY,QAAQ,MAAM;AAC/C;;;ACzFA,SAAS,oBAAoB,yBAAyB;AACtD,SAAsC,cAAc;AAEpD,SAAS,SAAS;;;ACFlB,SAAS,mBAAmB,yBAAyB;AAQ9C,SAAS,kBACd,KACA,KACoB;AACpB,MAAI,CAAC,IAAK,QAAO;AAGjB,MAAI;AACF,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT,QAAQ;AAEN,UAAM,UAAU,IAAI,SAAS;AAC7B,UAAM,OAAO,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,kBAAkB;AACpE,UAAM,WAAW,SAAS,IAAI,mBAAmB,KAAK,SAAS,IAAI,sBAAsB;AAEzF,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,GAAG,YAAY,OAAO,MAAM,IAAI;AAChD,WAAO,IAAI,IAAI,KAAK,OAAO,EAAE,SAAS;AAAA,EACxC;AACF;;;ADxBA,IAAM,yBAAyB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,KAAK,CAAC,QAAQ,UAAU,CAAC;AAAA,EACjC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG;AAAA,EACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACxB,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,GAAG,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS;AAAA,EAChG,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS;AAChE,CAAC;AAEM,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,WAAW,EAAE,OAAO;AAAA,EACpB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACtC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,UAAU,EACP,OAAO;AAAA,IACN,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,EACrC,CAAC,EACA,SAAS;AAAA,EACZ,cAAc,EAAE,MAAM,sBAAsB,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC9D,aAAa,EAAE,MAAM,sBAAsB,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC7D,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS;AACvD,CAAC;AAaD,eAAe,kBACb,KACA,QACA,SACkB;AAElB,QAAM,gBAAgB,QAAQ,yBAAyB;AACvD,MAAI,CAAC,eAAe;AAClB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAMC,QAAO,MAAM,IAAI,QAAQ,QAAQ,QAGpC;AAAA,MACD,OAAO;AAAA,MACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,OAAO,CAAC;AAAA,IACxC,CAAC;AAED,WAAOA,OAAM,aAAa;AAAA,EAC5B,SAAS,OAAO;AAGd,WAAO,KAAK,oDAAoD,MAAM,EAAE;AACxE,WAAO;AAAA,EACT;AACF;AAEA,IAAM,wBAAwB,CAACC,QAAc,YAA0B;AACrE,SAAO,OAAO,QAAgC;AAC5C,UAAM,OAAO,IAAI;AAEjB,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACT;AAAA,UACE,OACE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,kBAAkB,GAAG;AAE3C,aAAO;AAAA,QACL,0BAA0B,SAAS,MAAM,MAAM,WAAW,aAAa,KAAK,SAAS;AAAA,MACvF;AAGA,UAAI,eAAe;AACnB,UAAI,SAAS,MAAM,IAAI;AACrB,uBAAe,MAAM,kBAAkB,KAAK,QAAQ,KAAK,IAAI,OAAO;AACpE,YAAI,cAAc;AAChB,iBAAO;AAAA,YACL,gBAAgB,QAAQ,KAAK,EAAE;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAEA,YAAM,eAAe,KAAK,gBAAgB,KAAK;AAE/C,YAAM,WAAW,MAAMA,OAAM,UAAU,OAAO;AAAA,QAC5C,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB,OAAO,KAAK;AAAA,QACZ,cAAc,KAAK;AAAA,QACnB,UAAU,KAAK,UAAU,QACrB;AAAA,UACE,OAAO,KAAK,SAAS;AAAA,QACvB,IACA,SAAS,MAAM,QACb;AAAA,UACE,OAAO,QAAQ,KAAK;AAAA,QACtB,IACA;AAAA,QACN;AAAA,QACA,YAAY,kBAAkB,KAAK,cAAc,QAAQ,mBAAmB,GAAG;AAAA,QAC/E,UAAU;AAAA,UACR,GAAI,KAAK,YAAY,CAAC;AAAA,UACtB,GAAI,SAAS,MAAM,MAAM;AAAA,YACvB,aAAa,QAAQ,KAAK;AAAA,UAC5B;AAAA;AAAA;AAAA,UAGA,GAAI,gBAAgB;AAAA,YAClB,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF,CAAC;AAED,aAAO,MAAM,6BAA6B,SAAS,WAAW,EAAE;AAEhE,aAAO,IAAI,KAAK;AAAA,QACd,KAAK,SAAS;AAAA,QACd,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,aAAO,MAAM,sCAAsC,OAAO,EAAE;AAC5D,aAAO,IAAI,KAAK,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACzE;AAAA,EACF;AACF;AA4BO,IAAM,yBAAyB,CAACA,QAAc,YAA0B;AAC7E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,sBAAsBA,QAAO,OAAO;AAAA,EACtC;AACF;;;AEzLA,SAAS,sBAAAC,qBAAoB,qBAAAC,0BAAyB;AACtD,SAAsC,UAAAC,eAAc;AAEpD,SAAS,KAAAC,UAAS;AAIX,IAAM,eAAeA,GAAE,OAAO;AAAA,EACnC,YAAYA,GAAE,OAAO,EAAE,SAAS;AAClC,CAAC;AAOD,IAAM,sBAAsB,CAACC,QAAc,YAA0B;AACnE,SAAO,OAAO,QAAgC;AAC5C,UAAM,OAAQ,IAAI,QAAQ,CAAC;AAE3B,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACT;AAAA,UACE,OACE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMH,mBAAkB,GAAG;AAE3C,UAAI,CAAC,SAAS,MAAM,IAAI;AACtB,eAAO,IAAI,KAAK,EAAE,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACtE;AAEA,UAAI,CAAC,SAAS,KAAK,iBAAiB;AAClC,eAAO,IAAI,KAAK,EAAE,OAAO,qCAAqC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClF;AAEA,MAAAC,QAAO,MAAM,4BAA4B,KAAK,cAAc,QAAQ,KAAK,eAAe,EAAE;AAE1F,YAAM,SAAS,MAAME,OAAM,UAAU,qBAAqB;AAAA,QACxD,YAAY,KAAK,cAAc,QAAQ,KAAK;AAAA,MAC9C,CAAC;AAED,MAAAF,QAAO,MAAM,2BAA2B,OAAO,kBAAkB,EAAE;AAEnE,aAAO,IAAI,KAAK;AAAA,QACd,KAAK,OAAO;AAAA,QACZ,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAA,QAAO,MAAM,oCAAoC,OAAO,EAAE;AAC1D,aAAO,IAAI,KAAK,EAAE,OAAO,0BAA0B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AA8BO,IAAM,uBAAuB,CAACE,QAAc,YAA0B;AAC3E,SAAOJ;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,oBAAoBI,QAAO,OAAO;AAAA,EACpC;AACF;;;AClGA,SAAS,sBAAAC,qBAAoB,qBAAAC,0BAAyB;AACtD,SAAsC,UAAAC,eAAc;AAEpD,SAAS,KAAAC,UAAS;AAOX,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EAC/C,IAAIA,GAAE,OAAO,EAAE,SAAS;AAC1B,CAAC;AAOD,IAAM,kCAAkC,CAACC,QAAc,YAA0B;AAC/E,SAAO,OAAO,QAAgC;AAC5C,UAAM,OAAO,IAAI;AAEjB,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACT;AAAA,UACE,OACE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMH,mBAAkB,GAAG;AAE3C,UAAI,CAAC,SAAS,MAAM,IAAI;AACtB,eAAO,IAAI,KAAK,EAAE,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACtE;AAEA,UAAI,iBAAiB,KAAK;AAG1B,YAAM,gBAAgB,QAAQ,yBAAyB;AAEvD,UAAI,eAAe;AAEjB,cAAM,SAAS,QAAQ,KAAK;AAE5B,QAAAC,QAAO,MAAM,qDAAqD,MAAM,EAAE;AAG1E,cAAMG,iBAAgB,MAAM,IAAI,QAAQ,QAAQ,SAA6B;AAAA,UAC3E,OAAO;AAAA,UACP,OAAO,CAAC,EAAE,OAAO,eAAe,OAAO,OAAO,CAAC;AAAA,QACjD,CAAC;AAED,YAAIA,kBAAiBA,eAAc,SAAS,GAAG;AAE7C,gBAAM,qBAAqBA,eAAc;AAAA,YACvC,CAAC,QACC,IAAI,WAAW,YACf,IAAI,WAAW,cACf,IAAI,WAAW,YACf,IAAI,WAAW;AAAA,UACnB;AAEA,cAAI,sBAAsB,mBAAmB,qBAAqB;AAEhE,6BAAiB,mBAAmB;AAAA,UACtC,WAAW,CAAC,gBAAgB;AAE1B,mBAAO,IAAI;AAAA,cACT,EAAE,OAAO,6CAA6C;AAAA,cACtD,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAAA,QACF,WAAW,CAAC,gBAAgB;AAE1B,iBAAO,IAAI,KAAK,EAAE,OAAO,sCAAsC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,QACnF;AAAA,MACF,WAAW,CAAC,gBAAgB;AAE1B,eAAO,IAAI;AAAA,UACT;AAAA,YACE,OAAO;AAAA,UACT;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,MAAAH,QAAO,MAAM,oCAAoC,cAAc,EAAE;AAEjE,YAAME,OAAM,cAAc,OAAO,gBAAgB,CAAC,CAAC;AAEnD,aAAO,IAAI,KAAK;AAAA,QACd,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAF,QAAO,MAAM,0CAA0C,OAAO,EAAE;AAChE,aAAO,IAAI,KAAK,EAAE,OAAO,gCAAgC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7E;AAAA,EACF;AACF;AA4CO,IAAM,mCAAmC,CAACE,QAAc,YAA0B;AACvF,SAAOJ;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,gCAAgCI,QAAO,OAAO;AAAA,EAChD;AACF;;;AC9JA,SAAS,sBAAAE,qBAAoB,qBAAAC,0BAAyB;AACtD,SAAsC,UAAAC,eAAc;AAEpD,SAAS,KAAAC,UAAS;AAIX,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,IAAIA,GAAE,OAAO,EAAE,SAAS;AAC1B,CAAC;AAOD,IAAM,oCAAoC,CAACC,QAAc,YAA0B;AACjF,SAAO,OAAO,QAAgC;AAC5C,UAAM,OAAO,IAAI;AAEjB,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACT;AAAA,UACE,OACE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMH,mBAAkB,GAAG;AAE3C,UAAI,CAAC,SAAS,MAAM,IAAI;AACtB,eAAO,IAAI,KAAK,EAAE,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACtE;AAEA,UAAI,iBAAiB,KAAK;AAG1B,YAAM,gBAAgB,QAAQ,yBAAyB;AAEvD,UAAI,eAAe;AAEjB,cAAM,SAAS,QAAQ,KAAK;AAE5B,QAAAC,QAAO,MAAM,uDAAuD,MAAM,EAAE;AAG5E,cAAMG,iBAAgB,MAAM,IAAI,QAAQ,QAAQ,SAA6B;AAAA,UAC3E,OAAO;AAAA,UACP,OAAO,CAAC,EAAE,OAAO,eAAe,OAAO,OAAO,CAAC;AAAA,QACjD,CAAC;AAED,YAAIA,kBAAiBA,eAAc,SAAS,GAAG;AAE7C,gBAAM,mBAAmBA,eAAc,CAAC;AAExC,cAAI,oBAAoB,iBAAiB,qBAAqB;AAE5D,6BAAiB,iBAAiB;AAAA,UACpC,WAAW,CAAC,gBAAgB;AAE1B,mBAAO,IAAI,KAAK,EAAE,OAAO,sCAAsC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,UACnF;AAAA,QACF,WAAW,CAAC,gBAAgB;AAE1B,iBAAO,IAAI,KAAK,EAAE,OAAO,sCAAsC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,QACnF;AAAA,MACF,WAAW,CAAC,gBAAgB;AAE1B,eAAO,IAAI;AAAA,UACT;AAAA,YACE,OAAO;AAAA,UACT;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,MAAAH,QAAO,MAAM,oCAAoC,cAAc,EAAE;AAEjE,YAAM,eAAe,MAAME,OAAM,cAAc,IAAI,cAAc;AAEjE,aAAO,IAAI,KAAK,YAAY;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAF,QAAO,MAAM,4CAA4C,OAAO,EAAE;AAClE,aAAO,IAAI,KAAK,EAAE,OAAO,kCAAkC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC/E;AAAA,EACF;AACF;AA+CO,IAAM,qCAAqC,CAACE,QAAc,YAA0B;AACzF,SAAOJ;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,kCAAkCI,QAAO,OAAO;AAAA,EAClD;AACF;;;AClJA,SAAS,sBAAAE,qBAAoB,qBAAAC,0BAAyB;AACtD,SAAsC,UAAAC,eAAc;AAEpD,SAAS,KAAAC,UAAS;AAQX,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EAC/C,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAChC,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACvC,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACzC,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,SAASA,GAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAOD,IAAM,kCAAkC,CAACC,QAAc,YAA0B;AAC/E,SAAO,OAAO,QAAgC;AAC5C,UAAM,OAAO,IAAI;AAEjB,QAAI,CAAC,QAAQ,QAAQ;AACnB,aAAO,IAAI;AAAA,QACT;AAAA,UACE,OACE;AAAA,QACJ;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMH,mBAAkB,GAAG;AAE3C,UAAI,CAAC,SAAS,MAAM,IAAI;AACtB,eAAO,IAAI,KAAK,EAAE,OAAO,yBAAyB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACtE;AAGA,YAAM,aAAa,KAAK,cAAc,QAAQ,KAAK;AAEnD,UAAI,CAAC,YAAY;AACf,eAAO,IAAI,KAAK,EAAE,OAAO,qCAAqC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClF;AAEA,MAAAC,QAAO,MAAM,gDAAgD,UAAU,EAAE;AAEzE,YAAM,eAAe,MAAME,OAAM,aAAa;AAAA,QAC5C;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AAEA,aAAO,IAAI,KAAK,YAAY;AAAA,IAC9B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAF,QAAO,MAAM,0CAA0C,OAAO,EAAE;AAChE,aAAO,IAAI,KAAK,EAAE,OAAO,gCAAgC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7E;AAAA,EACF;AACF;AAmCO,IAAM,mCAAmC,CAACE,QAAc,YAA0B;AACvF,SAAOJ;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,IACA,gCAAgCI,QAAO,OAAO;AAAA,EAChD;AACF;;;ACjHA,SAAS,sBAAAC,qBAAoB,qBAAAC,0BAAyB;AACtD,SAAsC,UAAAC,eAAc;AACpD,SAAS,KAAAC,UAAS;AAIX,IAAM,yBAAyBA,GAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAI5D,IAAM,gCAAgC,CAAC,YAA0B;AAC/D,SAAO,OAAO,QAAgC;AAC5C,QAAI;AACF,YAAM,UAAU,MAAMF,mBAAkB,GAAG;AAE3C,UAAI,CAAC,SAAS,MAAM,IAAI;AACtB,eAAO,IAAI;AAAA,UACT;AAAA,YACE,kBAAkB;AAAA,YAClB,SAAS;AAAA,UACX;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAGA,YAAM,gBAAgB,QAAQ,yBAAyB;AAEvD,UAAI,CAAC,eAAe;AAClB,eAAO,IAAI;AAAA,UACT;AAAA,YACE,kBAAkB;AAAA,YAClB,SACE;AAAA,UACJ;AAAA,UACA,EAAE,QAAQ,IAAI;AAAA,QAChB;AAAA,MACF;AAEA,YAAM,SAAS,QAAQ,KAAK;AAG5B,YAAMG,iBAAgB,MAAM,IAAI,QAAQ,QAAQ,SAA6B;AAAA,QAC3E,OAAO;AAAA,QACP,OAAO,CAAC,EAAE,OAAO,eAAe,OAAO,OAAO,CAAC;AAAA,MACjD,CAAC;AAED,MAAAF,QAAO;AAAA,QACL,8BAA8B,MAAM,WAAWE,gBAAe,UAAU,CAAC;AAAA,MAC3E;AAEA,UAAI,CAACA,kBAAiBA,eAAc,WAAW,GAAG;AAChD,eAAO,IAAI,KAAK;AAAA,UACd,kBAAkB;AAAA,UAClB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAGA,YAAM,MAAM,oBAAI,KAAK;AAGrB,iBAAW,gBAAgBA,gBAAe;AACxC,cAAM,SAAS,aAAa,OAAO,YAAY;AAI/C,YAAI,WAAW,YAAY,WAAW,cAAc,WAAW,QAAQ;AACrE,UAAAF,QAAO,MAAM,wCAAwC,aAAa,EAAE,WAAW,MAAM,EAAE;AACvF,iBAAO,IAAI,KAAK;AAAA,YACd,kBAAkB;AAAA,YAClB,cAAc;AAAA,cACZ,IAAI,aAAa;AAAA,cACjB,QAAQ,aAAa;AAAA,cACrB,WAAW,aAAa;AAAA,cACxB,WAAW,aAAa;AAAA,YAC1B;AAAA,UACF,CAAC;AAAA,QACH;AAGA,YAAI,WAAW,cAAc,WAAW,cAAc,WAAW,UAAU;AACzE,cAAI,aAAa,WAAW;AAC1B,kBAAM,YAAY,IAAI,KAAK,aAAa,SAAS;AAGjD,gBAAI,YAAY,KAAK;AACnB,cAAAA,QAAO;AAAA,gBACL,wCAAwC,aAAa,EAAE,IAAI,MAAM,UAAU,UAAU,YAAY,CAAC;AAAA,cACpG;AACA,qBAAO,IAAI,KAAK;AAAA,gBACd,kBAAkB;AAAA,gBAClB,cAAc;AAAA,kBACZ,IAAI,aAAa;AAAA,kBACjB,QAAQ,aAAa;AAAA,kBACrB,WAAW,aAAa;AAAA,kBACxB,WAAW,aAAa;AAAA,gBAC1B;AAAA,gBACA,SAAS,mBAAmB,MAAM,6BAA6B,UAAU,YAAY,CAAC;AAAA,cACxF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,MAAAA,QAAO,MAAM,gDAAgD;AAE7D,aAAO,IAAI,KAAK;AAAA,QACd,kBAAkB;AAAA,QAClB,SAAS;AAAA,QACT,eAAeE,eAAc,IAAI,CAAC,OAAO;AAAA,UACvC,IAAI,EAAE;AAAA,UACN,QAAQ,EAAE;AAAA,UACV,WAAW,EAAE;AAAA,UACb,WAAW,EAAE;AAAA,QACf,EAAE;AAAA,MACJ,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,MAAAF,QAAO,MAAM,gDAAgD,YAAY,EAAE;AAC3E,aAAO,IAAI;AAAA,QACT;AAAA,UACE,kBAAkB;AAAA,UAClB,SAAS;AAAA,QACX;AAAA,QACA,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;AAaO,IAAM,iCAAiC,CAAC,YAA0B;AACvE,SAAOF;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,IACV;AAAA,IACA,8BAA8B,OAAO;AAAA,EACvC;AACF;;;ACtJA,SAAS,sBAAAK,2BAA0B;AACnC,SAAsC,UAAAC,eAAc;;;ACDpD,SAAsC,UAAAC,eAAc;AAsBpD,eAAsB,oBACpB,KACA,OACA,SACA;AAEA,QAAM,gBAAgB,QAAQ,yBAAyB;AAEvD,MAAI,CAAC,eAAe;AAClB,IAAAA,QAAO,KAAK,yEAAyE;AACrF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,WAAW,MAAM;AAGvB,UAAM,aAAa,SAAS,UAAU;AAEtC,QAAI,CAAC,YAAY;AACf,MAAAA,QAAO,KAAK,oDAAoD;AAChE;AAAA,IACF;AAGA,UAAM,cAAc,SAAS,UAAU;AAEvC,QAAI,CAAC,aAAa;AAChB,MAAAA,QAAO,KAAK,oDAAoD;AAChE;AAAA,IACF;AAEA,IAAAA,QAAO;AAAA,MACL,0CAA0C,UAAU,iBAAiB,WAAW,qBAAqB,CAAC,CAAC,SAAS,YAAY;AAAA,IAC9H;AAGA,QAAI;AACF,YAAMC,QAAO,MAAM,IAAI,QAAQ,QAAQ,QAGpC;AAAA,QACD,OAAO;AAAA,QACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,YAAY,CAAC;AAAA,MAC7C,CAAC;AAED,UAAIA,SAAQ,CAACA,MAAK,iBAAiB;AACjC,cAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,UAC/B,OAAO;AAAA,UACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,YAAY,CAAC;AAAA,UAC3C,QAAQ;AAAA,YACN,iBAAiB;AAAA,UACnB;AAAA,QACF,CAAC;AACD,QAAAD,QAAO,KAAK,wBAAwB,WAAW,0BAA0B,UAAU,EAAE;AAAA,MACvF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAA,QAAO,MAAM,uDAAuD,OAAO,EAAE;AAAA,IAC/E;AAGA,QAAI,SAAS,gBAAgB,SAAS,OAAO;AAC3C,YAAM,mBAAmB,SAAS;AAClC,YAAM,UAAU,OAAO,SAAS,UAAU,WAAW,SAAS,MAAM,KAAK,SAAS;AAClF,YAAM,YAAY,SAAS,QAAQ;AAEnC,UAAI,iBAAiB,IAAI;AACvB,cAAM,qBAAqB;AAAA,UACzB,WAAW,aAAa;AAAA,UACxB;AAAA,UACA,iBAAiB;AAAA,UACjB,qBAAqB,iBAAiB;AAAA,UACtC,cAAc;AAAA,UACd,QAAQ,iBAAiB;AAAA,UACzB,aAAa,iBAAiB,4BAC1B,IAAI,KAAK,iBAAiB,yBAAyB,IACnD;AAAA,UACJ,WAAW,iBAAiB,0BACxB,IAAI,KAAK,iBAAiB,uBAAuB,IACjD;AAAA,QACN;AAGA,cAAM,uBAAuB,MAAM,IAAI,QAAQ,QAAQ,QAA4B;AAAA,UACjF,OAAO;AAAA,UACP,OAAO,CAAC,EAAE,OAAO,uBAAuB,OAAO,iBAAiB,GAAG,CAAC;AAAA,QACtE,CAAC;AAED,YAAI,sBAAsB;AAExB,gBAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,YAC/B,OAAO;AAAA,YACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,qBAAqB,GAAG,CAAC;AAAA,YACvD,QAAQ;AAAA,UACV,CAAC;AACD,UAAAA,QAAO,KAAK,gCAAgC,qBAAqB,EAAE,gBAAgB;AAAA,QACrF,OAAO;AAEL,gBAAM,kBAAkB,MAAM,IAAI,QAAQ,QAAQ,OAA2B;AAAA,YAC3E,OAAO;AAAA,YACP,MAAM;AAAA,UACR,CAAC;AACD,UAAAA,QAAO,KAAK,gCAAgC,gBAAgB,EAAE,gBAAgB;AAAA,QAChF;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,IAAAA,QAAO,MAAM,gDAAgD,OAAO,EAAE;AAAA,EACxE;AACF;AAMA,eAAsB,qBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,UAAU,OAAO;AACxE;AAOA,eAAsB,uBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,YAAY,OAAO;AAGxE,QAAM,mBAAmB,KAAK,MAAM,QAAQ,OAAO;AACrD;AAUA,eAAe,mBACb,KACA,kBACA,SACA;AAEA,QAAM,gBAAgB,QAAQ,yBAAyB;AACvD,MAAI,CAAC,eAAe;AAClB;AAAA,EACF;AAEA,QAAM,cAAc,iBAAiB,UAAU;AAC/C,MAAI,CAAC,aAAa;AAChB,IAAAA,QAAO,KAAK,gFAAgF;AAC5F;AAAA,EACF;AAEA,MAAI;AAEF,UAAMC,QAAO,MAAM,IAAI,QAAQ,QAAQ,QAGpC;AAAA,MACD,OAAO;AAAA,MACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,YAAY,CAAC;AAAA,IAC7C,CAAC;AAED,QAAI,CAACA,OAAM;AACT,MAAAD,QAAO;AAAA,QACL,2CAA2C,WAAW;AAAA,MACxD;AACA;AAAA,IACF;AAGA,QAAI,CAACC,MAAK,UAAU;AAClB,YAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,QAC/B,OAAO;AAAA,QACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,YAAY,CAAC;AAAA,QAC3C,QAAQ;AAAA,UACN,UAAU;AAAA,QACZ;AAAA,MACF,CAAC;AACD,MAAAD,QAAO,KAAK,uBAAuB,WAAW,mBAAmB;AAAA,IACnE;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,IAAAA,QAAO,MAAM,4CAA4C,OAAO,EAAE;AAAA,EACpE;AACF;AAMA,eAAsB,uBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,YAAY,OAAO;AAC1E;AAMA,eAAsB,mBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,MAAM,OAAO,QAAQ,OAAO;AACnF;AAMA,eAAsB,sBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,WAAW,OAAO;AACzE;AAMA,eAAsB,qBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,UAAU,OAAO;AACxE;AAMA,eAAsB,qBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,MAAM,OAAO,QAAQ,OAAO;AACnF;AAMA,eAAsB,sBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,YAAY,OAAO;AAC1E;AAMA,eAAsB,qBACpB,KACA,OACA,SACA;AACA,QAAM,4BAA4B,KAAK,MAAM,QAAQ,UAAU,OAAO;AACxE;AAKA,eAAe,4BACb,KACA,kBACA,QACA,SACA;AAEA,QAAM,gBAAgB,QAAQ,yBAAyB;AAEvD,MAAI,CAAC,eAAe;AAClB,IAAAA,QAAO,KAAK,mEAAmE;AAC/E;AAAA,EACF;AAEA,QAAM,cAAc,iBAAiB,UAAU;AAE/C,MAAI,CAAC,aAAa;AAChB,IAAAA,QAAO,KAAK,uDAAuD;AACnE;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,aAAa,iBAAiB,SAAS;AAC7C,UAAM,YAAY,iBAAiB,QAAQ;AAE3C,IAAAA,QAAO,MAAM,2DAA2D,iBAAiB,EAAE,EAAE;AAG7F,QAAI,eAAe,MAAM,IAAI,QAAQ,QAAQ,QAA4B;AAAA,MACvE,OAAO;AAAA,MACP,OAAO,CAAC,EAAE,OAAO,uBAAuB,OAAO,iBAAiB,GAAG,CAAC;AAAA,IACtE,CAAC;AAGD,QAAI,CAAC,gBAAgB,YAAY;AAC/B,MAAAA,QAAO,MAAM,uDAAuD,UAAU,EAAE;AAChF,YAAME,iBAAgB,MAAM,IAAI,QAAQ,QAAQ,SAA6B;AAAA,QAC3E,OAAO;AAAA,QACP,OAAO,CAAC,EAAE,OAAO,mBAAmB,OAAO,WAAW,CAAC;AAAA,MACzD,CAAC;AAGD,qBACEA,eAAc,KAAK,CAAC,QAA4B,IAAI,cAAc,SAAS,KAC3EA,eAAc,CAAC;AAAA,IACnB;AAEA,QAAI,CAAC,cAAc;AACjB,MAAAF,QAAO,KAAK,2DAA2D,iBAAiB,EAAE,EAAE;AAC5F;AAAA,IACF;AAGA,UAAM,aAA0C;AAAA,MAC9C;AAAA,MACA,qBAAqB,iBAAiB;AAAA,MACtC,iBAAiB;AAAA,MACjB,aAAa,iBAAiB,4BAC1B,IAAI,KAAK,iBAAiB,yBAAyB,IACnD,aAAa;AAAA,MACjB,WAAW,iBAAiB,0BACxB,IAAI,KAAK,iBAAiB,uBAAuB,IACjD,aAAa;AAAA,IACnB;AAGA,UAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,MAC/B,OAAO;AAAA,MACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,aAAa,GAAG,CAAC;AAAA,MAC/C,QAAQ;AAAA,IACV,CAAC;AAED,IAAAA,QAAO,KAAK,gCAAgC,aAAa,EAAE,eAAe,MAAM,EAAE;AAAA,EACpF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,IAAAA,QAAO,MAAM,iDAAiD,OAAO,EAAE;AAAA,EACzE;AACF;;;ADlXA,IAAM,uBAAuB,CAAC,YAA0B;AACtD,SAAO,OAAO,QAAgC;AAC5C,QAAI;AACF,UAAI,CAAC,IAAI,SAAS;AAChB,eAAO,IAAI,KAAK,EAAE,OAAO,sBAAsB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACnE;AAEA,YAAM,MAAM,MAAM,IAAI,QAAQ,KAAK;AAEnC,YAAM,YAAY,IAAI,QAAQ,QAAQ,IAAI,iBAAiB;AAE3D,UAAI,CAAC,QAAQ,eAAe;AAC1B,QAAAG,QAAO,MAAM,0CAA0C;AACvD,eAAO,IAAI,KAAK,EAAE,OAAO,mCAAmC,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MAChF;AAEA,YAAM,oBAAoB,MAAM,kBAAkB,KAAK,QAAQ,aAAa;AAC5E,UAAI,sBAAsB,WAAW;AACnC,eAAO,IAAI,KAAK,EAAE,OAAO,oBAAoB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACjE;AAEA,MAAAA,QAAO,MAAM,oCAAoC;AAEjD,YAAM,QAAQ,kBAAkB,GAAG;AAEnC,MAAAA,QAAO,MAAM,mCAAmC,MAAM,SAAS,SAAS,MAAM,EAAE,GAAG;AAUnF,cAAQ,MAAM,WAAW;AAAA,QACvB,KAAK;AACH,gBAAM,oBAAoB,KAAK,OAAO,OAAO;AAC7C,gBAAM,QAAQ,sBAAsB;AAAA,YAClC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,QAAQ,kBAAkB;AAAA,YAC9B,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,QAAQ,mBAAmB;AAAA,YAC/B,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,qBAAqB,KAAK,OAAO,OAAO;AAC9C,gBAAM,QAAQ,gBAAgB;AAAA,YAC5B,QAAQ;AAAA,YACR,GAAG,MAAM;AAAA,UACX,CAAC;AACD,gBAAM,QAAQ,uBAAuB;AAAA,YACnC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,uBAAuB,KAAK,OAAO,OAAO;AAChD,gBAAM,QAAQ,gBAAgB;AAAA,YAC5B,QAAQ;AAAA,YACR,GAAG,MAAM;AAAA,UACX,CAAC;AACD,gBAAM,QAAQ,yBAAyB;AAAA,YACrC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AAED;AAAA,QACF,KAAK;AACH,gBAAM,uBAAuB,KAAK,OAAO,OAAO;AAChD,gBAAM,QAAQ,yBAAyB;AAAA,YACrC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,mBAAmB,KAAK,OAAO,OAAO;AAC5C,gBAAM,QAAQ,gBAAgB;AAAA,YAC5B,QAAQ;AAAA,YACR,GAAG,MAAM;AAAA,UACX,CAAC;AACD,gBAAM,QAAQ,qBAAqB;AAAA,YACjC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,sBAAsB,KAAK,OAAO,OAAO;AAC/C,gBAAM,QAAQ,iBAAiB;AAAA,YAC7B,QAAQ;AAAA,YACR,GAAG,MAAM;AAAA,UACX,CAAC;AACD,gBAAM,QAAQ,wBAAwB;AAAA,YACpC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,qBAAqB,KAAK,OAAO,OAAO;AAC9C,gBAAM,QAAQ,uBAAuB;AAAA,YACnC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,qBAAqB,KAAK,OAAO,OAAO;AAC9C,gBAAM,QAAQ,uBAAuB;AAAA,YACnC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,sBAAsB,KAAK,OAAO,OAAO;AAC/C,gBAAM,QAAQ,wBAAwB;AAAA,YACpC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF,KAAK;AACH,gBAAM,qBAAqB,KAAK,OAAO,OAAO;AAC9C,gBAAM,QAAQ,iBAAiB;AAAA,YAC7B,QAAQ;AAAA,YACR,GAAG,MAAM;AAAA,UACX,CAAC;AACD,gBAAM,QAAQ,uBAAuB;AAAA,YACnC,kBAAkB,MAAM;AAAA,YACxB,WAAW,MAAM;AAAA,YACjB,kBAAkB,MAAM;AAAA,YACxB,GAAG,MAAM;AAAA,UACX,CAAC;AACD;AAAA,QAEF;AACE,UAAAA,QAAO,KAAK,wCAAyC,MAAc,SAAS,EAAE;AAC9E,iBAAO,IAAI,KAAK,EAAE,OAAO,qBAAqB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,MACpE;AAEA,aAAO,IAAI,KAAK,EAAE,SAAS,mBAAmB,CAAC;AAAA,IACjD,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAA,QAAO,MAAM,sCAAsC,OAAO,EAAE;AAC5D,aAAO,IAAI,KAAK,EAAE,OAAO,4BAA4B,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACzE;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB,CAAC,YAA0B;AAC9D,SAAOC;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACf;AAAA,IACA,qBAAqB,OAAO;AAAA,EAC9B;AACF;;;AExNA,SAAS,aAAa;AACtB,SAAS,UAAAC,eAAc;AAsChB,SAAS,kBAAkB,QAAkC;AAClE,QAAM,YAAY,OAAO,WAAW,8BAA8B;AAElE,SAAO,IAAI,MAAM,EAAE,QAAQ,OAAO,QAAQ,UAAU,CAAC;AACvD;AAiBO,SAAS,qBAAqB,QAAyB;AAC5D,SAAO,CAAC,UAAU,YAAY,MAAM,EAAE,SAAS,OAAO,YAAY,CAAC;AACrE;AAgBO,SAAS,gBAAgB,WAAyB;AACvD,SAAO,IAAI,KAAK,YAAY,GAAI;AAClC;AAoBO,SAAS,oBAAoB,oBAAoC;AACtE,QAAM,cAAc,gBAAgB,kBAAkB;AACtD,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,WAAW,YAAY,QAAQ,IAAI,IAAI,QAAQ;AACrD,SAAO,KAAK,KAAK,YAAY,MAAO,KAAK,KAAK,GAAG;AACnD;AA4BA,eAAsB,yBACpB,SACA,WACA,QACkB;AAClB,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,oBAAoB,MAAM,kBAAkB,SAAS,MAAM;AACjE,SAAO,sBAAsB;AAC/B;AA+CA,eAAsB,eACpB,QACA,OAWiC;AACjC,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMC,SAAQ,kBAAkB,MAAM;AAEtC,QAAM,WAAW,MAAMA,OAAM,UAAU,OAAO;AAAA,IAC5C,WAAW,MAAM;AAAA,IACjB,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb,cAAc,MAAM;AAAA,IACpB,UAAU,MAAM;AAAA,IAChB,cAAc,MAAM,gBAAgB,MAAM;AAAA,IAC1C,YAAY,MAAM;AAAA,IAClB,UAAU;AAAA,MACR,GAAI,MAAM,YAAY,CAAC;AAAA;AAAA,MAEvB,GAAI,MAAM,aAAa,EAAE,WAAW,KAAK;AAAA,IAC3C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,KACE,SAAS,gBACR,MAAM;AACL,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD,GAAG;AAAA,IACL,UAAU;AAAA,EACZ;AACF;AAkCA,eAAsB,aACpB,QACA,YAC+B;AAC/B,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,SAAQ,kBAAkB,MAAM;AAEtC,QAAM,SAAS,MAAMA,OAAM,UAAU,qBAAqB;AAAA,IACxD;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,KAAK,OAAO;AAAA,IACZ,UAAU;AAAA,EACZ;AACF;AA8BA,eAAsB,mBACpB,QACA,gBACgD;AAChD,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,SAAQ,kBAAkB,MAAM;AAEtC,QAAMA,OAAM,cAAc,OAAO,gBAAgB,CAAC,CAAC;AAEnD,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACF;AAiCA,eAAsB,qBACpB,QACA,gBAC2B;AAC3B,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,SAAQ,kBAAkB,MAAM;AAEtC,QAAM,eAAe,MAAMA,OAAM,cAAc,IAAI,cAAc;AAEjE,SAAO;AACT;AA+BA,eAAsB,mBACpB,QACA,SAOqC;AACrC,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,SAAQ,kBAAkB,MAAM;AAEtC,QAAM,WAAW,MAAMA,OAAM,aAAa;AAAA,IACxC,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAEA,SAAO;AACT;AA8CA,eAAsB,wBACpB,QACA,SASC;AAKD,MAAI,QAAQ,YAAY,QAAQ,QAAQ;AACtC,QAAI;AACF,YAAMC,iBAAgB,MAAM,QAAQ,SACjC,OAAO,EACP,KAAK,oBAAoB,EACzB,MAAM,eAAe,KAAK,QAAQ,MAAM;AAE3C,YAAM,qBAAqBA,eAAc;AAAA,QACvC,CAAC,QAAa,IAAI,WAAW,YAAY,IAAI,WAAW,cAAc,IAAI,WAAW;AAAA,MACvF;AAEA,UAAI,oBAAoB;AACtB,eAAO;AAAA,UACL,WAAW;AAAA,UACX,QAAQ,mBAAmB;AAAA,UAC3B,gBAAgB,mBAAmB;AAAA,UACnC,WAAW,mBAAmB,YAC1B,IAAI,KAAK,mBAAmB,SAAS,IACrC;AAAA,QACN;AAAA,MACF;AAEA,aAAO,EAAE,WAAW,MAAM;AAAA,IAC5B,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAC,QAAO,MAAM,gEAAgE,OAAO,EAAE;AAAA,IAExF;AAAA,EACF;AAGA,MAAI,QAAQ,YAAY;AAEtB,WAAO,EAAE,WAAW,MAAM;AAAA,EAC5B;AAEA,SAAO,EAAE,WAAW,MAAM;AAC5B;AA2BA,eAAsB,uBACpB,QACA,SAWA;AAGA,MAAI,QAAQ,YAAY,QAAQ,QAAQ;AACtC,QAAI;AACF,YAAMD,iBAAgB,MAAM,QAAQ,SACjC,OAAO,EACP,KAAK,oBAAoB,EACzB,MAAM,eAAe,KAAK,QAAQ,MAAM;AAE3C,aAAOA,eACJ;AAAA,QACC,CAAC,QACC,IAAI,WAAW,YAAY,IAAI,WAAW,cAAc,IAAI,WAAW;AAAA,MAC3E,EACC,IAAI,CAAC,SAAc;AAAA,QAClB,IAAI,IAAI;AAAA,QACR,QAAQ,IAAI;AAAA,QACZ,WAAW,IAAI;AAAA,QACf,WAAW,IAAI,YAAY,IAAI,KAAK,IAAI,SAAS,IAAI;AAAA,MACvD,EAAE;AAAA,IACN,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAAC,QAAO,MAAM,+DAA+D,OAAO,EAAE;AACrF,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAGA,MAAI,QAAQ,YAAY;AAEtB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,CAAC;AACV;;;AXnfO,IAAM,QAAQ,CAAC,YAA0B;AAC9C,QAAM,YAAY,QAAQ,WAAW,8BAA8B;AAEnE,QAAMC,SAAQ,IAAIC,OAAM;AAAA,IACtB,QAAQ,QAAQ;AAAA,IAChB;AAAA,EACF,CAAC;AAED,MAAI,CAAC,QAAQ,QAAQ;AACnB,IAAAC,SAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,EAAAA,SAAO;AAAA,IACL,+BAA+B,QAAQ,WAAW,SAAS,YAAY,uBAAuB,QAAQ,yBAAyB,KAAK,cAAc,CAAC,CAAC,QAAQ,aAAa;AAAA,EAC3K;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,WAAW;AAAA,MACT,gBAAgB,uBAAuBF,QAAO,OAAO;AAAA,MACrD,cAAc,qBAAqBA,QAAO,OAAO;AAAA,MACjD,oBAAoB,iCAAiCA,QAAO,OAAO;AAAA,MACnE,sBAAsB,mCAAmCA,QAAO,OAAO;AAAA,MACvE,oBAAoB,iCAAiCA,QAAO,OAAO;AAAA,MACnE,kBAAkB,+BAA+B,OAAO;AAAA,MACxD,GAAI,QAAQ,iBAAiB;AAAA,QAC3B,cAAc,sBAAsB,OAAO;AAAA,MAC7C;AAAA,IACF;AAAA,IACA,QAAQ,UAAU,OAAO;AAAA,EAC3B;AACF;","names":["logger","Creem","user","creem","createAuthEndpoint","getSessionFromCtx","logger","z","creem","createAuthEndpoint","getSessionFromCtx","logger","z","creem","subscriptions","createAuthEndpoint","getSessionFromCtx","logger","z","creem","subscriptions","createAuthEndpoint","getSessionFromCtx","logger","z","creem","createAuthEndpoint","getSessionFromCtx","logger","z","subscriptions","createAuthEndpoint","logger","logger","user","subscriptions","logger","createAuthEndpoint","logger","creem","subscriptions","logger","creem","Creem","logger"]}